Преглед на файлове

Merge branch 'statistics' into master

zlisen преди 3 години
родител
ревизия
3d3f7d50f5
променени са 36 файла, в които са добавени 4797 реда и са изтрити 162 реда
  1. 74
    5
      config/routes.js
  2. 1
    0
      src/components/SelectButton/BuildSelect.jsx
  3. 105
    0
      src/pages/statistics/activity/activityContent/index.jsx
  4. 110
    0
      src/pages/statistics/activity/activityOverview/index.jsx
  5. 332
    0
      src/pages/statistics/activity/addRegistNum.jsx
  6. 289
    0
      src/pages/statistics/activity/compents/ContentTable.jsx
  7. 128
    0
      src/pages/statistics/activity/compents/NewUsers.jsx
  8. 204
    0
      src/pages/statistics/activity/compents/OverviewDeatil.jsx
  9. 102
    0
      src/pages/statistics/activity/compents/activityCount.jsx
  10. 87
    0
      src/pages/statistics/activity/detail.jsx
  11. 144
    0
      src/pages/statistics/activity/index copy.jsx
  12. 66
    123
      src/pages/statistics/activity/index.jsx
  13. 359
    0
      src/pages/statistics/activity/shareNum.jsx
  14. 344
    0
      src/pages/statistics/activity/sharePersonNum.jsx
  15. 363
    0
      src/pages/statistics/activity/visitNum.jsx
  16. 264
    0
      src/pages/statistics/activity/visitPersonNum.jsx
  17. 72
    0
      src/pages/statistics/building/BuildingStatistic/component/StatsChart.jsx
  18. 110
    0
      src/pages/statistics/building/BuildingStatistic/component/StatsChartLine.jsx
  19. 72
    0
      src/pages/statistics/building/BuildingStatistic/index.jsx
  20. 100
    0
      src/pages/statistics/building/detail.jsx
  21. 90
    0
      src/pages/statistics/building/detail/index.jsx
  22. 111
    0
      src/pages/statistics/building/detail/tableDetail.jsx
  23. 161
    0
      src/pages/statistics/building/detailData/index.jsx
  24. 25
    0
      src/pages/statistics/building/index.jsx
  25. 47
    15
      src/pages/statistics/compents/TimeSelect.jsx
  26. 317
    0
      src/pages/statistics/consultant/index.jsx
  27. 12
    12
      src/pages/statistics/dataReport/components/Count.jsx
  28. 148
    0
      src/pages/statistics/dataReport/components/IntentionalCustomers.jsx
  29. 108
    0
      src/pages/statistics/dataReport/components/NewUsers.jsx
  30. 94
    0
      src/pages/statistics/dataReport/components/UserActive.jsx
  31. 157
    0
      src/pages/statistics/dataReport/components/UserBehavior.jsx
  32. 2
    2
      src/pages/statistics/dataReport/components/UserSex.jsx
  33. 126
    0
      src/pages/statistics/dataReport/components/userSource.jsx
  34. 35
    4
      src/pages/statistics/dataReport/index.jsx
  35. 37
    0
      src/pages/statistics/dataReport/newAdd.jsx
  36. 1
    1
      src/services/apis.js

+ 74
- 5
config/routes.js Целия файл

@@ -378,7 +378,7 @@ export default [
378 378
               //   hideInMenu: true,
379 379
               //   component: './channel/InviteClients',
380 380
               // },
381
-               {
381
+              {
382 382
                 path: '/channel/independentList',
383 383
                 name: '经纪人',
384 384
                 component: './channel/independentList/index',
@@ -540,10 +540,9 @@ export default [
540 540
                 component: './carouselFigure/editAdvertising',
541 541
                 menuCode: '/carouselFigure/editAdvertising',
542 542
               },
543
-             
544 543
             ],
545 544
           },
546
-         
545
+
547 546
           {
548 547
             path: '/system',
549 548
             name: '系统管理',
@@ -607,14 +606,21 @@ export default [
607 606
             path: '/statistics',
608 607
             name: '数据统计',
609 608
             component: '../layouts/BlankLayout',
610
-            menuCode: '/statistics',
609
+            menuCode: '/building',
611 610
             // hideInMenu: true,
612 611
             routes: [
613 612
               {
614 613
                 path: '/statistics/dataReport',
615 614
                 name: '数据报表',
616 615
                 component: './statistics/dataReport',
617
-                menuCode: '/statistics/dataReport',
616
+                menuCode: '/statistics/dataRepor',
617
+              },
618
+              {
619
+                path: '/statistics/dataReport/newAdd',
620
+                name: '新增用户',
621
+                hideInMenu: true,
622
+                component: './statistics/dataReport/newAdd',
623
+                menuCode: '/statistics/dataRepor',
618 624
               },
619 625
               {
620 626
                 path: '/statistics/activity',
@@ -622,6 +628,69 @@ export default [
622 628
                 component: './statistics/activity',
623 629
                 menuCode: '/statistics/activity',
624 630
               },
631
+              {
632
+                path: '/statistics/activity/sharePersonNum',
633
+                name: '分享人数',
634
+                hideInMenu: true,
635
+                component: './statistics/activity/sharePersonNum',
636
+                menuCode: '/statistics/activity',
637
+              },
638
+              {
639
+                path: '/statistics/activity/shareNum',
640
+                name: '分享次数',
641
+                hideInMenu: true,
642
+                component: './statistics/activity/shareNum',
643
+                menuCode: '/statistics/activity',
644
+              },
645
+              {
646
+                path: '/statistics/activity/visitPersonNum',
647
+                name: '访问人数',
648
+                hideInMenu: true,
649
+                component: './statistics/activity/visitPersonNum',
650
+                menuCode: '/statistics/activity',
651
+              },
652
+              {
653
+                path: '/statistics/activity/visitNum',
654
+                name: '访问次数',
655
+                hideInMenu: true,
656
+                component: './statistics/activity/visitNum',
657
+                menuCode: '/statistics/activity',
658
+              },
659
+              {
660
+                path: '/statistics/activity/addRegistNum',
661
+                name: '新增注册用户',
662
+                hideInMenu: true,
663
+                component: './statistics/activity/addRegistNum',
664
+                menuCode: '/statistics/activity',
665
+              },
666
+              {
667
+                path: '/statistics/activity/detail',
668
+                name: '查看',
669
+                hideInMenu: true,
670
+                component: './statistics/activity/detail',
671
+                menuCode: '/statistics/activity',
672
+              },
673
+              
674
+              {
675
+                path: '/statistics/building',
676
+                name: '项目统计',
677
+                component: './statistics/building',
678
+                menuCode: '/statistics/building',
679
+              },
680
+              {
681
+                path: '/statistics/building/detail',
682
+                name: '项目统计',
683
+                hideInMenu: true,
684
+                component: './statistics/building/detail',
685
+                menuCode: '/statistics/building',
686
+              },
687
+
688
+              {
689
+                path: '/statistics/consultant',
690
+                name: 'KPI',
691
+                component: './statistics/consultant',
692
+                menuCode: '/statistics/consultant',
693
+              },
625 694
             ],
626 695
           },
627 696
           {

+ 1
- 0
src/components/SelectButton/BuildSelect.jsx Целия файл

@@ -52,6 +52,7 @@ const BuildingSelect = props => {
52 52
       style={{ width: '300px' }}
53 53
       placeholder="请选择项目"
54 54
       onChange={props.onChange}
55
+      allowClear={props.allowClear||false}
55 56
       filterOption={(input, option) =>
56 57
         option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
57 58
       }>

+ 105
- 0
src/pages/statistics/activity/activityContent/index.jsx Целия файл

@@ -0,0 +1,105 @@
1
+import React, { Component, useState, useEffect, useRef } from 'react';
2
+import { Card, Row, Col, Statistic, Icon, Tabs, Form, Select, Button, Input } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+import TimeSelect from '../../compents/TimeSelect';
10
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
11
+import Navigate from '@/components/Navigate';
12
+import ActivityCount from '../compents/activityCount';
13
+import NewUsers from '../compents/NewUsers';
14
+import OverviewDeatil from '../compents/OverviewDeatil';
15
+import ContentTable from '../compents/ContentTable';
16
+// import Count from './components/Count';
17
+// import SourceRole from './components/SourceRole';
18
+// import UserSex from './components/UserSex';
19
+// import UserConversion from './components/UserConversion';
20
+// import BuildingStatistic from './BuildingStatistic';
21
+const { TabPane } = Tabs;
22
+const { Option } = Select;
23
+
24
+const activityOverView = props => {
25
+  const timeRef = useRef();
26
+
27
+  const [data, setData] = useState({});
28
+  const [serachData, setSearchData] = useState({
29
+    startDate:
30
+      moment()
31
+        .subtract(7, 'day')
32
+        .format('YYYY-MM-DDT00:00:00.000') + 'Z',
33
+    endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
34
+  });
35
+  const [timeValue, setTimeValue] = useState();
36
+
37
+  const [time, setTime] = useState();
38
+
39
+  //重置搜索
40
+  const handleReset = e => {
41
+    props.form.resetFields();
42
+    timeRef.current.reset();
43
+    setSearchData({
44
+      startDate:
45
+        moment()
46
+          .subtract(7, 'day')
47
+          .format('YYYY-MM-DDT00:00:00.000') + 'Z',
48
+      endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
49
+    });
50
+  };
51
+
52
+  const onTimeChange = e => {
53
+    setTime(e);
54
+  };
55
+  const handleSubmit = e => {
56
+    props.form.validateFieldsAndScroll((err, values) => {
57
+      setTimeValue();
58
+      setSearchData({
59
+        ...values,
60
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
61
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
62
+      });
63
+    });
64
+  };
65
+
66
+  const { getFieldDecorator } = props.form;
67
+  console.log(timeValue, 'timeValue');
68
+  return (
69
+    <div>
70
+      <Form layout="inline" onSubmit={handleSubmit}>
71
+        <Form.Item>
72
+          <TimeSelect onChange={onTimeChange} ref={timeRef}></TimeSelect>
73
+        </Form.Item>
74
+        <Form.Item>{getFieldDecorator('buildingId')(<BuildingSelect allowClear />)}</Form.Item>
75
+        <Form.Item>
76
+          {getFieldDecorator('targetType')(
77
+            <Select placeholder="活动类型" allowClear style={{ width: 150, marginLeft: '20px' }}>
78
+              <Option value="dymic">报名</Option>
79
+              <Option value="look">带看</Option>
80
+              <Option value="house">团房</Option>
81
+              <Option value="live">直播</Option>
82
+            </Select>,
83
+          )}
84
+        </Form.Item>
85
+        <Form.Item>
86
+          {getFieldDecorator('activityName')(<Input placeholder="请输入活动名称" />)}
87
+        </Form.Item>
88
+        <Form.Item>
89
+          <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
90
+            搜索
91
+          </Button>
92
+          <Button onClick={e => handleReset()} style={{ marginLeft: '30px' }}>
93
+            重置
94
+          </Button>
95
+        </Form.Item>
96
+      </Form>
97
+      <div style={{ marginTop: '20px' }}>
98
+        <ContentTable params={serachData}></ContentTable>
99
+      </div>
100
+    </div>
101
+  );
102
+};
103
+
104
+const WrappedTypeForm = Form.create()(activityOverView);
105
+export default WrappedTypeForm;

+ 110
- 0
src/pages/statistics/activity/activityOverview/index.jsx Целия файл

@@ -0,0 +1,110 @@
1
+import React, { Component, useState, useEffect, useRef } from 'react';
2
+import { Card, Row, Col, Statistic, Icon, Tabs, Form, Select, Button, Modal } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+import TimeSelect from '../../compents/TimeSelect';
10
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
11
+import Navigate from '@/components/Navigate';
12
+import ActivityCount from '../compents/activityCount';
13
+import NewUsers from '../compents/NewUsers';
14
+import OverviewDeatil from '../compents/OverviewDeatil';
15
+
16
+// import Count from './components/Count';
17
+// import SourceRole from './components/SourceRole';
18
+// import UserSex from './components/UserSex';
19
+// import UserConversion from './components/UserConversion';
20
+// import BuildingStatistic from './BuildingStatistic';
21
+const { TabPane } = Tabs;
22
+const { Option } = Select;
23
+
24
+const activityOverView = props => {
25
+  const timeRef = useRef();
26
+
27
+  const [data, setData] = useState({});
28
+  const [serachData, setSearchData] = useState({
29
+    startDate:
30
+      moment()
31
+        .subtract(7, 'day')
32
+        .format('YYYY-MM-DDT00:00:00.000') + 'Z',
33
+    endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
34
+  });
35
+  const [timeValue, setTimeValue] = useState();
36
+
37
+  const [time, setTime] = useState();
38
+
39
+
40
+  //重置搜索
41
+  const handleReset = e => {
42
+    props.form.resetFields();
43
+    timeRef.current.reset();
44
+    setSearchData({
45
+      startDate:
46
+        moment()
47
+          .subtract(7, 'day')
48
+          .format('YYYY-MM-DDT00:00:00.000') + 'Z',
49
+      endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
50
+    });
51
+  };
52
+
53
+  const onTimeChange = e => {
54
+    setTime(e);
55
+  };
56
+  const handleSubmit = e => {
57
+    props.form.validateFieldsAndScroll((err, values) => {
58
+      setTimeValue();
59
+      setSearchData({
60
+        ...values,
61
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
62
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
63
+      });
64
+    });
65
+  };
66
+
67
+
68
+  const { getFieldDecorator } = props.form;
69
+
70
+  return (
71
+    <div>
72
+      <Form layout="inline" onSubmit={handleSubmit}>
73
+        <Form.Item>
74
+          <TimeSelect onChange={onTimeChange} ref={timeRef}></TimeSelect>
75
+        </Form.Item>
76
+        <Form.Item>{getFieldDecorator('buildingId')(<BuildingSelect allowClear />)}</Form.Item>
77
+        <Form.Item>
78
+          {getFieldDecorator('targetType')(
79
+            <Select placeholder="活动类型" allowClear style={{ width: 150, marginLeft: '20px' }}>
80
+              <Option value="dymic">报名</Option>
81
+              <Option value="look">带看</Option>
82
+              <Option value="house">团房</Option>
83
+              <Option value="live">直播</Option>
84
+            </Select>,
85
+          )}
86
+        </Form.Item>
87
+        <Form.Item>
88
+          <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
89
+            搜索
90
+          </Button>
91
+          <Button onClick={e => handleReset()} style={{ marginLeft: '30px' }}>
92
+            重置
93
+          </Button>
94
+        </Form.Item>
95
+      </Form>
96
+      <div style={{ marginTop: '20px' }}>
97
+        <ActivityCount params={serachData}></ActivityCount>
98
+      </div>
99
+      <div style={{ marginTop: '20px' }}>
100
+        <NewUsers params={serachData} dataZoom={false}></NewUsers>
101
+      </div>
102
+      <div style={{ marginTop: '20px' }}>
103
+        <OverviewDeatil params={serachData} ></OverviewDeatil>
104
+      </div>
105
+    </div>
106
+  );
107
+};
108
+
109
+const WrappedTypeForm = Form.create()(activityOverView);
110
+export default WrappedTypeForm;

+ 332
- 0
src/pages/statistics/activity/addRegistNum.jsx Целия файл

@@ -0,0 +1,332 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import {
3
+  Form,
4
+  Icon,
5
+  Input,
6
+  Button,
7
+  DatePicker,
8
+  Select,
9
+  Card,
10
+  Row,
11
+  Col,
12
+  Pagination,
13
+  Alert,
14
+  Table,
15
+  Avatar,
16
+  Radio,
17
+  Modal,
18
+  Descriptions,
19
+} from 'antd';
20
+import moment from 'moment';
21
+import request from '../../../utils/request';
22
+import apis from '../../../services/apis';
23
+import router from 'umi/router';
24
+import AuthButton from '@/components/AuthButton';
25
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
26
+import WxDictSelect from '@/components/SelectButton/WxDictSelect';
27
+import Prompt from 'umi/prompt';
28
+
29
+const { RangePicker } = DatePicker;
30
+const { Option } = Select;
31
+
32
+const formItemLayout = {
33
+  labelCol: { span: 10 },
34
+  wrapperCol: { span: 14 },
35
+};
36
+
37
+let daterange = [];
38
+let tableTitle = ['类型'];
39
+
40
+let columns = [
41
+  {
42
+    title: '姓名',
43
+    dataIndex: 'nickName',
44
+    key: 'nickName',
45
+  },
46
+  {
47
+    title: '电话',
48
+    dataIndex: 'phone',
49
+    key: 'phone',
50
+  },
51
+  {
52
+    title: '性别',
53
+    dataIndex: 'gender',
54
+    key: 'gender',
55
+  },
56
+  {
57
+    title: '归属地',
58
+    dataIndex: 'province',
59
+    key: 'province',
60
+  },
61
+  {
62
+    title: '来源渠道',
63
+    dataIndex: 'personFrom',
64
+    key: 'personFrom',
65
+  },
66
+  {
67
+    title: '置业顾问',
68
+    dataIndex: 'realtyConsultant',
69
+    key: 'realtyConsultant',
70
+  },
71
+  {
72
+    title: '置业顾问电话',
73
+    dataIndex: 'realtyConsultantPhone',
74
+    key: 'realtyConsultantPhone',
75
+  },
76
+  {
77
+    title: '分享者',
78
+    dataIndex: 'sharePersonName',
79
+    key: 'sharePersonName',
80
+  },
81
+  {
82
+    title: '分享者电话',
83
+    dataIndex: 'sharePersonPhone',
84
+    key: 'sharePersonPhone',
85
+  },
86
+];
87
+
88
+class SharePersonNum extends React.Component {
89
+  constructor(props) {
90
+    super(props);
91
+    let startDate;
92
+    let endDate;
93
+    if (props.location.query.queryDate) {
94
+      startDate =
95
+        moment(props.location.query.queryDate)
96
+          .hours(0)
97
+          .minutes(0)
98
+          .seconds(0)
99
+          .milliseconds(0)
100
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
101
+      endDate =
102
+        moment(props.location.query.queryDate)
103
+          .hours(23)
104
+          .minutes(59)
105
+          .seconds(59)
106
+          .milliseconds(999)
107
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
108
+    } else {
109
+      startDate =
110
+        moment(props.location.query.startDate)
111
+          .hours(0)
112
+          .minutes(0)
113
+          .seconds(0)
114
+          .milliseconds(0)
115
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
116
+      endDate =
117
+        moment(props.location.query.endDate)
118
+          .hours(23)
119
+          .minutes(59)
120
+          .seconds(59)
121
+          .milliseconds(999)
122
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
123
+    }
124
+
125
+    this.state = {
126
+      formData: {
127
+        personFrom: '',
128
+        province: '',
129
+        pageNum: '',
130
+        pageSize: '',
131
+        startDate: startDate,
132
+        endDate: endDate,
133
+        activityId: props.location.query.activityId,
134
+        activityType: props.location.query.activityType,
135
+        buildingId: props.location.query.buildingId,
136
+      },
137
+      personData: [],
138
+      dataSoures: [],
139
+      tableData: [],
140
+      userType: 'all',
141
+      activityName: props.location.query.activityName,
142
+    };
143
+  }
144
+
145
+  componentDidMount() {
146
+    this.getTableList();
147
+  }
148
+
149
+  getTableList() {
150
+    const { formData } = this.state;
151
+    console.log(formData);
152
+    request({ ...apis.activityDataStatis.activityAddRegist, params: formData })
153
+      .then(data => {
154
+        console.log(data);
155
+        this.setState({ tableData: data.records, total: data.total });
156
+      })
157
+      .catch();
158
+  }
159
+
160
+  handleSubmit = (e, props) => {
161
+    let startDate = null;
162
+    let endDate = null;
163
+    const personFrom = this.props.form.getFieldValue('personFrom');
164
+    const province = this.props.form.getFieldValue('province');
165
+    const { formData } = this.state;
166
+    this.setState(
167
+      {
168
+        formData: {
169
+          ...formData,
170
+          personFrom: personFrom,
171
+          province: province,
172
+          pageNum: 1,
173
+          pageSize: 999,
174
+        },
175
+      },
176
+      this.getTableList,
177
+    );
178
+  };
179
+
180
+  //重置搜索
181
+  handleReset = e => {
182
+    this.props.form.resetFields();
183
+    let startDate;
184
+    let endDate;
185
+    if (this.props.location.query.queryDate) {
186
+      startDate =
187
+        moment(this.props.location.query.queryDate)
188
+          .hours(0)
189
+          .minutes(0)
190
+          .seconds(0)
191
+          .milliseconds(0)
192
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
193
+      endDate =
194
+        moment(this.props.location.query.queryDate)
195
+          .hours(23)
196
+          .minutes(59)
197
+          .seconds(59)
198
+          .milliseconds(999)
199
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
200
+    } else {
201
+      startDate =
202
+        moment(this.props.location.query.startDate)
203
+          .hours(0)
204
+          .minutes(0)
205
+          .seconds(0)
206
+          .milliseconds(0)
207
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
208
+      endDate =
209
+        moment(this.props.location.query.endDate)
210
+          .hours(23)
211
+          .minutes(59)
212
+          .seconds(59)
213
+          .milliseconds(999)
214
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
215
+    }
216
+    this.setState(
217
+      {
218
+        formData: {
219
+          personFrom: '',
220
+          province: '',
221
+          pageNum: '',
222
+          pageSize: '',
223
+          startDate: startDate,
224
+          endDate: endDate,
225
+          activityId: this.props.location.query.activityId,
226
+          activityType: this.props.location.query.activityType,
227
+          buildingId: this.props.location.query.buildingId,
228
+        },
229
+        personData: [],
230
+        dataSoures: [],
231
+        tableData: [],
232
+        userType: 'all',
233
+        activityName: this.props.location.query.activityName,
234
+      },
235
+      this.getTableList,
236
+    );
237
+  };
238
+
239
+  goback = () => {
240
+    router.go(-1);
241
+  };
242
+
243
+  exportActivityStats = () => {
244
+    const { formData } = this.state;
245
+    request({ ...apis.activityDataStatis.activityAddRegistNumExport, params: formData })
246
+      .then(data => {
247
+        if (!data) {
248
+          return;
249
+        }
250
+        const url = window.URL.createObjectURL(new Blob([data]));
251
+        const link = document.createElement('a');
252
+        link.style.display = 'none';
253
+        link.href = url;
254
+        link.setAttribute('download', '分享统计.xlsx');
255
+        document.body.append(link);
256
+        link.click();
257
+      })
258
+      .catch();
259
+  };
260
+
261
+  //排序
262
+  handleTableChange = (pagination, filters, sorter) => {
263
+    console.log(pagination, filters, sorter);
264
+    const { formData } = this.state;
265
+    this.setState(
266
+      {
267
+        formData: {
268
+          ...formData,
269
+          personFrom: formData.personFrom,
270
+          pageNum: pagination.current,
271
+          pageSize: pagination.pageSize,
272
+        },
273
+      },
274
+      this.getTableList,
275
+    );
276
+  };
277
+
278
+  render() {
279
+    const { radioVal } = this.state;
280
+    const { getFieldDecorator } = this.props.form;
281
+
282
+    return (
283
+      <Card>
284
+        <div align="right" style={{ marginBottom: '16px' }}>
285
+          <Button onClick={this.goback}>返回</Button>
286
+        </div>
287
+        {this.state.activityName && (
288
+          <div>
289
+            <span style={{ marginLeft: '20px' }}>分享内容:{this.state.activityName}</span>
290
+          </div>
291
+        )}
292
+        <Form layout="inline" onSubmit={e => this.handleSubmit(e, this.props)}>
293
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
294
+            {getFieldDecorator('province')(<Input placeholder="请输入归属地" />)}
295
+          </Form.Item>
296
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
297
+            {getFieldDecorator('personFrom')(<WxDictSelect />)}
298
+          </Form.Item>
299
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
300
+            <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
301
+              搜索
302
+            </Button>
303
+            <Button onClick={e => this.handleReset()} style={{ marginLeft: '30px' }}>
304
+              重置
305
+            </Button>
306
+          </Form.Item>
307
+        </Form>
308
+        <div>
309
+          <AuthButton name="admin.statistical.activity.export" noRight={null}>
310
+            <Button
311
+              type="primary"
312
+              style={{ float: 'right', margin: '20px 0', zIndex: 1 }}
313
+              onClick={this.exportActivityStats}
314
+            >
315
+              导出
316
+            </Button>
317
+          </AuthButton>
318
+          <Table
319
+            style={{ marginTop: '20px' }}
320
+            dataSource={this.state.tableData}
321
+            columns={columns}
322
+            pagination={{ total: this.state.total }}
323
+            onChange={this.handleTableChange}
324
+            scroll={{ y: 500 }}
325
+          ></Table>
326
+        </div>
327
+      </Card>
328
+    );
329
+  }
330
+}
331
+const WrappedTypeForm = Form.create()(SharePersonNum);
332
+export default WrappedTypeForm;

+ 289
- 0
src/pages/statistics/activity/compents/ContentTable.jsx Целия файл

@@ -0,0 +1,289 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Table, Button } from 'antd';
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 Navigate from '@/components/Navigate';
9
+import AuthButton from '@/components/AuthButton';
10
+const ContentTable = props => {
11
+  const { params } = props;
12
+  const [data, setData] = useState({ records: [] });
13
+  const formatDate = (start, end) => {
14
+    const startDate = moment(start).format('YYYY-MM-DDT00:00:00.000') + 'Z';
15
+    const endDate = moment(end).format('YYYY-MM-DDT23:59:59.999') + 'Z';
16
+    return { startDate, endDate };
17
+  };
18
+
19
+  useEffect(() => {
20
+    getTableList({
21
+      ...params,
22
+    });
23
+  }, [params]);
24
+
25
+  function getTableList(params) {
26
+    request({
27
+      ...apis.activityDataStatis.activityDetailTableData,
28
+      params: {
29
+        ...params,
30
+      },
31
+    })
32
+      .then(data => {
33
+        console.log(data);
34
+        setData(data);
35
+        // this.setState({ tableData: data.records, total: data.total });
36
+      })
37
+      .catch();
38
+  }
39
+
40
+  const toSharePersonNum = rowData => () => {
41
+    // const startDate = moment().subtract(dateType, 'day').toDate()
42
+    // const endDate = new Date()
43
+
44
+    if (rowData) {
45
+      router.push({
46
+        pathname: '/statistics/activity/sharePersonNum',
47
+        query: {
48
+          startDate: params.startDate,
49
+          endDate: params.endDate,
50
+          activityId: rowData.activityId,
51
+          activityType: rowData.activityType,
52
+          activityName: rowData.activityName,
53
+        },
54
+      });
55
+      return;
56
+    }
57
+  };
58
+
59
+  const toShareNum = rowData => () => {
60
+    // const startDate = moment().subtract(dateType, 'day').toDate()
61
+    // const endDate = new Date()
62
+    if (rowData) {
63
+      router.push({
64
+        pathname: '/statistics/activity/shareNum',
65
+        query: {
66
+          startDate: params.startDate,
67
+          endDate: params.endDate,
68
+          activityId: rowData.activityId,
69
+          activityType: rowData.activityType,
70
+          activityName: rowData.activityName,
71
+        },
72
+      });
73
+      return;
74
+    }
75
+  };
76
+
77
+  const toAddRegistNum = rowData => () => {
78
+    // const startDate = moment().subtract(dateType, 'day').toDate()
79
+    // const endDate = new Date()
80
+    // console.log(rowData, 'rowData')
81
+    if (rowData) {
82
+      router.push({
83
+        pathname: '/statistics/activity/addRegistNum',
84
+        query: {
85
+          startDate: params.startDate,
86
+          endDate: params.endDate,
87
+          activityId: rowData.activityId,
88
+          activityType: rowData.activityType,
89
+          activityName: rowData.activityName,
90
+        },
91
+      });
92
+      return;
93
+    }
94
+  };
95
+
96
+  const toAddVisitPersonNum = rowData => () => {
97
+    if (rowData) {
98
+      router.push({
99
+        pathname: '/statistics/activity/visitPersonNum',
100
+        query: {
101
+          startDate: params.startDate,
102
+          endDate: params.endDate,
103
+          activityId: rowData.activityId,
104
+          activityType: rowData.activityType,
105
+          activityName: rowData.activityName,
106
+        },
107
+      });
108
+      return;
109
+    }
110
+  };
111
+
112
+  const toAddVisitNum = rowData => () => {
113
+    if (rowData) {
114
+      router.push({
115
+        pathname: '/statistics/activity/visitNum',
116
+        query: {
117
+          startDate: params.startDate,
118
+          endDate: params.endDate,
119
+          activityId: rowData.activityId,
120
+          activityType: rowData.activityType,
121
+          activityName: rowData.activityName,
122
+        },
123
+      });
124
+      return;
125
+    }
126
+  };
127
+
128
+  const toDetail = rowData => {
129
+    if (rowData) {
130
+      router.push({
131
+        pathname: '/statistics/activity/detail',
132
+        query: {
133
+          startDate: params.startDate,
134
+          endDate: params.endDate,
135
+          targetId: rowData.activityId,
136
+          targetType: rowData.activityType,
137
+          targetName: rowData.activityName,
138
+          buildingId: '',
139
+        },
140
+      });
141
+  
142
+      return
143
+    }
144
+  }
145
+
146
+  let columns = [
147
+    {
148
+      title: '活动类型',
149
+      dataIndex: 'activityType',
150
+      key: 'activityType',
151
+      render: (text, records) => {
152
+        if (records.activityType === 'live') {
153
+          return '直播活动';
154
+        }
155
+        if (records.activityType === 'look') {
156
+          return '一键带看';
157
+        }
158
+        if (records.activityType === 'house') {
159
+          return '团房活动';
160
+        }
161
+        if (records.activityType === 'dymic') {
162
+          return '报名活动';
163
+        }
164
+      },
165
+    },
166
+    {
167
+      title: '活动名称',
168
+      dataIndex: 'activityName',
169
+      key: 'activityName',
170
+    },
171
+    {
172
+      title: '访问人数',
173
+      dataIndex: 'visitPersonNum',
174
+      key: 'visitPersonNum',
175
+      sorter: true,
176
+      render: (text, record) => (
177
+        <Navigate onClick={toAddVisitPersonNum(record)}>{record.visitPersonNum}</Navigate>
178
+      ),
179
+    },
180
+    {
181
+      title: '访问次数',
182
+      dataIndex: 'visitNum',
183
+      key: 'visitNum',
184
+      sorter: true,
185
+      render: (text, record) => (
186
+        <Navigate onClick={toAddVisitNum(record)}>{record.visitNum}</Navigate>
187
+        // <a style={{ color: '#66B3FF' }} onClick={toAddVisitNum(record)}><span>{record.visitNum}</span></a>
188
+      ),
189
+    },
190
+    {
191
+      title: '新增注册用户',
192
+      dataIndex: 'addRegistNum',
193
+      key: 'addRegistNum',
194
+      sorter: true,
195
+      render: (text, record) => (
196
+        <Navigate onClick={toAddRegistNum(record)}>{record.addRegistNum}</Navigate>
197
+        // <a style={{ color: '#66B3FF' }} onClick={toAddRegistNum(record)}><span>{record.addRegistNum}</span></a>
198
+      ),
199
+    },
200
+    {
201
+      title: '分享人数',
202
+      dataIndex: 'sharePersonNum',
203
+      key: 'sharePersonNum',
204
+      sorter: true,
205
+      render: (text, record) => (
206
+        <Navigate onClick={toSharePersonNum(record)}>{record.sharePersonNum}</Navigate>
207
+      ),
208
+    },
209
+    {
210
+      title: '分享次数',
211
+      dataIndex: 'shareNum',
212
+      key: 'shareNum',
213
+      sorter: true,
214
+      render: (text, record) => <Navigate onClick={toShareNum(record)}>{record.shareNum}</Navigate>,
215
+    },
216
+    {
217
+      title: '详情',
218
+      align: 'center',
219
+      render: (text, record) => (
220
+        <a style={{ color: '#FF4A4A' }} onClick={() => toDetail(record)}>
221
+          查看
222
+        </a>
223
+      ),
224
+    },
225
+  ];
226
+
227
+  // const toAddVisitNum = record => {
228
+  //   router.push({
229
+  //     pathname: '/activity/SignupActivity/registrationRecord',
230
+  //     query: {
231
+  //       dynamicId: record.dynamicId,
232
+  //     },
233
+  //   });
234
+  // };
235
+
236
+  //排序
237
+  const handleTableChange = (pagination, filters, sorter) => {
238
+
239
+    getTableList({
240
+      ...params,
241
+      pageNum: pagination.current,
242
+      pageSize: pagination.pageSize,
243
+      sort: sorter.order,
244
+      colKey: sorter.columnKey
245
+    });
246
+  };
247
+
248
+  const exportActivityStats = () => {
249
+    request({ ...apis.activityDataStatis.activityDetailTableDataExport, params: params })
250
+      .then(data => {
251
+        if (!data) {
252
+          return;
253
+        }
254
+        const url = window.URL.createObjectURL(new Blob([data]));
255
+        const link = document.createElement('a');
256
+        link.style.display = 'none';
257
+        link.href = url;
258
+        link.setAttribute('download', '活动统计.xlsx');
259
+        document.body.append(link);
260
+        link.click();
261
+      })
262
+      .catch();
263
+  };
264
+  return (
265
+    <Card>
266
+      <div style={{ textAlign: 'right' }}>
267
+        <AuthButton name="admin.staisttics.activity.export" noRight={null}>
268
+          <Button
269
+            type="primary"
270
+            style={{ float: 'right', margin: '20px 0', zIndex: 1 }}
271
+            onClick={exportActivityStats}
272
+          >
273
+            导出
274
+          </Button>
275
+        </AuthButton>
276
+      </div>
277
+
278
+      <Table
279
+        columns={columns}
280
+        dataSource={data?.records}
281
+        key="dynamicId"
282
+        pagination={{ current: data?.current, pageSize: 10, total: data?.total }}
283
+        onChange={handleTableChange}
284
+      ></Table>
285
+    </Card>
286
+  );
287
+};
288
+
289
+export default ContentTable;

+ 128
- 0
src/pages/statistics/activity/compents/NewUsers.jsx Целия файл

@@ -0,0 +1,128 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import {Card} from 'antd'
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
+
9
+const NewUsers = props => {
10
+  const { params } = props;
11
+  const [data, setData] = useState({ records: [] });
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
+  useEffect(() => {
19
+    NewsUserCount({
20
+      ...params,
21
+      ...formatDate(params.startDate, params.endDate),
22
+    });
23
+  }, [params]);
24
+
25
+  function NewsUserCount(params) {
26
+    request({
27
+      ...apis.activityDataStatis.selectAllActivityUser,
28
+      params: { ...params },
29
+    }).then(data => {
30
+      setData(data);
31
+    });
32
+  }
33
+
34
+  const dataZoom = props.dataZoom
35
+    ? [
36
+        {
37
+          type: 'inside',
38
+          start: 0,
39
+          end: 100,
40
+        },
41
+        {
42
+          type: 'slider',
43
+          start: 0,
44
+          end: 100,
45
+        },
46
+      ]
47
+    : undefined;
48
+  const dataset = data.selectAllActivityUser || [];
49
+  const options = {
50
+    color: [
51
+      'rgba(241,43,62,1)',
52
+      'rgba(254,146,156,1)',
53
+      'rgba(100,124,225,1)',
54
+      'rgba(162,185,255,1)',
55
+      'rgba(255,132,79,1)',
56
+    ],
57
+    tooltip: {
58
+      trigger: 'axis',
59
+    },
60
+    icon: 'rect',
61
+    legend: {
62
+      data: ['访问人数', '访问次数', '新增注册用户', '分享人数', '分享次数'],
63
+    },
64
+    toolbox: {},
65
+    xAxis: {
66
+      type: 'category',
67
+    },
68
+    yAxis: {},
69
+    dataZoom,
70
+    series: [
71
+      {
72
+        name: '访问人数',
73
+        type: 'line',
74
+        smooth: true,
75
+      },
76
+      {
77
+        name: '访问次数',
78
+        type: 'line',
79
+        smooth: true,
80
+      },
81
+      {
82
+        name: '新增注册用户',
83
+        type: 'line',
84
+        smooth: true,
85
+      },
86
+      {
87
+        name: '分享人数',
88
+        type: 'line',
89
+        smooth: true,
90
+      },
91
+      {
92
+        name: '分享次数',
93
+        type: 'line',
94
+        smooth: true,
95
+      },
96
+    ],
97
+    dataset: {
98
+      dimensions: [
99
+        'date',
100
+        'visitPersonCount',
101
+        'visitCount',
102
+        'addregistCount',
103
+        'sharePersonCount',
104
+        'shareCount',
105
+      ],
106
+      source: dataset,
107
+    },
108
+  };
109
+
110
+  const piestyles = {
111
+    width: '100%',
112
+    height: '400px',
113
+  };
114
+
115
+  return (
116
+    <Card title="活动趋势图" headStyle={{ textAlign: 'left' }}>
117
+      <EChart options={options} />
118
+    </Card>
119
+    // <>
120
+    //   <div ><p><span style={{fontSize:'0.12rem',fontWeight:'600'}}>活动趋势图</span></p></div>
121
+    //   <div style={{marginTop:'30px'}}>
122
+
123
+    //   </div>
124
+    // </>
125
+  );
126
+};
127
+
128
+export default NewUsers;

+ 204
- 0
src/pages/statistics/activity/compents/OverviewDeatil.jsx Целия файл

@@ -0,0 +1,204 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Table, Button } from 'antd';
3
+import Navigate from '@/components/Navigate';
4
+import EChart from '../../../../components/EchartsTest/EChart';
5
+import request from '../../../../utils/request';
6
+import apis from '../../../../services/apis';
7
+import moment from 'moment';
8
+import router from 'umi/router';
9
+
10
+const NewUsers = props => {
11
+  const { params } = props;
12
+  const [data, setData] = useState({ records: [] });
13
+
14
+  const toSharePersonNum = rowData => () => {
15
+    if (rowData) {
16
+      router.push({
17
+        pathname: '/statistics/activity/sharePersonNum',
18
+        query: {
19
+          queryDate: rowData.date,
20
+          buildingId: params.buildingId || undefined,
21
+          activityType: params.activityType || undefined,
22
+        },
23
+      });
24
+      return;
25
+    }
26
+  };
27
+
28
+  const toShareNum = rowData => () => {
29
+    if (rowData) {
30
+      router.push({
31
+        pathname: '/statistics/activity/shareNum',
32
+        query: {
33
+          queryDate: rowData.date,
34
+          buildingId: params.buildingId || undefined,
35
+          activityType: params.activityType || undefined,
36
+        },
37
+      });
38
+      return;
39
+    }
40
+  };
41
+
42
+  const toAddVisitPersonNum = rowData => () => {
43
+    if (rowData) {
44
+      router.push({
45
+        pathname: '/statistics/activity/visitPersonNum',
46
+        query: {
47
+          queryDate: rowData.date,
48
+          buildingId: params.buildingId || undefined,
49
+          activityType: params.activityType || undefined,
50
+        },
51
+      });
52
+      return;
53
+    }
54
+  };
55
+
56
+  const toAddVisitNum = rowData => () => {
57
+    if (rowData) {
58
+      router.push({
59
+        pathname: '/statistics/activity/visitNum',
60
+        query: {
61
+          queryDate: rowData.date,
62
+          buildingId: params.buildingId || undefined,
63
+          activityType: params.activityType || undefined,
64
+        },
65
+      });
66
+      return;
67
+    }
68
+  };
69
+
70
+  const toAddRegistNum = rowData => () => {
71
+    if (rowData) {
72
+      router.push({
73
+        pathname: '/statistics/activity/addRegistNum',
74
+        query: {
75
+          queryDate: rowData.date,
76
+          buildingId: params.buildingId || undefined,
77
+          activityType: params.activityType || undefined,
78
+        },
79
+      });
80
+      return;
81
+    }
82
+  };
83
+
84
+  const columns = [
85
+    {
86
+      title: '日期',
87
+      dataIndex: 'date',
88
+      key: 'date',
89
+    },
90
+    {
91
+      title: '分享人数',
92
+      dataIndex: 'sharePersonNum',
93
+      key: 'sharePersonNum',
94
+      sorter: true,
95
+      render: (text, record) => (
96
+        <Navigate onClick={toSharePersonNum(record)}>{record.sharePersonNum}</Navigate>
97
+      ),
98
+    },
99
+    {
100
+      title: '分享次数',
101
+      dataIndex: 'shareNum',
102
+      key: 'shareNum',
103
+      sorter: true,
104
+      render: (text, record) => <Navigate onClick={toShareNum(record)}>{record.shareNum}</Navigate>,
105
+    },
106
+
107
+    {
108
+      title: '访问人数',
109
+      dataIndex: 'visitPersonNum',
110
+      key: 'visitPersonNum',
111
+      sorter: true,
112
+      render: (text, record) => (
113
+        <Navigate onClick={toAddVisitPersonNum(record)}>{record.visitPersonNum}</Navigate>
114
+      ),
115
+    },
116
+    {
117
+      title: '访问次数',
118
+      dataIndex: 'visitNum',
119
+      key: 'visitNum',
120
+      sorter: true,
121
+      render: (text, record) => (
122
+        <Navigate onClick={toAddVisitNum(record)}>{record.visitNum}</Navigate>
123
+      ),
124
+    },
125
+    {
126
+      title: '新增注册用户',
127
+      dataIndex: 'addRegistNum',
128
+      key: 'addRegistNum',
129
+      sorter: true,
130
+      render: (text, record) => (
131
+        <Navigate onClick={toAddRegistNum(record)}>{record.addRegistNum}</Navigate>
132
+      ),
133
+    },
134
+  ];
135
+
136
+  useEffect(() => {
137
+    getTableList();
138
+  }, [params]);
139
+
140
+  const getTableList = payload => {
141
+    request({
142
+      ...apis.activityDataStatis.tableData,
143
+      params: { ...params, ...payload },
144
+    })
145
+      .then(res => {
146
+        setData(res);
147
+      })
148
+      .catch();
149
+  };
150
+
151
+  const exportActivityStats = () => {
152
+    request({ ...apis.activityDataStatis.tableDataExport, params: params })
153
+      .then(data => {
154
+        if (!data) {
155
+          return;
156
+        }
157
+        const url = window.URL.createObjectURL(new Blob([data]));
158
+        const link = document.createElement('a');
159
+        link.style.display = 'none';
160
+        link.href = url;
161
+        link.setAttribute('download', '活动统计.xlsx');
162
+        document.body.append(link);
163
+        link.click();
164
+      })
165
+      .catch();
166
+  };
167
+
168
+  //排序
169
+  const handleTableChange = (pagination, filters, sorter) => {
170
+    console.log(pagination, filters, sorter);
171
+    // Desc  和asc
172
+    const sortType =
173
+      sorter.order == 'ascend' ? 'asc' : sorter.order == 'descend' ? 'Desc' : undefined;
174
+    getTableList({
175
+      ...params,
176
+      pageNum: pagination.current,
177
+      pageSize: pagination.pageSize,
178
+      sortType: sortType,
179
+      sortField: sorter.columnKey,
180
+    });
181
+  };
182
+
183
+  return (
184
+    <Card title="详细数据" headStyle={{ textAlign: 'left' }}>
185
+      {/* <div style={{ textAlign: 'right' }}>
186
+        <Button type="primary" onClick={exportActivityStats}>
187
+          导出
188
+        </Button>
189
+      </div> */}
190
+
191
+      <Table
192
+        key="date"
193
+        dataSource={data?.records}
194
+        columns={columns}
195
+        pagination={{ total: data?.total, current: data?.current, pageSize: data?.size }}
196
+        onChange={handleTableChange}
197
+        scroll={{ y: 500 }}
198
+      ></Table>
199
+    </Card>
200
+  );
201
+};
202
+
203
+export default NewUsers;
204
+// pagination={{ total: this.state.total}} onChange={this.handleTableChange}

+ 102
- 0
src/pages/statistics/activity/compents/activityCount.jsx Целия файл

@@ -0,0 +1,102 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Statistic, Icon } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+
10
+function getDayBegin(dt) {
11
+  return moment(dt, 'day').hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss')+'.000Z';
12
+}
13
+
14
+
15
+function getDayEnd(dt) {
16
+  return moment(dt, 'day').hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss')+'.999Z';
17
+}
18
+
19
+
20
+const Count = props => {
21
+  const {params} = props
22
+  const [data, setData] = useState([]);
23
+
24
+
25
+  const [checkData, setCheckData] = useState([]);
26
+
27
+  useEffect(() => {
28
+    getList()
29
+
30
+  }, [params]);
31
+
32
+ const getList =() => {
33
+
34
+console.log(params,'params')
35
+    request({
36
+      ...apis.activityDataStatis.total,
37
+      params: {
38
+        ...params,
39
+        // startDate: getDayBegin(params.startDate),
40
+        // endDate: getDayEnd(params.endDate),
41
+      }
42
+    }).then(res => {
43
+    setData(res)
44
+    }).catch(err => {
45
+
46
+    })
47
+  }
48
+
49
+//   function getBuildingReports() {
50
+//     request({ ...apis.system.taBuildingReports }).then(data => {
51
+//       console.log(
52
+//         (data.records || []).map(x => x.reportCode),
53
+//         '22222222222222222',
54
+//       );
55
+//       setCheckData((data.records || []).map(x => x.reportCode));
56
+//     });
57
+//   }
58
+
59
+  return (
60
+    <>
61
+      <Row gutter={16} style={{textAlign:'center'}}>
62
+        <Col span={6}>
63
+          <Card>
64
+            <Statistic
65
+              title="分享总次数"
66
+              value={data.shareNum || 0}
67
+              //   valueStyle={{ color: '#3f8600' }}
68
+            />
69
+          </Card>
70
+        </Col>
71
+        <Col span={6}>
72
+          <Card>
73
+            <Statistic
74
+              title="分享总人数"
75
+              value={data.sharePersonNum || 0}
76
+              //   valueStyle={{ color: '#cf1322' }}
77
+            />
78
+          </Card>
79
+        </Col>
80
+        <Col span={6}>
81
+          <Card>
82
+            <Statistic
83
+              title="访问总次数"
84
+              value={data.visitNum || 0}
85
+              //   valueStyle={{ color: '#3f8600' }}
86
+            />
87
+          </Card>
88
+        </Col>
89
+        <Col span={6}>
90
+          <Card >
91
+            <Statistic
92
+              title="访问总人数"
93
+              value={data.visitPersonNum || 0}
94
+              //   valueStyle={{ color: '#cf1322' }}
95
+            />
96
+          </Card>
97
+        </Col>
98
+      </Row>
99
+    </>
100
+  );
101
+};
102
+export default Count;

+ 87
- 0
src/pages/statistics/activity/detail.jsx Целия файл

@@ -0,0 +1,87 @@
1
+import React, { Component, useState, useEffect, useRef } from 'react';
2
+import { Card, Row, Col, Statistic, Icon, Tabs, Form, Select, Button, Modal } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+import TimeSelect from '../compents/TimeSelect';
10
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
11
+import Navigate from '@/components/Navigate';
12
+import NewUsers from './compents/NewUsers';
13
+import OverviewDeatil from './compents/OverviewDeatil';
14
+
15
+const activityOverView = props => {
16
+  const timeRef = useRef();
17
+
18
+  const [data, setData] = useState({});
19
+  const [serachData, setSearchData] = useState({
20
+    startDate:
21
+      moment()
22
+        .subtract(7, 'day')
23
+        .format('YYYY-MM-DDT00:00:00.000') + 'Z',
24
+    endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
25
+    ...props.location.query,
26
+  });
27
+  const [timeValue, setTimeValue] = useState();
28
+
29
+  const [time, setTime] = useState();
30
+
31
+  //重置搜索
32
+  const handleReset = e => {
33
+    props.form.resetFields();
34
+    timeRef.current.reset();
35
+    setSearchData({
36
+      startDate:
37
+        moment()
38
+          .subtract(7, 'day')
39
+          .format('YYYY-MM-DDT00:00:00.000') + 'Z',
40
+      endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
41
+    });
42
+  };
43
+
44
+  const onTimeChange = e => {
45
+    setTime(e);
46
+  };
47
+  const handleSubmit = e => {
48
+    props.form.validateFieldsAndScroll((err, values) => {
49
+      setTimeValue();
50
+      setSearchData({
51
+        ...values,
52
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
53
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
54
+      });
55
+    });
56
+  };
57
+
58
+  const { getFieldDecorator } = props.form;
59
+
60
+  return (
61
+    <div>
62
+      <Form layout="inline" onSubmit={handleSubmit}>
63
+        <Form.Item>
64
+          <TimeSelect onChange={onTimeChange} ref={timeRef}></TimeSelect>
65
+        </Form.Item>
66
+        <Form.Item>
67
+          <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
68
+            搜索
69
+          </Button>
70
+          <Button onClick={e => handleReset()} style={{ marginLeft: '30px' }}>
71
+            重置
72
+          </Button>
73
+        </Form.Item>
74
+      </Form>
75
+
76
+      <div style={{ marginTop: '20px' }}>
77
+        <NewUsers params={serachData} dataZoom={false}></NewUsers>
78
+      </div>
79
+      <div style={{ marginTop: '20px' }}>
80
+        <OverviewDeatil params={serachData}></OverviewDeatil>
81
+      </div>
82
+    </div>
83
+  );
84
+};
85
+
86
+const WrappedTypeForm = Form.create()(activityOverView);
87
+export default WrappedTypeForm;

+ 144
- 0
src/pages/statistics/activity/index copy.jsx Целия файл

@@ -0,0 +1,144 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Statistic, Icon, Table } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+import TimeSelect from '../compents/TimeSelect';
10
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
11
+import Navigate from '@/components/Navigate';
12
+// import Count from './components/Count';
13
+// import SourceRole from './components/SourceRole';
14
+// import UserSex from './components/UserSex';
15
+// import UserConversion from './components/UserConversion';
16
+// import BuildingStatistic from './BuildingStatistic';
17
+
18
+const DataReport = props => {
19
+  const [data, setData] = useState({});
20
+  const [time, setTime] = useState();
21
+  const [buildingValue, setBuildingValue] = useState();
22
+
23
+  useEffect(() => {
24
+    if (time) {
25
+      getTableList({
26
+        buildingId:buildingValue,
27
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
28
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
29
+      });
30
+    }
31
+  }, [time,buildingValue]);
32
+
33
+  const columns = [
34
+    {
35
+      title: '活动名称',
36
+      dataIndex: 'title',
37
+      key: 'title',
38
+      // sorter: true,
39
+    },
40
+    {
41
+      title: '访问人数',
42
+      dataIndex: 'visitPersonNum',
43
+      key: 'visit_person_num',
44
+      width:'25%',
45
+      sorter: true,
46
+      render: (text)=>text||0
47
+    },
48
+    {
49
+      title: '访问次数',
50
+      dataIndex: 'visitNum',
51
+      key: 'visit_num',
52
+      width:'25%',
53
+      sorter: true,
54
+      render: (text)=>text||0
55
+    },
56
+    {
57
+      title: '报名人数',
58
+      dataIndex: 'signNum',
59
+      key: 'sign_num',
60
+      width:'25%',
61
+      sorter: true,
62
+      // render: (text)=>text||0
63
+        render: (text, record) => (
64
+          text? <Navigate onClick={()=>toAddVisitNum(record)}>{record.signNum}</Navigate>:0
65
+          // <a style={{ color: '#66B3FF' }} onClick={toAddVisitNum(record)}><span>{record.visitNum}</span></a>
66
+        ),
67
+    },
68
+  ];
69
+
70
+  const  toAddVisitNum = (record)=>{
71
+    router.push({
72
+      pathname: '/activity/SignupActivity/registrationRecord',
73
+      query: {
74
+        dynamicId:record.dynamicId
75
+      },
76
+    });
77
+  }
78
+
79
+  //排序
80
+  const handleTableChange = (pagination, filters, sorter) => {
81
+    console.log(pagination, filters, sorter);
82
+    // Desc  和asc
83
+    const sortType=  sorter.order=="ascend"?'asc':sorter.order=="descend"?'Desc':undefined
84
+    getTableList({
85
+      buildingId:buildingValue,
86
+      startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
87
+      endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
88
+      pageNum: pagination.current,
89
+      pageSize: pagination.pageSize,
90
+      sortType: sortType,
91
+      sortField: sorter.columnKey,
92
+    });
93
+    // const { formData } = this.state
94
+    // this.setState({
95
+    //   formData: {
96
+    //     ...formData,
97
+    //     startDate: formData.startDate,
98
+    //     endDate: formData.endDate,
99
+    //     buildingId: formData.buildingId,
100
+    //     targetType: formData.targetType,
101
+    //     pageNum: pagination.current,
102
+    //     pageSize: pagination.pageSize,
103
+    //     sort: sorter.order,
104
+    //     colKey: sorter.columnKey
105
+    //   }
106
+    // }, this.getTableList)
107
+  };
108
+
109
+  function getTableList(params) {
110
+    request({
111
+      ...apis.activityDataStatis.activityDetailTableData,
112
+      params: {
113
+        ...params,
114
+      },
115
+    })
116
+      .then(data => {
117
+        console.log(data);
118
+        setData(data);
119
+        // this.setState({ tableData: data.records, total: data.total });
120
+      })
121
+      .catch();
122
+  }
123
+
124
+  const onTimeChange = e => {
125
+    setTime(e);
126
+  };
127
+
128
+  return (
129
+    <Card
130
+      title={<BuildingSelect value={buildingValue} onChange={e => setBuildingValue(e)} all />}
131
+      headStyle={{ textAlign: 'left' }}
132
+      extra={<TimeSelect onChange={onTimeChange}></TimeSelect>}
133
+    >
134
+      <Table
135
+        columns={columns}
136
+        dataSource={data?.records}
137
+        key="dynamicId"
138
+        pagination={{current:data?.current, pageSize: 10, total: data?.total }}
139
+        onChange={handleTableChange}
140
+      ></Table>
141
+    </Card>
142
+  );
143
+};
144
+export default DataReport;

+ 66
- 123
src/pages/statistics/activity/index.jsx Целия файл

@@ -1,5 +1,5 @@
1 1
 import React, { Component, useState, useEffect } from 'react';
2
-import { Card, Row, Col, Statistic, Icon, Table } from 'antd';
2
+import { Card, Row, Col, Statistic, Icon, Modal, Tabs, Button } from 'antd';
3 3
 // import IndexEcharts from './components/indexEcharts';
4 4
 // import Swiper from './swiper/index';
5 5
 import moment from 'moment';
@@ -9,136 +9,79 @@ import apis from '@/services/apis';
9 9
 import TimeSelect from '../compents/TimeSelect';
10 10
 import BuildingSelect from '@/components/SelectButton/BuildSelect';
11 11
 import Navigate from '@/components/Navigate';
12
-// import Count from './components/Count';
13
-// import SourceRole from './components/SourceRole';
14
-// import UserSex from './components/UserSex';
15
-// import UserConversion from './components/UserConversion';
16
-// import BuildingStatistic from './BuildingStatistic';
12
+import ActivityOverview from './activityOverview';
13
+import ActivityContent from './activityContent';
17 14
 
18
-const DataReport = props => {
19
-  const [data, setData] = useState({});
20
-  const [time, setTime] = useState();
21
-  const [buildingValue, setBuildingValue] = useState();
22 15
 
23
-  useEffect(() => {
24
-    if (time) {
25
-      getTableList({
26
-        buildingId:buildingValue,
27
-        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
28
-        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
29
-      });
30
-    }
31
-  }, [time,buildingValue]);
16
+const { TabPane } = Tabs;
32 17
 
33
-  const columns = [
34
-    {
35
-      title: '活动名称',
36
-      dataIndex: 'title',
37
-      key: 'title',
38
-      // sorter: true,
39
-    },
40
-    {
41
-      title: '访问人数',
42
-      dataIndex: 'visitPersonNum',
43
-      key: 'visit_person_num',
44
-      width:'25%',
45
-      sorter: true,
46
-      render: (text)=>text||0
47
-    },
48
-    {
49
-      title: '访问次数',
50
-      dataIndex: 'visitNum',
51
-      key: 'visit_num',
52
-      width:'25%',
53
-      sorter: true,
54
-      render: (text)=>text||0
55
-    },
56
-    {
57
-      title: '报名人数',
58
-      dataIndex: 'signNum',
59
-      key: 'sign_num',
60
-      width:'25%',
61
-      sorter: true,
62
-      // render: (text)=>text||0
63
-        render: (text, record) => (
64
-          text? <Navigate onClick={()=>toAddVisitNum(record)}>{record.signNum}</Navigate>:0
65
-          // <a style={{ color: '#66B3FF' }} onClick={toAddVisitNum(record)}><span>{record.visitNum}</span></a>
66
-        ),
67
-    },
68
-  ];
18
+const activity = props => {
69 19
 
70
-  const  toAddVisitNum = (record)=>{
71
-    router.push({
72
-      pathname: '/activity/SignupActivity/registrationRecord',
73
-      query: {
74
-        dynamicId:record.dynamicId
75
-      },
76
-    });
77
-  }
20
+  const [helpVisible, setHelpVisible] = useState(false);
78 21
 
79
-  //排序
80
-  const handleTableChange = (pagination, filters, sorter) => {
81
-    console.log(pagination, filters, sorter);
82
-    // Desc  和asc
83
-    const sortType=  sorter.order=="ascend"?'asc':sorter.order=="descend"?'Desc':undefined
84
-    getTableList({
85
-      buildingId:buildingValue,
86
-      startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
87
-      endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
88
-      pageNum: pagination.current,
89
-      pageSize: pagination.pageSize,
90
-      sortType: sortType,
91
-      sortField: sorter.columnKey,
92
-    });
93
-    // const { formData } = this.state
94
-    // this.setState({
95
-    //   formData: {
96
-    //     ...formData,
97
-    //     startDate: formData.startDate,
98
-    //     endDate: formData.endDate,
99
-    //     buildingId: formData.buildingId,
100
-    //     targetType: formData.targetType,
101
-    //     pageNum: pagination.current,
102
-    //     pageSize: pagination.pageSize,
103
-    //     sort: sorter.order,
104
-    //     colKey: sorter.columnKey
105
-    //   }
106
-    // }, this.getTableList)
107
-  };
108 22
 
109
-  function getTableList(params) {
110
-    request({
111
-      ...apis.activityDataStatis.activityDetailTableData,
112
-      params: {
113
-        ...params,
114
-      },
115
-    })
116
-      .then(data => {
117
-        console.log(data);
118
-        setData(data);
119
-        // this.setState({ tableData: data.records, total: data.total });
120
-      })
121
-      .catch();
23
+  function callback(key) {
24
+    console.log(key);
122 25
   }
123 26
 
124
-  const onTimeChange = e => {
125
-    setTime(e);
126
-  };
127
-
128 27
   return (
129
-    <Card
130
-      title={<BuildingSelect value={buildingValue} onChange={e => setBuildingValue(e)} all />}
131
-      headStyle={{ textAlign: 'left' }}
132
-      extra={<TimeSelect onChange={onTimeChange}></TimeSelect>}
133
-    >
134
-      <Table
135
-        columns={columns}
136
-        dataSource={data?.records}
137
-        key="dynamicId"
138
-        pagination={{current:data?.current, pageSize: 10, total: data?.total }}
139
-        onChange={handleTableChange}
140
-      ></Table>
141
-    </Card>
28
+    <div>
29
+      <Tabs
30
+        onChange={callback}
31
+        type="card"
32
+        tabBarExtraContent={
33
+          <Button type="link" onClick={() => setHelpVisible(true)}>
34
+            指标说明
35
+          </Button>
36
+        }
37
+      >
38
+        <TabPane tab="统计总况" key="1">
39
+          <ActivityOverview></ActivityOverview>
40
+        </TabPane>
41
+        <TabPane tab="统计内容" key="2">
42
+          <ActivityContent></ActivityContent>
43
+        </TabPane>
44
+      </Tabs>
45
+
46
+      <Modal
47
+        title="指标说明"
48
+        visible={helpVisible}
49
+        onCancel={() => setHelpVisible(false)}
50
+        footer={null}
51
+      >
52
+        <Row>
53
+          <p style={{ fontSize: '0.106rem', color: '#333', marginBottom: '4px' }}>分享人数:</p>
54
+          <p style={{ fontSize: '0.106rem', color: '#999', marginBottom: '8px' }}>
55
+            分享小程序活动的总人数
56
+          </p>
57
+        </Row>
58
+        <Row>
59
+          <p style={{ fontSize: '0.106rem', color: '#333', marginBottom: '4px' }}>分享次数:</p>
60
+          <p style={{ fontSize: '0.106rem', color: '#999', marginBottom: '8px' }}>
61
+            触发小程序活动分享的总次数
62
+          </p>
63
+        </Row>
64
+        <Row>
65
+          <p style={{ fontSize: '0.106rem', color: '#333', marginBottom: '4px' }}>新增注册用户:</p>
66
+          <p style={{ fontSize: '0.106rem', color: '#999', marginBottom: '8px' }}>
67
+            通过分享的活动授权手机号的总人数
68
+          </p>
69
+        </Row>
70
+        <Row>
71
+          <p style={{ fontSize: '0.106rem', color: '#333', marginBottom: '4px' }}>访问人数:</p>
72
+          <p style={{ fontSize: '0.106rem', color: '#999', marginBottom: '8px' }}>
73
+            访问小程序活动的总人数
74
+          </p>
75
+        </Row>
76
+
77
+        <Row>
78
+          <p style={{ fontSize: '0.106rem', color: '#333', marginBottom: '4px' }}>访问次数:</p>
79
+          <p style={{ fontSize: '0.106rem', color: '#999', marginBottom: '8px' }}>
80
+            访问小程序活动的总次数
81
+          </p>
82
+        </Row>
83
+      </Modal>
84
+    </div>
142 85
   );
143 86
 };
144
-export default DataReport;
87
+export default activity;

+ 359
- 0
src/pages/statistics/activity/shareNum.jsx Целия файл

@@ -0,0 +1,359 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import {
3
+  Form,
4
+  Icon,
5
+  Input,
6
+  Button,
7
+  DatePicker,
8
+  Select,
9
+  Card,
10
+  Row,
11
+  Col,
12
+  Pagination,
13
+  Alert,
14
+  Table,
15
+  Avatar,
16
+  Radio,
17
+  Modal,
18
+  Descriptions,
19
+} from 'antd';
20
+import moment from 'moment';
21
+import request from '../../../utils/request';
22
+import apis from '../../../services/apis';
23
+import router from 'umi/router';
24
+import AuthButton from '@/components/AuthButton';
25
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
26
+import Prompt from 'umi/prompt';
27
+
28
+const { RangePicker } = DatePicker;
29
+const { Option } = Select;
30
+
31
+const formItemLayout = {
32
+  labelCol: { span: 10 },
33
+  wrapperCol: { span: 14 },
34
+};
35
+
36
+let daterange = [];
37
+let tableTitle = ['类型'];
38
+let queryDate = '';
39
+
40
+let columns = [
41
+  {
42
+    title: '分享者姓名',
43
+    dataIndex: 'sharePersonName',
44
+    key: 'sharePersonName',
45
+  },
46
+  {
47
+    title: '分享者类型',
48
+    dataIndex: 'shareType',
49
+    key: 'shareType',
50
+    render: (text, records) => {
51
+      if (records.sharePersonType === 'drift') {
52
+        return '游客';
53
+      }
54
+      if (records.sharePersonType === 'customer') {
55
+        return '普通客户';
56
+      }
57
+      if (records.sharePersonType === 'Realty Consultant') {
58
+        return '置业顾问';
59
+      }
60
+      if (records.sharePersonType === 'channel agent') {
61
+        return '专业经纪人';
62
+      }
63
+    },
64
+  },
65
+  {
66
+    title: '分享时间',
67
+    dataIndex: 'shareTime',
68
+    key: 'shareTime',
69
+    render: (x, row) => (
70
+      <>
71
+        <span>{`${moment(row.shareTime).format('YYYY-MM-DD HH:mm:ss')}`}</span>
72
+      </>
73
+    ),
74
+  },
75
+  {
76
+    title: '分享者电话',
77
+    dataIndex: 'sharePersonPhone',
78
+    key: 'sharePersonPhone',
79
+  },
80
+  // {
81
+  //   title: '访问人数',
82
+  //   dataIndex: 'visitPersonNum',
83
+  //   key: 'visitPersonNum',
84
+  // },
85
+];
86
+
87
+class SharePersonNum extends React.Component {
88
+  constructor(props) {
89
+    super(props);
90
+    console.log(props);
91
+    queryDate = props.location.query.queryDate;
92
+    let startDate;
93
+    let endDate;
94
+    if (props.location.query.queryDate) {
95
+      startDate =
96
+        moment(props.location.query.queryDate)
97
+          .hours(0)
98
+          .minutes(0)
99
+          .seconds(0)
100
+          .milliseconds(0)
101
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
102
+      endDate =
103
+        moment(props.location.query.queryDate)
104
+          .hours(23)
105
+          .minutes(59)
106
+          .seconds(59)
107
+          .milliseconds(999)
108
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
109
+    } else {
110
+      startDate =
111
+        moment(props.location.query.startDate)
112
+          .hours(0)
113
+          .minutes(0)
114
+          .seconds(0)
115
+          .milliseconds(0)
116
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
117
+      endDate =
118
+        moment(props.location.query.endDate)
119
+          .hours(23)
120
+          .minutes(59)
121
+          .seconds(59)
122
+          .milliseconds(999)
123
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
124
+    }
125
+    this.state = {
126
+      formData: {
127
+        sharePhone: '',
128
+        sharePersonType: '',
129
+        pageNum: '',
130
+        pageSize: '',
131
+        shareName: '',
132
+        sort: null,
133
+        colKey: null,
134
+        startDate: startDate,
135
+        endDate: endDate,
136
+        activityId: props.location.query.activityId,
137
+        activityType: props.location.query.activityType,
138
+        personId: props.location.query.personId,
139
+        buildingId: props.location.query.buildingId,
140
+      },
141
+      personData: [],
142
+      dataSoures: [],
143
+      tableData: [],
144
+      userType: 'all',
145
+      activityName: props.location.query.activityName,
146
+    };
147
+  }
148
+
149
+  componentDidMount() {
150
+    this.getTableList();
151
+  }
152
+
153
+  getTableList() {
154
+    const { formData } = this.state;
155
+    console.log(formData);
156
+    request({ ...apis.activityDataStatis.activityShareNum, params: formData })
157
+      .then(data => {
158
+        console.log(data);
159
+        this.setState({ tableData: data.records, total: data.total });
160
+      })
161
+      .catch();
162
+  }
163
+
164
+  handleSubmit = (e, props) => {
165
+    let startDate = null;
166
+    let endDate = null;
167
+    const sharePersonType = this.props.form.getFieldValue('sharePersonType');
168
+    const sharePersonPhone = this.props.form.getFieldValue('sharePersonPhone');
169
+    const sharePersonName = this.props.form.getFieldValue('sharePersonName');
170
+    const { formData } = this.state;
171
+    this.setState(
172
+      {
173
+        formData: {
174
+          ...formData,
175
+          sharePersonType: sharePersonType,
176
+          sharePersonPhone: sharePersonPhone,
177
+          sharePersonName: sharePersonName,
178
+          pageNum: 1,
179
+          pageSize: 999,
180
+        },
181
+      },
182
+      this.getTableList,
183
+    );
184
+  };
185
+
186
+  //重置搜索
187
+  handleReset = e => {
188
+    this.props.form.resetFields();
189
+    let startDate;
190
+    let endDate;
191
+    if (this.props.location.query.queryDate) {
192
+      startDate =
193
+        moment(this.props.location.query.queryDate)
194
+          .hours(0)
195
+          .minutes(0)
196
+          .seconds(0)
197
+          .milliseconds(0)
198
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
199
+      endDate =
200
+        moment(this.props.location.query.queryDate)
201
+          .hours(23)
202
+          .minutes(59)
203
+          .seconds(59)
204
+          .milliseconds(999)
205
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
206
+    } else {
207
+      startDate =
208
+        moment(this.props.location.query.startDate)
209
+          .hours(0)
210
+          .minutes(0)
211
+          .seconds(0)
212
+          .milliseconds(0)
213
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
214
+      endDate =
215
+        moment(this.props.location.query.endDate)
216
+          .hours(23)
217
+          .minutes(59)
218
+          .seconds(59)
219
+          .milliseconds(999)
220
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
221
+    }
222
+    this.setState(
223
+      {
224
+        formData: {
225
+          sharePhone: '',
226
+          sharePersonType: '',
227
+          pageNum: '',
228
+          pageSize: '',
229
+          shareName: '',
230
+          sort: null,
231
+          colKey: null,
232
+          startDate: startDate,
233
+          endDate: endDate,
234
+          activityId: this.props.location.query.activityId,
235
+          activityType: this.props.location.query.activityType,
236
+          personId: this.props.location.query.personId,
237
+          buildingId: this.props.location.query.buildingId,
238
+        },
239
+        personData: [],
240
+        dataSoures: [],
241
+        tableData: [],
242
+        userType: 'all',
243
+        activityName: this.props.location.query.activityName,
244
+      },
245
+      this.getTableList,
246
+    );
247
+  };
248
+
249
+  goback = () => {
250
+    router.go(-1);
251
+  };
252
+
253
+  exportActivityStats = () => {
254
+    const { formData } = this.state;
255
+    request({ ...apis.activityDataStatis.activityShareNumExport, params: formData })
256
+      .then(data => {
257
+        if (!data) {
258
+          return;
259
+        }
260
+        const url = window.URL.createObjectURL(new Blob([data]));
261
+        const link = document.createElement('a');
262
+        link.style.display = 'none';
263
+        link.href = url;
264
+        link.setAttribute('download', '分享统计.xlsx');
265
+        document.body.append(link);
266
+        link.click();
267
+      })
268
+      .catch();
269
+  };
270
+
271
+  //排序
272
+  handleTableChange = (pagination, filters, sorter) => {
273
+    console.log(pagination, filters, sorter);
274
+    const { formData } = this.state;
275
+    this.setState(
276
+      {
277
+        formData: {
278
+          ...formData,
279
+          sharePersonType: formData.sharePersonType,
280
+          sharePhone: formData.sharePhone,
281
+          shareName: formData.shareName,
282
+          pageNum: pagination.current,
283
+          pageSize: pagination.pageSize,
284
+          sort: sorter.order,
285
+          colKey: sorter.columnKey,
286
+        },
287
+      },
288
+      this.getTableList,
289
+    );
290
+  };
291
+
292
+  render() {
293
+    const { getFieldDecorator } = this.props.form;
294
+
295
+    return (
296
+      <Card>
297
+        <div align="right" style={{ marginBottom: '16px' }}>
298
+          <Button onClick={this.goback}>返回</Button>
299
+        </div>
300
+        {this.state.activityName && (
301
+          <div>
302
+            <span style={{ marginLeft: '20px' }}>分享内容:{this.state.activityName}</span>
303
+          </div>
304
+        )}
305
+        <Form
306
+          layout="inline"
307
+          onSubmit={e => this.handleSubmit(e, this.props)}
308
+          style={{ display: 'flex', alignItems: 'center' }}
309
+        >
310
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
311
+            {getFieldDecorator('sharePersonType')(
312
+              <Select placeholder="分享者类型" style={{ width: 150, marginLeft: '20px' }}>
313
+                <Option value="drift">游客</Option>
314
+                <Option value="customer">普通客户</Option>
315
+                <Option value="Realty Consultant">置业顾问</Option>
316
+                <Option value="channel agent">专业经纪人</Option>
317
+              </Select>,
318
+            )}
319
+          </Form.Item>
320
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
321
+            {getFieldDecorator('sharePersonPhone')(<Input placeholder="分享者电话" />)}
322
+          </Form.Item>
323
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
324
+            {getFieldDecorator('sharePersonName')(<Input placeholder="分享者姓名" />)}
325
+          </Form.Item>
326
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
327
+            <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
328
+              搜索
329
+            </Button>
330
+            <Button onClick={e => this.handleReset()} style={{ marginLeft: '30px' }}>
331
+              重置
332
+            </Button>
333
+          </Form.Item>
334
+          {/* <AuthButton name="admin.statistical.activity.export" noRight={null}>
335
+            <Button
336
+              type="primary"
337
+              style={{ position: 'absolute', right: '27px', zIndex: 1 }}
338
+              onClick={this.exportActivityStats}
339
+            >
340
+              导出
341
+            </Button>
342
+          </AuthButton> */}
343
+        </Form>
344
+        <div>
345
+          <Table
346
+            style={{ marginTop: '20px' }}
347
+            dataSource={this.state.tableData}
348
+            columns={columns}
349
+            pagination={{ total: this.state.total }}
350
+            onChange={this.handleTableChange}
351
+            scroll={{ y: 500 }}
352
+          ></Table>
353
+        </div>
354
+      </Card>
355
+    );
356
+  }
357
+}
358
+const WrappedTypeForm = Form.create()(SharePersonNum);
359
+export default WrappedTypeForm;

+ 344
- 0
src/pages/statistics/activity/sharePersonNum.jsx Целия файл

@@ -0,0 +1,344 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions } from 'antd';
3
+import moment from 'moment';
4
+import request from '@/utils/request';
5
+import apis from '@/services/apis';
6
+import router from 'umi/router';
7
+import AuthButton from '@/components/AuthButton';
8
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
9
+import Navigate from '@/components/Navigate';
10
+
11
+const { RangePicker } = DatePicker;
12
+const { Option } = Select
13
+
14
+const formItemLayout = {
15
+  labelCol: { span: 10 },
16
+  wrapperCol: { span: 14 },
17
+};
18
+
19
+let daterange = []
20
+let tableTitle = ['类型']
21
+
22
+let staticStartDate = ''
23
+let staticEndDate = ''
24
+let queryDate = ''
25
+let activityName = ''
26
+let activityId = ''
27
+let activityType = ''
28
+
29
+const toShareNum = rowData => () => {
30
+  if (rowData) {
31
+    router.push({
32
+      pathname: '/statistics/activity/shareNum',
33
+      query: {
34
+        queryDate: queryDate,
35
+        personId: rowData.personId,
36
+        startDate: staticStartDate,
37
+        endDate: staticEndDate,
38
+        activityName: activityName,
39
+        activityId: activityId,
40
+        activityType: activityType
41
+      },
42
+    });
43
+    return
44
+  }
45
+}
46
+
47
+const toVisitPersonNum = rowData => () => {
48
+  if (rowData) {
49
+    router.push({
50
+      pathname: '/statistics/activity/visitPersonNum',
51
+      query: {
52
+        queryDate: queryDate,
53
+        personId: rowData.personId,
54
+        startDate: staticStartDate,
55
+        endDate: staticEndDate,
56
+        activityName: activityName,
57
+        activityId: activityId,
58
+        activityType: activityType
59
+      },
60
+    });
61
+    return
62
+  }
63
+}
64
+
65
+const toVisitNum = rowData => () => {
66
+  if (rowData) {
67
+    router.push({
68
+      pathname: '/statistics/activity/visitNum',
69
+      query: {
70
+        queryDate: queryDate,
71
+        personId: rowData.personId,
72
+        startDate: staticStartDate,
73
+        endDate: staticEndDate,
74
+        activityName: activityName,
75
+        activityId: activityId,
76
+        activityType: activityType
77
+      },
78
+    });
79
+    return
80
+  }
81
+}
82
+
83
+let columns = [
84
+  {
85
+    title: '分享者姓名',
86
+    dataIndex: 'sharePersonName',
87
+    key: 'sharePersonName',
88
+  },
89
+  {
90
+    title: '分享者类型',
91
+    dataIndex: 'sharePersonType',
92
+    key: 'sharePersonType',
93
+    render: (text, records) => {
94
+      if (records.sharePersonType === 'drift') { return '游客' }
95
+      if (records.sharePersonType === 'customer') { return '普通客户' }
96
+      if (records.sharePersonType === 'Realty Consultant') { return '置业顾问' }
97
+      if (records.sharePersonType === 'channel agent') { return '经纪人' }
98
+    },
99
+  },
100
+  {
101
+    title: '分享者电话',
102
+    dataIndex: 'sharePersonPhone',
103
+    key: 'sharePersonPhone',
104
+  },
105
+  {
106
+    title: '分享次数',
107
+    dataIndex: 'shareNum',
108
+    key: 'shareNum',
109
+    sorter: true,
110
+    render: (text, record) => (
111
+      <Navigate onClick={toShareNum(record)}>{record.shareNum}</Navigate>
112
+      // <a style={{ color: '#66B3FF' }} onClick={toShareNum(record)}><span>{record.shareNum}</span></a>
113
+    ),
114
+  },
115
+  {
116
+    title: '访问人数',
117
+    dataIndex: 'visitPersonNum',
118
+    key: 'visitPersonNum',
119
+    sorter: true,
120
+    render: (text, record) => (
121
+      <Navigate onClick={toVisitPersonNum(record)}>{record.visitPersonNum}</Navigate>
122
+      // <a style={{ color: '#66B3FF' }} onClick={toVisitPersonNum(record)}><span>{record.visitPersonNum}</span></a>
123
+    ),
124
+  },
125
+  {
126
+    title: '访问次数',
127
+    dataIndex: 'visitNum',
128
+    key: 'visitNum',
129
+    sorter: true,
130
+    render: (text, record) => (
131
+      <Navigate onClick={toVisitNum(record)}>{record.visitNum}</Navigate>
132
+      // <a style={{ color: '#66B3FF' }} onClick={toVisitNum(record)}><span>{record.visitNum}</span></a>
133
+    ),
134
+  },
135
+]
136
+
137
+class SharePersonNum extends React.Component {
138
+
139
+  constructor(props) {
140
+    super(props)
141
+    let startDate;
142
+    let endDate;
143
+    queryDate = props.location.query.queryDate
144
+    activityName = props.location.query.activityName
145
+    staticStartDate = props.location.query.startDate;
146
+    staticEndDate = props.location.query.endDate;
147
+    activityId = props.location.query.activityId;
148
+    activityType = props.location.query.activityType;
149
+
150
+    if (props.location.query.queryDate) {
151
+      console.log(queryDate, "props.location.query.queryDateprops.location.query.queryDate")
152
+      startDate = moment(props.location.query.queryDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
153
+      endDate = moment(props.location.query.queryDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
154
+      console.log(startDate, endDate, "endDateendDateendDateendDateendDateendDate")
155
+    } else {
156
+      startDate = moment(props.location.query.startDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
157
+      endDate = moment(props.location.query.endDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
158
+    }
159
+
160
+    console.log(startDate)
161
+    this.state = {
162
+      formData: {
163
+        sharePhone: '',
164
+        sharePersonType: '',
165
+        pageNum: '',
166
+        pageSize: '',
167
+        shareName: '',
168
+        sort: null,
169
+        colKey: null,
170
+        startDate: startDate,
171
+        endDate: endDate,
172
+        activityId: props.location.query.activityId,
173
+        activityType: props.location.query.activityType,
174
+        buildingId: props.location.query.buildingId,
175
+      },
176
+      personData: [],
177
+      dataSoures: [],
178
+      tableData: [],
179
+      userType: 'all',
180
+      activityName: props.location.query.activityName
181
+    }
182
+  }
183
+
184
+  componentDidMount() {
185
+    this.getTableList()
186
+  }
187
+
188
+  getTableList() {
189
+    const { formData } = this.state
190
+    request({ ...apis.activityDataStatis.activitySharePersonNum, params: formData }).then(data => {
191
+      console.log(data)
192
+      this.setState({ tableData: data.records, total: data.total })
193
+    }).catch()
194
+  }
195
+
196
+  handleSubmit = (e, props) => {
197
+    let startDate = null
198
+    let endDate = null
199
+    const sharePersonType = this.props.form.getFieldValue("sharePersonType");
200
+    const sharePersonPhone = this.props.form.getFieldValue("sharePersonPhone");
201
+    const sharePersonName = this.props.form.getFieldValue("sharePersonName");
202
+    const { formData } = this.state
203
+    this.setState({
204
+      formData: {
205
+        ...formData,
206
+        sharePersonType: sharePersonType,
207
+        sharePersonPhone: sharePersonPhone,
208
+        sharePersonName: sharePersonName,
209
+        pageNum: 1,
210
+        pageSize: 999
211
+      }
212
+    }, this.getTableList)
213
+  }
214
+
215
+  //重置搜索
216
+  handleReset = e => {
217
+    this.props.form.resetFields()
218
+    let startDate;
219
+    let endDate;
220
+    queryDate = this.props.location.query.queryDate
221
+    activityName = this.props.location.query.activityName
222
+    staticStartDate = this.props.location.query.startDate;
223
+    staticEndDate = this.props.location.query.endDate;
224
+    activityId = this.props.location.query.activityId;
225
+    activityType = this.props.location.query.activityType;
226
+
227
+    if (this.props.location.query.queryDate) {
228
+      startDate = moment(this.props.location.query.queryDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
229
+      endDate = moment(this.props.location.query.queryDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
230
+    } else {
231
+      startDate = moment(this.props.location.query.startDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
232
+      endDate = moment(this.props.location.query.endDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
233
+    }
234
+    this.setState({
235
+      formData: {
236
+        sharePhone: '',
237
+        sharePersonType: '',
238
+        pageNum: '',
239
+        pageSize: '',
240
+        shareName: '',
241
+        sort: null,
242
+        colKey: null,
243
+        startDate: startDate,
244
+        endDate: endDate,
245
+        activityId: this.props.location.query.activityId,
246
+        activityType: this.props.location.query.activityType,
247
+        buildingId: this.props.location.query.buildingId,
248
+      },
249
+      personData: [],
250
+      dataSoures: [],
251
+      tableData: [],
252
+      userType: 'all',
253
+      activityName: this.props.location.query.activityName
254
+    }, this.getTableList)
255
+  }
256
+
257
+  goback = () => {
258
+    router.go(-1);
259
+  }
260
+
261
+  exportActivityStats = () => {
262
+    const { formData } = this.state
263
+    request({ ...apis.activityDataStatis.activitySharePersonNumExport, params: formData }).then(data => {
264
+      if (!data) {
265
+        return
266
+      }
267
+      const url = window.URL.createObjectURL(new Blob([data]))
268
+      const link = document.createElement('a')
269
+      link.style.display = 'none'
270
+      link.href = url
271
+      link.setAttribute('download', '分享统计.xlsx')
272
+      document.body.append(link)
273
+      link.click()
274
+    }).catch()
275
+  }
276
+
277
+  //排序
278
+  handleTableChange = (pagination, filters, sorter) => {
279
+    console.log(pagination, filters, sorter)
280
+    const { formData } = this.state
281
+    this.setState({
282
+      formData: {
283
+        ...formData,
284
+        sharePersonType: formData.sharePersonType,
285
+        sharePhone: formData.sharePhone,
286
+        shareName: formData.shareName,
287
+        pageNum: pagination.current,
288
+        pageSize: pagination.pageSize,
289
+        sort: sorter.order,
290
+        colKey: sorter.columnKey
291
+      }
292
+    }, this.getTableList)
293
+  };
294
+
295
+  render() {
296
+    const { radioVal } = this.state
297
+    const { getFieldDecorator } = this.props.form;
298
+
299
+    return (
300
+      <Card>
301
+        <div align="right" style={{ marginBottom: '16px' }}><Button onClick={this.goback}>返回</Button></div>
302
+        {this.state.activityName&&<div>
303
+          <span style={{ marginLeft: '20px' }}>分享内容:{this.state.activityName}</span>
304
+        </div>}
305
+        <Form layout="inline" onSubmit={e => this.handleSubmit(e, this.props)}>
306
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
307
+            {getFieldDecorator('sharePersonType')(
308
+              <Select placeholder="分享者类型" style={{ width: 150, marginLeft: '20px' }}>
309
+                <Option value="drift">游客</Option>
310
+                <Option value="customer">普通客户</Option>
311
+                <Option value="Realty Consultant">置业顾问</Option>
312
+                <Option value="channel agent">经纪人</Option>
313
+              </Select>
314
+            )}
315
+          </Form.Item>
316
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
317
+            {getFieldDecorator('sharePersonPhone')(<Input placeholder="分享者电话" />)}
318
+          </Form.Item>
319
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
320
+            {getFieldDecorator('sharePersonName')(<Input placeholder="分享者姓名" />)}
321
+          </Form.Item>
322
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
323
+            <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
324
+              搜索
325
+            </Button>
326
+            <Button onClick={e => this.handleReset()} style={{ marginLeft: '30px' }}>重置</Button>
327
+          </Form.Item>
328
+          {/* <AuthButton name="admin.statistics.activity.export" noRight={null}>
329
+            <Button type="primary" style={{ float: 'right', zIndex: 1, marginTop: '24px' }} onClick={this.exportActivityStats}>
330
+              导出
331
+            </Button>
332
+          </AuthButton> */}
333
+        </Form>
334
+        <div>
335
+
336
+          <Table style={{ marginTop: '20px' }} dataSource={this.state.tableData} columns={columns} pagination={{ total: this.state.total }} onChange={this.handleTableChange} scroll={{ y: 500 }}></Table>
337
+        </div>
338
+      </Card>
339
+    )
340
+
341
+  }
342
+}
343
+const WrappedTypeForm = Form.create()(SharePersonNum);
344
+export default WrappedTypeForm

+ 363
- 0
src/pages/statistics/activity/visitNum.jsx Целия файл

@@ -0,0 +1,363 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import {
3
+  Form,
4
+  Icon,
5
+  Input,
6
+  Button,
7
+  DatePicker,
8
+  Select,
9
+  Card,
10
+  Row,
11
+  Col,
12
+  Pagination,
13
+  Alert,
14
+  Table,
15
+  Avatar,
16
+  Radio,
17
+  Modal,
18
+  Descriptions,
19
+} from 'antd';
20
+import moment from 'moment';
21
+import request from '../../../utils/request';
22
+import apis from '../../../services/apis';
23
+import router from 'umi/router';
24
+import AuthButton from '@/components/AuthButton';
25
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
26
+import WxDictSelect from '@/components/SelectButton/WxDictSelect';
27
+import Prompt from 'umi/prompt';
28
+
29
+const { RangePicker } = DatePicker;
30
+const { Option } = Select;
31
+
32
+const formItemLayout = {
33
+  labelCol: { span: 10 },
34
+  wrapperCol: { span: 14 },
35
+};
36
+
37
+let daterange = [];
38
+let tableTitle = ['类型'];
39
+let queryDate = '';
40
+
41
+let columns = [
42
+  {
43
+    title: '姓名',
44
+    dataIndex: 'nickName',
45
+    key: 'nickName',
46
+  },
47
+  {
48
+    title: '电话',
49
+    dataIndex: 'phone',
50
+    key: 'phone',
51
+  },
52
+  {
53
+    title: '性别',
54
+    dataIndex: 'gender',
55
+    key: 'gender',
56
+  },
57
+  {
58
+    title: '归属地',
59
+    dataIndex: 'province',
60
+    key: 'province',
61
+  },
62
+  {
63
+    title: '来源渠道',
64
+    dataIndex: 'personFrom',
65
+    key: 'personFrom',
66
+  },
67
+  {
68
+    title: '置业顾问',
69
+    dataIndex: 'realtyConsultant',
70
+    key: 'realtyConsultant',
71
+  },
72
+  {
73
+    title: '置业顾问电话',
74
+    dataIndex: 'realtyConsultantPhone',
75
+    key: 'realtyConsultantPhone',
76
+  },
77
+  {
78
+    title: '分享者',
79
+    dataIndex: 'sharePersonName',
80
+    key: 'sharePersonName',
81
+  },
82
+  {
83
+    title: '分享者电话',
84
+    dataIndex: 'sharePersonPhone',
85
+    key: 'sharePersonPhone',
86
+  },
87
+  {
88
+    title: '访问时间',
89
+    dataIndex: 'visitDate',
90
+    key: 'visitDate',
91
+    render: (x, row) => (
92
+      <>
93
+        <span>{`${moment(row.visitDate).format('YYYY-MM-DD HH:mm:ss')}`}</span>
94
+      </>
95
+    ),
96
+  },
97
+];
98
+
99
+class SharePersonNum extends React.Component {
100
+  constructor(props) {
101
+    super(props);
102
+    queryDate = props.location.query.queryDate;
103
+
104
+    let startDate;
105
+    let endDate;
106
+    if (props.location.query.queryDate) {
107
+      startDate =
108
+        moment(props.location.query.queryDate)
109
+          .hours(0)
110
+          .minutes(0)
111
+          .seconds(0)
112
+          .milliseconds(0)
113
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
114
+      endDate =
115
+        moment(props.location.query.queryDate)
116
+          .hours(23)
117
+          .minutes(59)
118
+          .seconds(59)
119
+          .milliseconds(999)
120
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
121
+    } else {
122
+      startDate =
123
+        moment(props.location.query.startDate)
124
+          .hours(0)
125
+          .minutes(0)
126
+          .seconds(0)
127
+          .milliseconds(0)
128
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
129
+      endDate =
130
+        moment(props.location.query.endDate)
131
+          .hours(23)
132
+          .minutes(59)
133
+          .seconds(59)
134
+          .milliseconds(999)
135
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
136
+    }
137
+    console.log(startDate);
138
+    this.state = {
139
+      formData: {
140
+        personFrom: '',
141
+        pageNum: '',
142
+        pageSize: '',
143
+        startDate: startDate,
144
+        endDate: endDate,
145
+        province: '',
146
+        realtyConsultant: '',
147
+        realtyConsultantPhone: '',
148
+        activityId: props.location.query.activityId,
149
+        activityType: props.location.query.activityType,
150
+        personId: props.location.query.personId,
151
+        buildingId: props.location.query.buildingId,
152
+      },
153
+      personData: [],
154
+      dataSoures: [],
155
+      tableData: [],
156
+      userType: 'all',
157
+      activityName: props.location.query.activityName,
158
+    };
159
+  }
160
+
161
+  componentDidMount() {
162
+    this.getTableList();
163
+  }
164
+
165
+  getTableList() {
166
+    const { formData } = this.state;
167
+    console.log(formData);
168
+    request({ ...apis.activityDataStatis.activityVisitNum, params: formData })
169
+      .then(data => {
170
+        console.log(data);
171
+        this.setState({ tableData: data.records, total: data.total });
172
+      })
173
+      .catch();
174
+  }
175
+
176
+  handleSubmit = (e, props) => {
177
+    let startDate = null;
178
+    let endDate = null;
179
+    const province = this.props.form.getFieldValue('province');
180
+    const personFrom = this.props.form.getFieldValue('personFrom');
181
+    const realtyConsultant = this.props.form.getFieldValue('realtyConsultant');
182
+    const realtyConsultantPhone = this.props.form.getFieldValue('realtyConsultantPhone');
183
+
184
+    const { formData } = this.state;
185
+    this.setState(
186
+      {
187
+        formData: {
188
+          ...formData,
189
+          personFrom: personFrom,
190
+          province: province,
191
+          realtyConsultant: realtyConsultant,
192
+          realtyConsultantPhone: realtyConsultantPhone,
193
+          pageNum: 1,
194
+          pageSize: 999,
195
+        },
196
+      },
197
+      this.getTableList,
198
+    );
199
+  };
200
+
201
+  //重置搜索
202
+  handleReset = e => {
203
+    this.props.form.resetFields();
204
+    let startDate;
205
+    let endDate;
206
+    if (this.props.location.query.queryDate) {
207
+      startDate =
208
+        moment(this.props.location.query.queryDate)
209
+          .hours(0)
210
+          .minutes(0)
211
+          .seconds(0)
212
+          .milliseconds(0)
213
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
214
+      endDate =
215
+        moment(this.props.location.query.queryDate)
216
+          .hours(23)
217
+          .minutes(59)
218
+          .seconds(59)
219
+          .milliseconds(999)
220
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
221
+    } else {
222
+      startDate =
223
+        moment(this.props.location.query.startDate)
224
+          .hours(0)
225
+          .minutes(0)
226
+          .seconds(0)
227
+          .milliseconds(0)
228
+          .format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
229
+      endDate =
230
+        moment(this.props.location.query.endDate)
231
+          .hours(23)
232
+          .minutes(59)
233
+          .seconds(59)
234
+          .milliseconds(999)
235
+          .format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
236
+    }
237
+    console.log(startDate);
238
+    this.setState(
239
+      {
240
+        formData: {
241
+          personFrom: '',
242
+          pageNum: '',
243
+          pageSize: '',
244
+          startDate: startDate,
245
+          endDate: endDate,
246
+          province: '',
247
+          realtyConsultant: '',
248
+          realtyConsultantPhone: '',
249
+          activityId: this.props.location.query.activityId,
250
+          activityType: this.props.location.query.activityType,
251
+          personId: this.props.location.query.personId,
252
+          buildingId: this.props.location.query.buildingId,
253
+        },
254
+        personData: [],
255
+        dataSoures: [],
256
+        tableData: [],
257
+        userType: 'all',
258
+        activityName: this.props.location.query.activityName,
259
+      },
260
+      this.getTableList,
261
+    );
262
+  };
263
+
264
+  goback = () => {
265
+    router.go(-1);
266
+  };
267
+
268
+  exportActivityStats = () => {
269
+    const { formData } = this.state;
270
+    request({ ...apis.activityDataStatis.activityVisitNumExport, params: formData })
271
+      .then(data => {
272
+        if (!data) {
273
+          return;
274
+        }
275
+        const url = window.URL.createObjectURL(new Blob([data]));
276
+        const link = document.createElement('a');
277
+        link.style.display = 'none';
278
+        link.href = url;
279
+        link.setAttribute('download', '访问统计.xlsx');
280
+        document.body.append(link);
281
+        link.click();
282
+      })
283
+      .catch();
284
+  };
285
+
286
+  //排序
287
+  handleTableChange = (pagination, filters, sorter) => {
288
+    console.log(pagination, filters, sorter);
289
+    const { formData } = this.state;
290
+    this.setState(
291
+      {
292
+        formData: {
293
+          ...formData,
294
+          personFrom: formData.personFrom,
295
+          pageNum: pagination.current,
296
+          pageSize: pagination.pageSize,
297
+        },
298
+      },
299
+      this.getTableList,
300
+    );
301
+  };
302
+
303
+  render() {
304
+    const { radioVal } = this.state;
305
+    const { getFieldDecorator } = this.props.form;
306
+
307
+    return (
308
+      <Card>
309
+        <div align="right" style={{ marginBottom: '16px' }}>
310
+          <Button onClick={this.goback}>返回</Button>
311
+        </div>
312
+        {this.state.activityName && (
313
+          <div>
314
+            <span style={{ marginLeft: '20px' }}>分享内容:{this.state.activityName}</span>
315
+          </div>
316
+        )}
317
+        <Form layout="inline" onSubmit={e => this.handleSubmit(e, this.props)}>
318
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
319
+            {getFieldDecorator('personFrom')(<WxDictSelect />)}
320
+          </Form.Item>
321
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
322
+            {getFieldDecorator('province')(<Input placeholder="请输入归属地" />)}
323
+          </Form.Item>
324
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
325
+            {getFieldDecorator('realtyConsultant')(<Input placeholder="置业顾问" />)}
326
+          </Form.Item>
327
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
328
+            {getFieldDecorator('realtyConsultantPhone')(<Input placeholder="置业顾问电话" />)}
329
+          </Form.Item>
330
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
331
+            <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
332
+              搜索
333
+            </Button>
334
+            <Button onClick={e => this.handleReset()} style={{ marginLeft: '30px' }}>
335
+              重置
336
+            </Button>
337
+          </Form.Item>
338
+          {/* <AuthButton name="admin.statistics.activity.export" noRight={null}>
339
+            <Button
340
+              type="primary"
341
+              style={{ float: 'right', margin: '20px 0', zIndex: 1 }}
342
+              onClick={this.exportActivityStats}
343
+            >
344
+              导出
345
+            </Button>
346
+          </AuthButton> */}
347
+        </Form>
348
+        <div>
349
+          <Table
350
+            style={{ marginTop: '20px' }}
351
+            dataSource={this.state.tableData}
352
+            columns={columns}
353
+            pagination={{ total: this.state.total }}
354
+            onChange={this.handleTableChange}
355
+            scroll={{ y: 500 }}
356
+          ></Table>
357
+        </div>
358
+      </Card>
359
+    );
360
+  }
361
+}
362
+const WrappedTypeForm = Form.create()(SharePersonNum);
363
+export default WrappedTypeForm;

+ 264
- 0
src/pages/statistics/activity/visitPersonNum.jsx Целия файл

@@ -0,0 +1,264 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../utils/request';
5
+import apis from '../../../services/apis';
6
+import router from 'umi/router';
7
+import AuthButton from '@/components/AuthButton';
8
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
9
+import WxDictSelect from '@/components/SelectButton/WxDictSelect';
10
+import Prompt from 'umi/prompt';
11
+
12
+const { RangePicker } = DatePicker;
13
+const { Option } = Select
14
+
15
+const formItemLayout = {
16
+  labelCol: { span: 10 },
17
+  wrapperCol: { span: 14 },
18
+};
19
+
20
+let daterange = []
21
+let tableTitle = ['类型']
22
+let queryDate = ''
23
+
24
+let columns = [
25
+  {
26
+    title: '姓名',
27
+    dataIndex: 'nickName',
28
+    key: 'nickName',
29
+  },
30
+  {
31
+    title: '电话',
32
+    dataIndex: 'phone',
33
+    key: 'phone',
34
+  },
35
+  {
36
+    title: '性别',
37
+    dataIndex: 'gender',
38
+    key: 'gender',
39
+  },
40
+  {
41
+    title: '归属地',
42
+    dataIndex: 'province',
43
+    key: 'province',
44
+  },
45
+  {
46
+    title: '来源渠道',
47
+    dataIndex: 'personFrom',
48
+    key: 'personFrom',
49
+  },
50
+  {
51
+    title: '置业顾问',
52
+    dataIndex: 'realtyConsultant',
53
+    key: 'realtyConsultant',
54
+  },
55
+  {
56
+    title: '置业顾问电话',
57
+    dataIndex: 'realtyConsultantPhone',
58
+    key: 'realtyConsultantPhone',
59
+  },
60
+  {
61
+    title: '推广人',
62
+    dataIndex: 'sharePersonName',
63
+    key: 'sharePersonName',
64
+  },
65
+  {
66
+    title: '访问次数',
67
+    dataIndex: 'visitNum',
68
+    key: 'visitNum',
69
+  },
70
+]
71
+
72
+class SharePersonNum extends React.Component {
73
+
74
+  constructor(props) {
75
+    super(props)
76
+    queryDate = props.location.query.queryDate
77
+
78
+    let startDate;
79
+    let endDate;
80
+
81
+    if (props.location.query.queryDate) {
82
+      startDate = moment(props.location.query.queryDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
83
+      endDate = moment(props.location.query.queryDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
84
+    } else {
85
+      startDate = moment(props.location.query.startDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
86
+      endDate = moment(props.location.query.endDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
87
+    }
88
+    console.log(startDate)
89
+    this.state = {
90
+      formData: {
91
+        personFrom: '',
92
+        pageNum: '',
93
+        pageSize: '',
94
+        startDate: startDate,
95
+        endDate: endDate,
96
+        province: '',
97
+        realtyConsultant: '',
98
+        realtyConsultantPhone: '',
99
+        activityId: props.location.query.activityId,
100
+        activityType: props.location.query.activityType,
101
+        personId: props.location.query.personId,
102
+        buildingId: props.location.query.buildingId
103
+      },
104
+      personData: [],
105
+      dataSoures: [],
106
+      tableData: [],
107
+      userType: 'all',
108
+      activityName: props.location.query.activityName
109
+    }
110
+  }
111
+
112
+  componentDidMount() {
113
+    this.getTableList()
114
+  }
115
+
116
+  getTableList() {
117
+    const { formData } = this.state
118
+    console.log(formData)
119
+    request({ ...apis.activityDataStatis.activityVisitPersonNum, params: formData }).then(data => {
120
+      console.log(data)
121
+      this.setState({ tableData: data.records, total: data.total })
122
+    }).catch()
123
+  }
124
+
125
+  handleSubmit = (e, props) => {
126
+    let startDate = null
127
+    let endDate = null
128
+    const province = this.props.form.getFieldValue("province");
129
+    const personFrom = this.props.form.getFieldValue("personFrom");
130
+    const realtyConsultant = this.props.form.getFieldValue("realtyConsultant");
131
+    const realtyConsultantPhone = this.props.form.getFieldValue("realtyConsultantPhone");
132
+
133
+    const { formData } = this.state
134
+    this.setState({
135
+      formData: {
136
+        ...formData,
137
+        personFrom: personFrom,
138
+        province: province,
139
+        realtyConsultant: realtyConsultant,
140
+        realtyConsultantPhone: realtyConsultantPhone,
141
+        pageNum: 1,
142
+        pageSize: 999
143
+      }
144
+    }, this.getTableList)
145
+  }
146
+
147
+  //重置搜索
148
+  handleReset = e => {
149
+    this.props.form.resetFields()
150
+    let startDate;
151
+    let endDate;
152
+
153
+    if (this.props.location.query.queryDate) {
154
+      startDate = moment(this.props.location.query.queryDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
155
+      endDate = moment(this.props.location.query.queryDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
156
+    } else {
157
+      startDate = moment(this.props.location.query.startDate).hours(0).minutes(0).seconds(0).milliseconds(0).format('YYYY-MM-DDTHH:mm:ss') + '.000Z';
158
+      endDate = moment(this.props.location.query.endDate).hours(23).minutes(59).seconds(59).milliseconds(999).format('YYYY-MM-DDTHH:mm:ss') + '.999Z';
159
+    }
160
+    this.setState({
161
+      formData: {
162
+        personFrom: '',
163
+        pageNum: '',
164
+        pageSize: '',
165
+        startDate: startDate,
166
+        endDate: endDate,
167
+        province: '',
168
+        realtyConsultant: '',
169
+        realtyConsultantPhone: '',
170
+        activityId: this.props.location.query.activityId,
171
+        activityType: this.props.location.query.activityType,
172
+        personId: this.props.location.query.personId,
173
+        buildingId: this.props.location.query.buildingId
174
+      },
175
+      personData: [],
176
+      dataSoures: [],
177
+      tableData: [],
178
+      userType: 'all',
179
+      activityName: this.props.location.query.activityName
180
+    }, this.getTableList)
181
+  }
182
+
183
+  goback = () => {
184
+    router.go(-1);
185
+  }
186
+
187
+  exportActivityStats = () => {
188
+    const { formData } = this.state
189
+    request({ ...apis.activityDataStatis.activityVisitPersonNumExport, params: formData }).then(data => {
190
+      if (!data) {
191
+        return
192
+      }
193
+      const url = window.URL.createObjectURL(new Blob([data]))
194
+      const link = document.createElement('a')
195
+      link.style.display = 'none'
196
+      link.href = url
197
+      link.setAttribute('download', '访问统计.xlsx')
198
+      document.body.append(link)
199
+      link.click()
200
+    }).catch()
201
+  }
202
+
203
+  //排序
204
+  handleTableChange = (pagination, filters, sorter) => {
205
+    console.log(pagination, filters, sorter)
206
+    const { formData } = this.state
207
+    this.setState({
208
+      formData: {
209
+        ...formData,
210
+        personFrom: formData.personFrom,
211
+        pageNum: pagination.current,
212
+        pageSize: pagination.pageSize
213
+      }
214
+    }, this.getTableList)
215
+  };
216
+
217
+  render() {
218
+    const { radioVal } = this.state
219
+    const { getFieldDecorator } = this.props.form;
220
+
221
+    return (
222
+      <Card>
223
+        <div align="right" style={{ marginBottom: '16px' }}><Button onClick={this.goback}>返回</Button></div>
224
+        {this.state.activityName&&<div>
225
+          <span style={{ marginLeft: '20px' }}>分享内容:{this.state.activityName}</span>
226
+        </div>}
227
+        <Form layout="inline" onSubmit={e => this.handleSubmit(e, this.props)}>
228
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
229
+            {getFieldDecorator('personFrom')(
230
+              <WxDictSelect />,
231
+            )}
232
+          </Form.Item>
233
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
234
+            {getFieldDecorator('province')(<Input placeholder="请输入归属地" />)}
235
+          </Form.Item>
236
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
237
+            {getFieldDecorator('realtyConsultant')(<Input placeholder="置业顾问" />)}
238
+          </Form.Item>
239
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
240
+            {getFieldDecorator('realtyConsultantPhone')(<Input placeholder="置业顾问电话" />)}
241
+          </Form.Item>
242
+          <Form.Item style={{ marginTop: '20px', marginBottom: '20px' }}>
243
+            <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
244
+              搜索
245
+            </Button>
246
+            <Button onClick={e => this.handleReset()} style={{ marginLeft: '30px' }}>重置</Button>
247
+          </Form.Item>
248
+          {/* <AuthButton name="admin.statistics.activity.export" noRight={null}>
249
+            <Button type="primary" style={{ float: 'right', margin: '20px 0', zIndex: 1 }} onClick={this.exportActivityStats}>
250
+              导出
251
+            </Button>
252
+          </AuthButton> */}
253
+        </Form>
254
+        <div>
255
+
256
+          <Table style={{ marginTop: '20px' }} dataSource={this.state.tableData} columns={columns} pagination={{ total: this.state.total }} onChange={this.handleTableChange} scroll={{ y: 500 }}></Table>
257
+        </div>
258
+      </Card>
259
+    )
260
+
261
+  }
262
+}
263
+const WrappedTypeForm = Form.create()(SharePersonNum);
264
+export default WrappedTypeForm

+ 72
- 0
src/pages/statistics/building/BuildingStatistic/component/StatsChart.jsx Целия файл

@@ -0,0 +1,72 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Table, Avatar, Radio, Modal, Descriptions } from 'antd';
3
+import moment from 'moment';
4
+import echarts from 'echarts/lib/echarts';
5
+import EChart from '@/components/EchartsTest/EChart';
6
+import router from 'umi/router';
7
+
8
+class StatsChart extends React.Component {
9
+
10
+  constructor(props) {
11
+    super(props)
12
+    this.state = {}
13
+  }
14
+
15
+  render() {
16
+    const { data = [] } = this.props
17
+    const options = {
18
+      title: {
19
+        text: this.props.title,
20
+        subtext: this.props.subtext,
21
+      },
22
+      xAxis: {
23
+        type: 'category',
24
+        axisLabel: { rotate: 45 },
25
+        // data: data.buildingNameList || []
26
+      },
27
+      grid: {
28
+        bottom: '30%'
29
+      },
30
+      tooltip: {},
31
+      yAxis: {
32
+        type: 'value'
33
+      },
34
+      dataset: {
35
+        // 用 dimensions 指定了维度的顺序。直角坐标系中,
36
+        // 默认把第一个维度映射到 X 轴上,第二个维度映射到 Y 轴上。
37
+        // 如果不指定 dimensions,也可以通过指定 series.encode
38
+        // 完成映射,参见后文。
39
+        dimensions: ['buildingName', 'num' ],
40
+        source: data
41
+    },
42
+      series: {
43
+        type: 'bar',
44
+        name: this.props.title,
45
+        barWidth: 50,
46
+        // data: data.numList || [],
47
+        itemStyle: {
48
+          normal: {
49
+            barBorderRadius: [50, 50, 0, 0],
50
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
51
+              offset: 0,
52
+              color: '#FFC6AA'
53
+            }, {
54
+              offset: 1,
55
+              color: '#FF7E48'
56
+            }]),
57
+            shadowColor: 'rgba(0, 0, 0, 0.4)',
58
+
59
+          }
60
+        }
61
+      }
62
+    }
63
+
64
+    return (
65
+      <>
66
+        <EChart options={options} style={{ width: '100%', height: '400px'}} />
67
+      </>
68
+    )
69
+  }
70
+}
71
+
72
+export default StatsChart

+ 110
- 0
src/pages/statistics/building/BuildingStatistic/component/StatsChartLine.jsx Целия файл

@@ -0,0 +1,110 @@
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, Card, Icon, message } from 'antd';
9
+
10
+const formatDate = (start, end) => {
11
+  const startDate = moment(start).format('YYYY-MM-DDT00:00:00.000') + 'Z';
12
+  const endDate = moment(end).format('YYYY-MM-DDT23:59:59.999') + 'Z';
13
+  return { startDate, endDate };
14
+};
15
+const UserSource = props => {
16
+    const {buildingId,buildingName,params} = props 
17
+  const [data, setData] = useState({  });
18
+  //柱图
19
+//   // 获取图表数据
20
+//  const getTimeBarDate = (startDate, endDate) => {
21
+//     request({ ...apis.stats.timeBarList, params: { startDate: moment(startDate).format('YYYY-MM-DDT00:00:00.000') + 'Z', endDate: moment(endDate).format('YYYY-MM-DDT23:59:59.999') + 'Z', buildingId: this.state.buildingId } }).then((data) => {
22
+//       this.setState({ ...this.state, barData: data })
23
+//     })
24
+//   }
25
+  useEffect(() => {
26
+    getData(params);
27
+  }, [params]);
28
+
29
+  function getData(params) {
30
+    request({
31
+        ...apis.stats.timeBarList,
32
+      params: {  ...params,buildingId },
33
+    }).then(data => {
34
+      setData(data);
35
+    });
36
+  }
37
+
38
+  const options = {
39
+    // title: {
40
+    //     text: this.props.title,
41
+    // },
42
+    tooltip: {
43
+        trigger: 'axis'
44
+    },
45
+    legend: {
46
+        data: ['公客数', '私客数', '新增客户数', '访问人数']
47
+    },
48
+    grid: {
49
+        left: '3%',
50
+        right: '4%',
51
+        bottom: '3%',
52
+        containLabel: true
53
+    },
54
+    toolbox: {
55
+        feature: {
56
+            saveAsImage: {}
57
+        }
58
+    },
59
+    xAxis: {
60
+        type: 'category',
61
+        boundaryGap: false,
62
+        axisLabel: {rotate: 45},
63
+        data: data.timeList || []
64
+    },
65
+    yAxis: {
66
+        type: 'value'
67
+    },
68
+    series: [
69
+        {
70
+            name: '公客数',
71
+            type: 'line',
72
+            data: data.gkList || []
73
+            
74
+        },
75
+        {
76
+            name: '私客数',
77
+            type: 'line',
78
+            data: data.skList || []
79
+        },
80
+        {
81
+            name: '新增客户数',
82
+            type: 'line',
83
+            data: data.khList || []
84
+        },
85
+        {
86
+            name: '访问人数',
87
+            type: 'line',
88
+            data: data.uvList || []
89
+        }
90
+    ]
91
+};
92
+
93
+
94
+
95
+
96
+  return (
97
+    <>
98
+      <Card
99
+        title={`趋势图:${buildingName}`}
100
+        headStyle={{ textAlign: 'left' }}
101
+
102
+      >
103
+
104
+        <EChart options={options}  />
105
+      </Card>
106
+    </>
107
+  );
108
+};
109
+
110
+export default UserSource;

+ 72
- 0
src/pages/statistics/building/BuildingStatistic/index.jsx Целия файл

@@ -0,0 +1,72 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Statistic, Icon, Button } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+import moment from 'moment';
5
+import request from '@/utils/request';
6
+import apis from '@/services/apis';
7
+import CitySelect from '@/components/SelectButton/CitySelect2';
8
+import TimeSelect from '../../compents/TimeSelect';
9
+import StatsChart from './component/StatsChart';
10
+
11
+const BuildingStatistic = props => {
12
+  const [cityId, setCityId] = useState('');
13
+  const [time, setTime] = useState();
14
+
15
+  const [data, setData] = useState({});
16
+  useEffect(() => {
17
+    if (time) {
18
+      getData({
19
+        cityId: cityId || undefined,
20
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
21
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
22
+      });
23
+    }
24
+  }, [cityId, time]);
25
+  const onTimeChange = e => {
26
+    console.log(e, 'onTimeChange');
27
+    setTime(e);
28
+    // getData({ startDate: e[0], endDate: e[1] });
29
+  };
30
+
31
+  const getData = params => {
32
+    request({
33
+      ...apis.stats.barList,
34
+      params: {
35
+        ...params,
36
+      },
37
+    }).then(data => {
38
+      setData(data);
39
+    });
40
+  };
41
+
42
+  return (
43
+    <Card
44
+      title={<CitySelect value={cityId} onChange={e => setCityId(e)} all />}
45
+      headStyle={{ textAlign: 'left' }}
46
+      extra={<TimeSelect onChange={onTimeChange}></TimeSelect>}
47
+    >
48
+      <div style={{ fontSize: '12px', color: '#ccc', marginBottom: '10px' }}>
49
+        最多显示6个项目,更多项目数据请在下方详细数据中搜索
50
+      </div>
51
+      <div>
52
+        <Row>
53
+          <Col span={12}>
54
+            <StatsChart title="项目公客排行" data={data.gkList} />
55
+          </Col>
56
+          <Col span={12}>
57
+            <StatsChart title="项目私客排行" data={data.skList} />
58
+          </Col>
59
+        </Row>
60
+        <Row>
61
+          <Col span={12}>
62
+            <StatsChart title="项目访问人数排行" subtext="项目详情访问情况" data={data.visitList} />
63
+          </Col>
64
+          <Col span={12}>
65
+            <StatsChart title="成交量排行" data={data.successList} />
66
+          </Col>
67
+        </Row>
68
+      </div>
69
+    </Card>
70
+  );
71
+};
72
+export default BuildingStatistic;

+ 100
- 0
src/pages/statistics/building/detail.jsx Целия файл

@@ -0,0 +1,100 @@
1
+import React, { Component, useState, useEffect, useRef } from 'react';
2
+import { Card, Row, Col, Statistic, Icon, Tabs, Form, Select, Button, Modal } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+import TimeSelect from '../compents/TimeSelect';
10
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
11
+import Navigate from '@/components/Navigate';
12
+import StatsChartLine from './BuildingStatistic/component/StatsChartLine';
13
+// import ActivityCount from '../compents/activityCount';
14
+// import NewUsers from '../compents/NewUsers';
15
+// import OverviewDeatil from '../compents/OverviewDeatil';
16
+
17
+// import Count from './components/Count';
18
+// import SourceRole from './components/SourceRole';
19
+// import UserSex from './components/UserSex';
20
+// import UserConversion from './components/UserConversion';
21
+// import BuildingStatistic from './BuildingStatistic';
22
+const { TabPane } = Tabs;
23
+const { Option } = Select;
24
+
25
+const activityOverView = props => {
26
+  const { buildingId, buildingName } = props.location.query;
27
+
28
+  const timeRef = useRef();
29
+
30
+  const [data, setData] = useState({});
31
+  const [serachData, setSearchData] = useState({
32
+    startDate:
33
+      moment()
34
+        .subtract(7, 'day')
35
+        .format('YYYY-MM-DDT00:00:00.000') + 'Z',
36
+    endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
37
+  });
38
+  const [timeValue, setTimeValue] = useState();
39
+
40
+  const [time, setTime] = useState();
41
+
42
+  //重置搜索
43
+  const handleReset = e => {
44
+    props.form.resetFields();
45
+    timeRef.current.reset();
46
+    setSearchData({
47
+      startDate:
48
+        moment()
49
+          .subtract(7, 'day')
50
+          .format('YYYY-MM-DDT00:00:00.000') + 'Z',
51
+      endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
52
+    });
53
+  };
54
+
55
+  const onTimeChange = e => {
56
+    setTime(e);
57
+  };
58
+  const handleSubmit = e => {
59
+    props.form.validateFieldsAndScroll((err, values) => {
60
+      setTimeValue();
61
+      setSearchData({
62
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
63
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
64
+      });
65
+    });
66
+  };
67
+
68
+  const { getFieldDecorator } = props.form;
69
+
70
+  return (
71
+    <div>
72
+      <Form layout="inline" onSubmit={handleSubmit}>
73
+        <Form.Item>
74
+          <TimeSelect onChange={onTimeChange} ref={timeRef}></TimeSelect>
75
+        </Form.Item>
76
+        <Form.Item>
77
+          <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
78
+            搜索
79
+          </Button>
80
+          <Button onClick={e => handleReset()} style={{ marginLeft: '30px' }}>
81
+            重置
82
+          </Button>
83
+        </Form.Item>
84
+      </Form>
85
+      <div style={{ marginTop: '20px' }}>
86
+        <StatsChartLine
87
+          params={serachData}
88
+          buildingId={buildingId}
89
+          buildingName={buildingName}
90
+        ></StatsChartLine>
91
+      </div>
92
+      <div style={{ marginTop: '20px' }}>
93
+        {/* <NewUsers params={serachData} dataZoom={false}></NewUsers> */}
94
+      </div>
95
+    </div>
96
+  );
97
+};
98
+
99
+const WrappedTypeForm = Form.create()(activityOverView);
100
+export default WrappedTypeForm;

+ 90
- 0
src/pages/statistics/building/detail/index.jsx Целия файл

@@ -0,0 +1,90 @@
1
+import React, { Component, useState, useEffect, useRef } from 'react';
2
+import { Card, Row, Col, Statistic, Icon, Tabs, Form, Select, Button, Modal } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+import TimeSelect from '../../compents/TimeSelect';
10
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
11
+import Navigate from '@/components/Navigate';
12
+import StatsChartLine from '../BuildingStatistic/component/StatsChartLine';
13
+import TableDetail from './tableDetail';
14
+
15
+const detail = props => {
16
+  const { buildingId, buildingName } = props.location.query;
17
+
18
+  const timeRef = useRef();
19
+
20
+  const [data, setData] = useState({});
21
+  const [serachData, setSearchData] = useState({
22
+    startDate:
23
+      moment()
24
+        .subtract(7, 'day')
25
+        .format('YYYY-MM-DDT00:00:00.000') + 'Z',
26
+    endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
27
+  });
28
+  const [timeValue, setTimeValue] = useState();
29
+
30
+  const [time, setTime] = useState();
31
+
32
+  //重置搜索
33
+  const handleReset = e => {
34
+    props.form.resetFields();
35
+    timeRef.current.reset();
36
+    setSearchData({
37
+      startDate:
38
+        moment()
39
+          .subtract(7, 'day')
40
+          .format('YYYY-MM-DDT00:00:00.000') + 'Z',
41
+      endDate: moment().format('YYYY-MM-DDT23:59:59.999') + 'Z',
42
+    });
43
+  };
44
+
45
+  const onTimeChange = e => {
46
+    setTime(e);
47
+  };
48
+  const handleSubmit = e => {
49
+    props.form.validateFieldsAndScroll((err, values) => {
50
+      setTimeValue();
51
+      setSearchData({
52
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
53
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
54
+      });
55
+    });
56
+  };
57
+
58
+  const { getFieldDecorator } = props.form;
59
+
60
+  return (
61
+    <div>
62
+      <Form layout="inline" onSubmit={handleSubmit}>
63
+        <Form.Item>
64
+          <TimeSelect onChange={onTimeChange} ref={timeRef}></TimeSelect>
65
+        </Form.Item>
66
+        <Form.Item>
67
+          <Button type="primary" htmlType="submit" style={{ marginLeft: '30px' }}>
68
+            搜索
69
+          </Button>
70
+          <Button onClick={e => handleReset()} style={{ marginLeft: '30px' }}>
71
+            重置
72
+          </Button>
73
+        </Form.Item>
74
+      </Form>
75
+      <div style={{ marginTop: '20px' }}>
76
+        <StatsChartLine
77
+          params={serachData}
78
+          buildingId={buildingId}
79
+          buildingName={buildingName}
80
+        ></StatsChartLine>
81
+      </div>
82
+      <div style={{ marginTop: '20px' }}>
83
+        <TableDetail params={serachData} buildingId={buildingId}></TableDetail>
84
+      </div>
85
+    </div>
86
+  );
87
+};
88
+
89
+const WrappedTypeForm = Form.create()(detail);
90
+export default WrappedTypeForm;

+ 111
- 0
src/pages/statistics/building/detail/tableDetail.jsx Целия файл

@@ -0,0 +1,111 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Statistic, Table, Button } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+import router from 'umi/router';
5
+import moment from 'moment';
6
+import request from '@/utils/request';
7
+import apis from '@/services/apis';
8
+import AuthButton from '@/components/AuthButton';
9
+
10
+const detailData = props => {
11
+  const {params, buildingId }= props;
12
+
13
+  const [data, setData] = useState({});
14
+  useEffect(() => {
15
+    getTableData(params);
16
+  }, [params]);
17
+
18
+  //获取表格数据
19
+  const getTableData = params => {
20
+    request({ ...apis.stats.timeTableList, params: { ...params, buildingId: buildingId } }).then(
21
+      res => {
22
+        setData(res);
23
+        // this.setState({ ...this.state, tableData: data.records, total: data.total });
24
+      },
25
+    );
26
+  };
27
+
28
+  const handleTableChange = (pagination, filters, sorter) => {
29
+    console.log(pagination, filters, sorter);
30
+    // { startDate: moment(startDate).format('YYYY-MM-DDT00:00:00.000') + 'Z', endDate: moment(endDate).format('YYYY-MM-DDT23:59:59.999') + 'Z', buildingId, pageNum, pageSize, sortField, sortOrder }
31
+    getTableData({
32
+      pageNum: pagination.current,
33
+      sortField: sorter.columnKey,
34
+      sortOrder: sorter.order,
35
+      ...params,
36
+    });
37
+  };
38
+
39
+  const exportBuildingStats = () => {
40
+    request({ ...apis.stats.buildingTimeExport, params: { ...params, buildingId: buildingId } })
41
+      .then(data => {
42
+        if (!data) {
43
+          return;
44
+        }
45
+        const url = window.URL.createObjectURL(new Blob([data]));
46
+        const link = document.createElement('a');
47
+        link.style.display = 'none';
48
+        link.href = url;
49
+        link.setAttribute('download', '项目详情统计.xlsx');
50
+        document.body.append(link);
51
+        link.click();
52
+      })
53
+      .catch(() => {});
54
+  };
55
+
56
+  const columns = [
57
+    {
58
+      title: '日期',
59
+      dataIndex: 'createDate',
60
+      key: 'createDate',
61
+    },
62
+    {
63
+      title: '新增客户',
64
+      dataIndex: 'khNum',
65
+      key: 'kh_num',
66
+      sorter: true,
67
+    },
68
+    {
69
+      title: '公客',
70
+      dataIndex: 'gkNum',
71
+      key: 'gk_num',
72
+      sorter: true,
73
+    },
74
+    {
75
+      title: '私客',
76
+      dataIndex: 'skNum',
77
+      key: 'sk_num',
78
+      sorter: true,
79
+    },
80
+    {
81
+      title: '访问人数',
82
+      dataIndex: 'uvNum',
83
+      key: 'uv_num',
84
+      sorter: true,
85
+    },
86
+  ];
87
+
88
+  return (
89
+    <Card
90
+      title={'详细数据'}
91
+      headStyle={{ textAlign: 'left' }}
92
+
93
+    >
94
+      {/* <div style={{ marginBottom: '20px', textAlign: 'right' }}>
95
+        <AuthButton name="admin.statistical.building.export" noRight={null}>
96
+          <Button type="primary" onClick={exportBuildingStats}>
97
+            导出
98
+          </Button>
99
+        </AuthButton>
100
+      </div> */}
101
+      <Table
102
+        dataSource={data?.records || []}
103
+        columns={columns}
104
+        pagination={{ total: data?.total }}
105
+        key={'createDate'}
106
+        onChange={handleTableChange}
107
+      ></Table>
108
+    </Card>
109
+  );
110
+};
111
+export default detailData;

+ 161
- 0
src/pages/statistics/building/detailData/index.jsx Целия файл

@@ -0,0 +1,161 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Statistic, Table, Button } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+import router from 'umi/router';
5
+import moment from 'moment';
6
+import request from '@/utils/request';
7
+import apis from '@/services/apis';
8
+import CitySelect from '@/components/SelectButton/CitySelect2';
9
+import BuildSelect from '@/components/SelectButton/BuildSelect';
10
+import TimeSelect from '../../compents/TimeSelect';
11
+// import StatsChart from './component/StatsChart';
12
+import AuthButton from '@/components/AuthButton';
13
+
14
+
15
+const detailData = props => {
16
+  const [buildingId, setBuildingId] = useState('');
17
+  const [time, setTime] = useState();
18
+
19
+  const [data, setData] = useState({});
20
+  useEffect(() => {
21
+    if (time) {
22
+      getTableData({
23
+        buildingId: buildingId || undefined,
24
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
25
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
26
+      });
27
+    }
28
+  }, [buildingId, time]);
29
+  const onTimeChange = e => {
30
+    console.log(e, 'onTimeChange');
31
+    setTime(e);
32
+    // getData({ startDate: e[0], endDate: e[1] });
33
+  };
34
+  //获取表格数据
35
+  const getTableData = params => {
36
+    request({ ...apis.stats.tableList, params: { ...params } }).then(res => {
37
+      setData(res);
38
+      // this.setState({ ...this.state, tableData: data.records, total: data.total });
39
+    });
40
+  };
41
+  const handleTableChange = (pagination, filters, sorter) => {
42
+    console.log(pagination, filters, sorter);
43
+    // { startDate: moment(startDate).format('YYYY-MM-DDT00:00:00.000') + 'Z', endDate: moment(endDate).format('YYYY-MM-DDT23:59:59.999') + 'Z', buildingId, pageNum, pageSize, sortField, sortOrder }
44
+    getTableData({
45
+      buildingId: buildingId || undefined,
46
+      startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
47
+      endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
48
+      pageNum: pagination.current,
49
+      sortField: sorter.columnKey,
50
+      sortOrder: sorter.order,
51
+    });
52
+    // {current:pagination.current, sorter.columnKey, sorter.order})
53
+  };
54
+
55
+  //导出
56
+ const exportBuildingStats = () => {
57
+    request({
58
+      ...apis.stats.buildingExport,
59
+      params: {
60
+        buildingId: buildingId || undefined,
61
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
62
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
63
+      },
64
+    })
65
+      .then(data => {
66
+        if (!data) {
67
+          return;
68
+        }
69
+        const url = window.URL.createObjectURL(new Blob([data]));
70
+        const link = document.createElement('a');
71
+        link.style.display = 'none';
72
+        link.href = url;
73
+        link.setAttribute('download', '项目统计.xlsx');
74
+        document.body.append(link);
75
+        link.click();
76
+      })
77
+      .catch(() => {});
78
+  };
79
+  //去详情页面
80
+ const toDetailPage = (record) => {
81
+    router.push({
82
+      pathname: '/statistics/building/detail',
83
+      query: {
84
+        buildingId: record.buildingId,
85
+        buildingName: record.buildingName
86
+      },
87
+    });
88
+  }
89
+
90
+  const columns = [
91
+    {
92
+      title: '项目名称',
93
+      dataIndex: 'buildingName',
94
+      key: 'buildingName',
95
+    },
96
+    {
97
+      title: '新增客户',
98
+      dataIndex: 'khNum',
99
+      key: 'kh_num',
100
+      sorter: true,
101
+    },
102
+    {
103
+      title: '公客',
104
+      dataIndex: 'gkNum',
105
+      key: 'gk_num',
106
+      sorter: true,
107
+    },
108
+    {
109
+      title: '私客',
110
+      dataIndex: 'skNum',
111
+      key: 'sk_num',
112
+      sorter: true,
113
+    },
114
+    {
115
+      title: '访问人数',
116
+      dataIndex: 'uvNum',
117
+      key: 'uv_num',
118
+      sorter: true,
119
+    },
120
+
121
+    {
122
+      title: '成交量',
123
+      dataIndex: 'cjNum',
124
+      key: 'cj_num',
125
+      sorter: true,
126
+    },
127
+
128
+    {
129
+      title: '详情',
130
+      render: (_, record) => (
131
+        <Button type="link" onClick={() => toDetailPage(record)}>
132
+          查看详情
133
+        </Button>
134
+      ),
135
+    },
136
+  ];
137
+
138
+  return (
139
+    <Card
140
+      title={<BuildSelect value={buildingId} onChange={e => setBuildingId(e)} all />}
141
+      headStyle={{ textAlign: 'left' }}
142
+      extra={<TimeSelect onChange={onTimeChange}></TimeSelect>}
143
+    >
144
+      {/* <div style={{marginBottom:'20px',textAlign:'right'}}>
145
+        <AuthButton name="admin.statistical.building.export" noRight={null}>
146
+          <Button type="primary" onClick={exportBuildingStats}>
147
+            导出
148
+          </Button>
149
+        </AuthButton>
150
+      </div> */}
151
+      <Table
152
+        dataSource={data?.records || []}
153
+        columns={columns}
154
+        pagination={{ total: data?.total }}
155
+        onChange={handleTableChange}
156
+        scroll={{ y: 500 }}
157
+      ></Table>
158
+    </Card>
159
+  );
160
+};
161
+export default detailData;

+ 25
- 0
src/pages/statistics/building/index.jsx Целия файл

@@ -0,0 +1,25 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Statistic, Icon } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import router from 'umi/router';
6
+import request from '@/utils/request';
7
+import apis from '@/services/apis';
8
+import BuildingStatistic from './BuildingStatistic';
9
+import DetailData from './detailData';
10
+
11
+const building = props => {
12
+  const [data, setData] = useState([]);
13
+
14
+  return (
15
+    <>
16
+      <div style={{ marginBottom: '20px' }}>
17
+        <BuildingStatistic></BuildingStatistic>
18
+      </div>
19
+      <div style={{ marginBottom: '20px' }}>
20
+        <DetailData></DetailData>
21
+      </div>
22
+    </>
23
+  );
24
+};
25
+export default building;

+ 47
- 15
src/pages/statistics/compents/TimeSelect.jsx Целия файл

@@ -1,18 +1,29 @@
1
-import React, { Component, useState, useEffect } from 'react';
1
+import React, { Component, useState, useImperativeHandle,useEffect } from 'react';
2 2
 import { Card, Row, Col, Statistic, Icon, Button, DatePicker } from 'antd';
3 3
 import ButtonGroup from 'antd/lib/button/button-group';
4 4
 import moment from 'moment';
5 5
 
6 6
 const { RangePicker } = DatePicker;
7
-const TimeSelect = props => {
8
-  const { value, onChange=()=>{} } = props;
7
+
8
+const TimeSelect = React.forwardRef((props, ref) => {
9
+  const { value = 'week', onChange = () => {}, buttonType = 'link' } = props;
9 10
 
10 11
   const [rangePickerValue, setRangePickerValue] = useState();
11 12
   const [type, setType] = useState('week');
12 13
   //   const [rangePickerValue,setRangePickerValue] = useState()
13
-  useEffect(() => {
14
-    // setType('week');
15
-  }, []);
14
+
15
+  useImperativeHandle(ref, () => ({
16
+    reset: () => {
17
+      setType(value);
18
+    },
19
+    // getSearchData: searchData,
20
+  }));
21
+  // useEffect(() => {
22
+  //   // setType('week');
23
+  //   if (value == 'today' || value == 'week' || value == 'month') {
24
+  //     setType(value);
25
+  //   }
26
+  // }, [value]);
16 27
   useEffect(() => {
17 28
     console.log(type);
18 29
     if (type == 'today') {
@@ -47,22 +58,43 @@ const TimeSelect = props => {
47 58
   const selectDate = e => {};
48 59
 
49 60
   const handleRangePickerChange = e => {
61
+    setType('other');
50 62
     onChange(e);
51 63
   };
52 64
 
53 65
   return (
54 66
     <div style={{ display: 'flex' }}>
55 67
       <div>
56
-        <Button type='link' style={type==='today'?undefined:{color:'rgba(0,0,0,0.65)'}} onClick={() => setType('today')}>今日</Button>
57
-        <Button type='link' style={type==='week'?undefined:{color:'rgba(0,0,0,0.65)'}} onClick={() => setType('week')}>最近一周</Button>
58
-        <Button type='link' style={type==='month'?undefined:{color:'rgba(0,0,0,0.65)'}} onClick={() => setType('month')}>最近一月</Button>
68
+        <Button
69
+          type={buttonType}
70
+          style={type === 'today' ? undefined : { color: 'rgba(0,0,0,0.65)' }}
71
+          onClick={() => setType('today')}
72
+        >
73
+          今日
74
+        </Button>
75
+        <Button
76
+          type={buttonType}
77
+          style={type === 'week' ? undefined : { color: 'rgba(0,0,0,0.65)' }}
78
+          onClick={() => setType('week')}
79
+        >
80
+          最近一周
81
+        </Button>
82
+        <Button
83
+          type={buttonType}
84
+          style={type === 'month' ? undefined : { color: 'rgba(0,0,0,0.65)' }}
85
+          onClick={() => setType('month')}
86
+        >
87
+          最近一月
88
+        </Button>
89
+      </div>
90
+      <div>
91
+        <RangePicker
92
+          value={rangePickerValue}
93
+          onChange={handleRangePickerChange}
94
+          style={{ width: 256 }}
95
+        />
59 96
       </div>
60
-      <RangePicker
61
-        value={rangePickerValue}
62
-        onChange={handleRangePickerChange}
63
-        style={{ width: 256 }}
64
-      />
65 97
     </div>
66 98
   );
67
-};
99
+});
68 100
 export default TimeSelect;

+ 317
- 0
src/pages/statistics/consultant/index.jsx Целия файл

@@ -0,0 +1,317 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Button, Icon, Table } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import moment from 'moment';
6
+import router from 'umi/router';
7
+import request from '@/utils/request';
8
+import apis from '@/services/apis';
9
+import TimeSelect from '../compents/TimeSelect';
10
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
11
+import Navigate from '@/components/Navigate';
12
+// import Count from './components/Count';
13
+// import SourceRole from './components/SourceRole';
14
+// import UserSex from './components/UserSex';
15
+// import UserConversion from './components/UserConversion';
16
+// import BuildingStatistic from './BuildingStatistic';
17
+import AuthButton from '@/components/AuthButton';
18
+const clickCon = (val, record, type) => {
19
+  if (val == 0) {
20
+    return (
21
+      <>
22
+        <span>{val}</span>
23
+      </>
24
+    );
25
+  }
26
+  return (
27
+    <>
28
+      <span style={{ color: '#1D74D9', cursor: 'pointer' }} onClick={() => toDetail(record, type)}>
29
+        {val}
30
+      </span>
31
+    </>
32
+  );
33
+};
34
+
35
+const consultant = props => {
36
+  const [data, setData] = useState({});
37
+  const [totalRow, setTotalRow] = useState({});
38
+
39
+  const [time, setTime] = useState();
40
+  const [buildingValue, setBuildingValue] = useState();
41
+
42
+  useEffect(() => {
43
+    if (time) {
44
+      getList({
45
+        buildingId: buildingValue,
46
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
47
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
48
+      });
49
+    }
50
+  }, [time, buildingValue]);
51
+
52
+  // 查询列表
53
+  const getList = params => {
54
+    // updataLoading(true);
55
+
56
+    request({ ...apis.stats.consultantKPI, params: { ...params } })
57
+      .then(data => {
58
+        setData(data.paged);
59
+        setTotalRow(data.total);
60
+        // updataLoading(false);
61
+      })
62
+      .catch(err => {
63
+        // updataLoading(false);
64
+      });
65
+  };
66
+
67
+  const columns = [
68
+    {
69
+      title: '项目',
70
+      dataIndex: 'buildingName',
71
+      key: 'buildingName',
72
+      align: 'center',
73
+      render: (txt, _, index) => (index ? txt : <span>总计</span>),
74
+    },
75
+
76
+    {
77
+      title: '置业顾问名称',
78
+      dataIndex: 'userName',
79
+      key: 'userName',
80
+      align: 'center',
81
+    },
82
+    {
83
+      title: '置业顾问电话',
84
+      dataIndex: 'phone',
85
+      key: 'phone',
86
+      align: 'center',
87
+    },
88
+    {
89
+      title: '客户总计',
90
+      dataIndex: 'totalPersons',
91
+      key: 'totalPersons',
92
+      align: 'center',
93
+      sorter: true,
94
+
95
+      // render: (txt, record, index) =>
96
+      //   index ? clickCon(txt, record, 'totalPersons') : <strong>{txt}</strong>,
97
+    },
98
+    {
99
+      title: '新增客户',
100
+      dataIndex: 'newPersons',
101
+      key: 'newPersons',
102
+      align: 'center',
103
+      sorter: true,
104
+
105
+      // render: (txt, record, index) =>
106
+      //   index ? clickCon(txt, record, 'newPersons') : <strong>{txt}</strong>,
107
+    },
108
+    {
109
+      title: '分享次数',
110
+      dataIndex: 'shareNum',
111
+      key: 'shareNum',
112
+      align: 'center',
113
+      sorter: true,
114
+
115
+      // render: (txt, record, index) =>
116
+      //   index ? clickCon(txt, record, 'shareNum') : <strong>{txt}</strong>,
117
+    },
118
+    {
119
+      title: '分享访问人数',
120
+      dataIndex: 'visitPersons',
121
+      key: 'visitPersons',
122
+      align: 'center',
123
+      sorter: true,
124
+
125
+      // render: (txt, record, index) =>
126
+      //   index ? clickCon(txt, record, 'visitPersons') : <strong>{txt}</strong>,
127
+    },
128
+    // {
129
+    //   title: '分享访问次数',
130
+    //   dataIndex: 'visitNum',
131
+    //   key: 'visitNum',
132
+    //   align: 'center',
133
+    //   sorter: true,
134
+
135
+    //   render: (txt, record, index) =>
136
+    //     index ? clickCon(txt, record, 'visitNum') : <strong>{txt}</strong>,
137
+    // },
138
+
139
+    // {
140
+    //   title: '分享拓客',
141
+    //   dataIndex: 'sharePersons',
142
+    //   key: 'sharePersons',
143
+    //   align: 'center',
144
+    //   sorter: true,
145
+
146
+    //   render: (txt, record, index) =>
147
+    //     index ? clickCon(txt, record, 'sharePersons') : <strong>{txt}</strong>,
148
+    // },
149
+    // {
150
+    //   title: '主页访问人数',
151
+    //   dataIndex: 'homePagePersons',
152
+    //   key: 'homePagePersons',
153
+    //   align: 'center',
154
+    //   sorter: true,
155
+
156
+    //   render: (txt, record, index) =>
157
+    //     index ? clickCon(txt, record, 'homePagePersons') : <strong>{txt}</strong>,
158
+    // },
159
+    // {
160
+    //   title: '主页访问次数',
161
+    //   dataIndex: 'homePageNums',
162
+    //   key: 'homePageNums',
163
+    //   align: 'center',
164
+    //   sorter: true,
165
+
166
+    //   render: (txt, record, index) =>
167
+    //     index ? clickCon(txt, record, 'homePageNums') : <strong>{txt}</strong>,
168
+    // },
169
+    // {
170
+    //   title: '咨询数',
171
+    //   dataIndex: 'chatPersons',
172
+    //   key: 'chatPersons',
173
+    //   align: 'center',
174
+    //   sorter: true,
175
+
176
+    //   render: (txt, record, index) =>
177
+    //     index ? clickCon(txt, record, 'chatPersons') : <strong>{txt}</strong>,
178
+    // },
179
+    // {
180
+    //   title: '点赞数',
181
+    //   dataIndex: 'favorNum',
182
+    //   key: 'favorNum',
183
+    //   align: 'center',
184
+    //   sorter: true,
185
+
186
+    //   render: (txt, record, index) =>
187
+    //     index ? clickCon(txt, record, 'favorNum') : <strong>{txt}</strong>,
188
+    // },
189
+  ];
190
+
191
+  const toAddVisitNum = record => {
192
+    router.push({
193
+      pathname: '/activity/SignupActivity/registrationRecord',
194
+      query: {
195
+        dynamicId: record.dynamicId,
196
+      },
197
+    });
198
+  };
199
+
200
+  //排序
201
+  const handleChange = (pagination, filters, sorter) => {
202
+    console.log(pagination, filters, sorter);
203
+    // Desc  和asc
204
+    let sort = {};
205
+    if (sorter.order == 'ascend') {
206
+      sort.asc = sorter.columnKey;
207
+    } else if (sorter.order == 'descend') {
208
+      sort.desc = sorter.columnKey;
209
+    }
210
+
211
+    getList({
212
+      buildingId: buildingValue,
213
+      startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
214
+      endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
215
+      pageNum: pagination.current,
216
+      pageSize: pagination.pageSize,
217
+      ...sort,
218
+    });
219
+  };
220
+
221
+  function getTableList(params) {
222
+    request({
223
+      ...apis.activityDataStatis.activityDetailTableData,
224
+      params: {
225
+        ...params,
226
+      },
227
+    })
228
+      .then(data => {
229
+        console.log(data);
230
+        setData(data);
231
+        // this.setState({ tableData: data.records, total: data.total });
232
+      })
233
+      .catch();
234
+  }
235
+
236
+  const onTimeChange = e => {
237
+    setTime(e);
238
+  };
239
+
240
+  // 下载文档
241
+  function download(data) {
242
+    if (!data) {
243
+      return;
244
+    }
245
+    const url = window.URL.createObjectURL(new Blob([data]));
246
+    const link = document.createElement('a');
247
+    link.style.display = 'none';
248
+    link.href = url;
249
+    link.setAttribute('download', '置业顾问KPI.xlsx');
250
+    document.body.append(link);
251
+    link.click();
252
+  }
253
+  // 导出
254
+  function exportRecord() {
255
+    updataBtnloading(true);
256
+    request({
257
+      ...apis.stats.exportConsultantKPI,
258
+      responseType: 'blob',
259
+      params: {
260
+        buildingId: buildingValue,
261
+        startDate: moment(time[0]).format('YYYY-MM-DDT00:00:00.000') + 'Z',
262
+        endDate: moment(time[1]).format('YYYY-MM-DDT23:59:59.999') + 'Z',
263
+      },
264
+    })
265
+      .then(response => {
266
+        download(response);
267
+        updataBtnloading(false);
268
+      })
269
+      .catch(error => {
270
+        updataBtnloading(false);
271
+      });
272
+  }
273
+
274
+  const list = data.records;
275
+  const _list = list && list.length > 0 ? [totalRow, ...list] : [];
276
+  let row = 0;
277
+  return (
278
+    <Card
279
+      title={<BuildingSelect value={buildingValue} onChange={e => setBuildingValue(e)} all />}
280
+      headStyle={{ textAlign: 'left' }}
281
+      extra={<TimeSelect onChange={onTimeChange}></TimeSelect>}
282
+    >
283
+      {/* <div>
284
+        <AuthButton name="admin.statistical.consultant.export" noRight={null}>
285
+          <Button
286
+            type="primary"
287
+            onClick={exportRecord}
288
+            style={{ float: 'right', margin: '20px 23px 20px 0', zIndex: 1 }}
289
+          >
290
+            导出
291
+          </Button>
292
+        </AuthButton>
293
+      </div> */}
294
+      <Table
295
+        // rowKey={record => data?.current * data?.size + row++}
296
+        style={{ marginTop: '30px' }}
297
+        dataSource={_list}
298
+        // dataSource={data.records}
299
+        columns={columns}
300
+        pagination={{ current: data?.current, total: data?.total }}
301
+        onChange={handleChange}
302
+        // onChange={handleChange}
303
+        // loading={loading}
304
+      />
305
+      {/* <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
306
+        <Pagination
307
+          showQuickJumper
308
+          defaultCurrent={1}
309
+          total={data.total}
310
+          onChange={changePageNum}
311
+          current={data.current}
312
+        />
313
+      </div> */}
314
+    </Card>
315
+  );
316
+};
317
+export default consultant;

+ 12
- 12
src/pages/statistics/dataReport/components/Count.jsx Целия файл

@@ -9,12 +9,10 @@ import apis from '@/services/apis';
9 9
 const Count = props => {
10 10
   const [data, setData] = useState([]);
11 11
 
12
-
13 12
   const [checkData, setCheckData] = useState([]);
14 13
 
15 14
   useEffect(() => {
16 15
     getIndexEcharts();
17
-
18 16
   }, []);
19 17
 
20 18
   function getIndexEcharts(params) {
@@ -27,19 +25,19 @@ const Count = props => {
27 25
     });
28 26
   }
29 27
 
30
-//   function getBuildingReports() {
31
-//     request({ ...apis.system.taBuildingReports }).then(data => {
32
-//       console.log(
33
-//         (data.records || []).map(x => x.reportCode),
34
-//         '22222222222222222',
35
-//       );
36
-//       setCheckData((data.records || []).map(x => x.reportCode));
37
-//     });
38
-//   }
28
+  //   function getBuildingReports() {
29
+  //     request({ ...apis.system.taBuildingReports }).then(data => {
30
+  //       console.log(
31
+  //         (data.records || []).map(x => x.reportCode),
32
+  //         '22222222222222222',
33
+  //       );
34
+  //       setCheckData((data.records || []).map(x => x.reportCode));
35
+  //     });
36
+  //   }
39 37
 
40 38
   return (
41 39
     <>
42
-      <Row gutter={16} style={{textAlign:'center'}}>
40
+      <Row gutter={16} style={{ textAlign: 'center' }}>
43 41
         <Col span={4}>
44 42
           <Card>
45 43
             <Statistic
@@ -69,8 +67,10 @@ const Count = props => {
69 67
         </Col>
70 68
         <Col span={4}>
71 69
           <Card>
70
+            {/* onClick={()=>router.push('/statistics/dataReport/newAdd')} style={{cursor:'pointer'}} */}
72 71
             <Statistic
73 72
               title="今日新增用户"
73
+              // title={<u></u>}
74 74
               value={data.todayAddPersonNum || 0}
75 75
               //   valueStyle={{ color: '#cf1322' }}
76 76
             />

+ 148
- 0
src/pages/statistics/dataReport/components/IntentionalCustomers.jsx Целия файл

@@ -0,0 +1,148 @@
1
+import React, { Component, useMemo, useState, useEffect } from 'react';
2
+import {
3
+  Form,
4
+  Icon,
5
+  Input,
6
+  Button,
7
+  DatePicker,
8
+  Select,
9
+  Card,
10
+  Row,
11
+  Col,
12
+  Pagination,
13
+  Alert,
14
+  Table,
15
+  Avatar,
16
+  Radio,
17
+  Modal,
18
+  Descriptions,
19
+} from 'antd';
20
+import BuildingSelect from '@/components/SelectButton/BuildSelect';
21
+import { func } from 'prop-types';
22
+import request from '@/utils/request';
23
+import apis from '@/services/apis';
24
+// const { Option } = Select;
25
+
26
+const Layout = prop =>
27
+prop.simple ? (
28
+    prop.children
29
+  ) : (
30
+    <Card title="意向客户" headStyle={{ textAlign: 'left' }}>
31
+      {prop.children}
32
+    </Card>
33
+  );
34
+
35
+const UserBehavior = props => {
36
+  const { simple = false } = props;
37
+  const [data, setData] = useState({ records: [] });
38
+  const [buildingId, setBuildingId] = useState();
39
+
40
+  useEffect(() => {
41
+    IntentionUsers({ buildingId:buildingId,pageNum: 1, pageSize: 5 });
42
+    // getUserBehaviorProfile(formatDate(props.startDate, props.endDate))
43
+  }, [buildingId]);
44
+  function IntentionUsers(params) {
45
+    request({
46
+      ...apis.indexEcharts.intentionUsers,
47
+      params: { ...params },
48
+    }).then(data => {
49
+      console.log(data, 'datadata');
50
+      setData(data);
51
+    });
52
+  }
53
+
54
+  // 分页
55
+  function onChange(pageNum) {
56
+    // eslint-disable-next-line react-hooks/rules-of-hooks
57
+    IntentionUsers({ pageNum: pageNum, pageSize: 5, buildingId });
58
+  }
59
+
60
+  const columns = [
61
+    {
62
+      title: '用户姓名',
63
+      dataIndex: 'personName',
64
+      key: 'personName',
65
+      width: '25%',
66
+    },
67
+    {
68
+      title: '手机号',
69
+      dataIndex: 'phone',
70
+      key: 'phone',
71
+      width: '25%',
72
+    },
73
+    {
74
+      title: '意向楼盘',
75
+      dataIndex: 'buildingName',
76
+      key: 'buildingName',
77
+      width: '25%',
78
+    },
79
+    {
80
+      title: '意向值',
81
+      dataIndex: 'intention',
82
+      key: 'intention',
83
+      width: '25%',
84
+    },
85
+  ];
86
+
87
+  function handleBuildingChange(e) {
88
+    console.log(e, '--eeeeww---');
89
+    // IntentionUsers({ pageNum: 1, pageSize: 5, buildingId: e });
90
+    setBuildingId(e);
91
+  }
92
+
93
+  //意向客户导出
94
+  function exportIntentionUsers() {
95
+    request({
96
+      ...apis.indexEcharts.exportIntentionUsers,
97
+      params: { buildingId },
98
+    }).then(data => {
99
+      if (!data) {
100
+        return;
101
+      }
102
+      const url = window.URL.createObjectURL(new Blob([data]));
103
+      const link = document.createElement('a');
104
+      link.style.display = 'none';
105
+      link.href = url;
106
+      link.setAttribute('download', '意向客户.xlsx');
107
+      document.body.append(link);
108
+      link.click();
109
+    });
110
+  }
111
+
112
+  return (
113
+    <Layout simple={simple}>
114
+      <div>
115
+        <Row>
116
+          <Col span={22}>
117
+            <BuildingSelect
118
+              value={buildingId}
119
+              // slot="action"
120
+              // value={buildingId}
121
+              onChange={e => handleBuildingChange(e)}
122
+            ></BuildingSelect>
123
+          </Col>
124
+          <Col span={2} style={{ textAlign: 'right' }}>
125
+            {/* <Button type="primary" onClick={exportIntentionUsers}>
126
+              导出
127
+            </Button> */}
128
+          </Col>
129
+        </Row>
130
+        <Table
131
+          rowKey="IntentionalCustomers"
132
+          dataSource={data.records}
133
+          columns={columns}
134
+          style={{ marginTop: '15px' }}
135
+          pagination={{
136
+            total: data.total,
137
+            defaultPageSize: 5,
138
+            current: data.current || 1,
139
+            onChange: e => onChange(e),
140
+          }}
141
+          scroll={{ y: 500 }}
142
+        />
143
+      </div>
144
+    </Layout>
145
+  );
146
+};
147
+
148
+export default UserBehavior;

+ 108
- 0
src/pages/statistics/dataReport/components/NewUsers.jsx Целия файл

@@ -0,0 +1,108 @@
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, Card } from 'antd';
9
+
10
+// import styles from '../styles.less'
11
+const formatDate = (start, end) => {
12
+  const startDate = moment(start).format('YYYY-MM-DDT00:00:00.000') + 'Z';
13
+  const endDate = moment(end).format('YYYY-MM-DDT23:59:59.999') + 'Z';
14
+  return { startDate, endDate };
15
+};
16
+const NewUsers = props => {
17
+  const {
18
+    startDate = moment()
19
+      .subtract(7, 'day')
20
+      .format('YYYY-MM-DD'),
21
+    endDate = moment().format('YYYY-MM-DD'),
22
+    simple = false,
23
+  } = props;
24
+  const [data, setData] = useState({ records: [] });
25
+
26
+  useEffect(() => {
27
+    NewsUserCount(formatDate(startDate, endDate));
28
+  }, [startDate, endDate]);
29
+
30
+  function NewsUserCount(params) {
31
+    request({
32
+      ...apis.indexEcharts.changeNewUser,
33
+      params,
34
+    }).then(data => {
35
+      setData(data);
36
+    });
37
+  }
38
+
39
+  const dataZoom = props.dataZoom
40
+    ? [
41
+        {
42
+          type: 'inside',
43
+          start: 0,
44
+          end: 100,
45
+        },
46
+        {
47
+          type: 'slider',
48
+          start: 0,
49
+          end: 100,
50
+        },
51
+      ]
52
+    : undefined;
53
+  const dataset = data || [];
54
+  const options = {
55
+    color: ['#FF814C', '#F02B3E'],
56
+    tooltip: {
57
+      trigger: 'axis',
58
+    },
59
+    icon: 'rect',
60
+    legend: {
61
+      data: ['新用户数', '授权注册'],
62
+    },
63
+    toolbox: {},
64
+    xAxis: {
65
+      type: 'category',
66
+    },
67
+    yAxis: {},
68
+    dataZoom,
69
+    series: [
70
+      {
71
+        name: '新用户数',
72
+        type: 'line',
73
+        smooth: true,
74
+      },
75
+      {
76
+        name: '授权注册',
77
+        type: 'line',
78
+        smooth: true,
79
+      },
80
+    ],
81
+    dataset: {
82
+      dimensions: ['createTime', 'fromNum', 'registeredNum'],
83
+      source: dataset,
84
+    },
85
+  };
86
+
87
+  const piestyles = {
88
+    width: '100%',
89
+    // height: '400px',
90
+  };
91
+
92
+  const Layout = prop =>
93
+    simple ? (
94
+      prop.children
95
+    ) : (
96
+      <Card title="新增用户" headStyle={{ textAlign: 'left' }}>
97
+        {prop.children}
98
+      </Card>
99
+    );
100
+
101
+  return (
102
+    <Layout>
103
+      <EChart options={options} style={piestyles} />
104
+    </Layout>
105
+  );
106
+};
107
+
108
+export default NewUsers;

+ 94
- 0
src/pages/statistics/dataReport/components/UserActive.jsx Целия файл

@@ -0,0 +1,94 @@
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, Card, Icon, message } from 'antd';
9
+
10
+const formatDate = (start, end) => {
11
+  const startDate = moment(start).format('YYYY-MM-DDT00:00:00.000') + 'Z';
12
+  const endDate = moment(end).format('YYYY-MM-DDT23:59:59.999') + 'Z';
13
+  return { startDate, endDate };
14
+};
15
+const UserSource = props => {
16
+  const [data, setData] = useState({ records: [] });
17
+  //柱图
18
+
19
+  useEffect(() => {
20
+    UserActive({ dateType: 'day' });
21
+  }, []);
22
+
23
+  function UserActive(params) {
24
+    request({
25
+      ...apis.indexEcharts.userActive,
26
+      params: { pageSize: 9999, ...params },
27
+    }).then(data => {
28
+      setData(data);
29
+    });
30
+  }
31
+
32
+  const dataset = data.selectActiveUserCount || [];
33
+  const options = {
34
+    tooltip: {},
35
+    xAxis: { type: 'category' },
36
+    yAxis: {},
37
+    series: {
38
+      type: 'bar',
39
+      name: '活跃用户',
40
+      barWidth: 50,
41
+      data: dataset.map(x => [x.date, !x.activityCount ? 0 : x.activityCount]),
42
+      itemStyle: {
43
+        normal: {
44
+          barBorderRadius: [50, 50, 0, 0],
45
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
46
+            {
47
+              offset: 0,
48
+              color: '#FD8A95',
49
+            },
50
+            {
51
+              offset: 1,
52
+              color: '#F13043',
53
+            },
54
+          ]),
55
+          shadowColor: 'rgba(0, 0, 0, 0.4)',
56
+        },
57
+      },
58
+    },
59
+  };
60
+
61
+  function onChange(value) {
62
+    UserActive({ dateType: value });
63
+  }
64
+
65
+  const piestyles = {
66
+    width: '100%',
67
+    height: '400px',
68
+  };
69
+
70
+  return (
71
+    <>
72
+      <Card
73
+        title="用户活跃"
74
+        headStyle={{ textAlign: 'left' }}
75
+        extra={
76
+          <Select
77
+            style={{ width: 100 }}
78
+            defaultValue='day'
79
+            onChange={onChange}
80
+            size={'small'}
81
+          >
82
+            <Option value="day">日活跃</Option>
83
+            <Option value="month">月活跃</Option>
84
+          </Select>
85
+        }
86
+      >
87
+
88
+        <EChart options={options} style={piestyles} />
89
+      </Card>
90
+    </>
91
+  );
92
+};
93
+
94
+export default UserSource;

+ 157
- 0
src/pages/statistics/dataReport/components/UserBehavior.jsx Целия файл

@@ -0,0 +1,157 @@
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, Card } from 'antd';
9
+import BuildSelect from '@/components/SelectButton/BuildSelect';
10
+
11
+const { Option } = Select;
12
+
13
+const eventcolumns = [
14
+  {
15
+    title: '编号',
16
+    dataIndex: 'recordId',
17
+    key: 'recordId',
18
+    align: 'center',
19
+    width: '16%',
20
+  },
21
+  {
22
+    title: '访问时间',
23
+    dataIndex: 'visitTime',
24
+    key: 'visitTime',
25
+    align: 'center',
26
+    width: '18%',
27
+    render: (x, row) => (
28
+      <>
29
+        <span>{moment(row.visitTime).format('YYYY-MM-DD hh:mm:ss')}</span>
30
+      </>
31
+    ),
32
+  },
33
+  {
34
+    title: '离开时间',
35
+    dataIndex: 'leaveTime',
36
+    key: 'leaveTime',
37
+    align: 'center',
38
+    width: '18%',
39
+    render: (x, row) => (
40
+      <>
41
+        <span>{row.leaveTime && moment(row.leaveTime).format('YYYY-MM-DD hh:mm:ss')}</span>
42
+      </>
43
+    ),
44
+  },
45
+];
46
+
47
+const formatDate = (start, end) => {
48
+  const startDate = `${moment(start).format('YYYY-MM-DDT00:00:00.000')}Z`;
49
+  const endDate = `${moment(end).format('YYYY-MM-DDT23:59:59.999')}Z`;
50
+  return { startDate, endDate };
51
+};
52
+const UserBehaviorIndex = props => {
53
+  const {
54
+    startDate = moment()
55
+      .subtract(7,'day')
56
+      .format('YYYY-MM-DD'),
57
+    endDate = moment().format('YYYY-MM-DD'),
58
+  } = props;
59
+  const [data, setData] = useState({ records: [] });
60
+  const [visibleData, setVisibleData] = useState({ visible: false, row: {} });
61
+  const [buildingId, setBuildingId] = useState('');
62
+
63
+  // 柱图
64
+  useEffect(() => {
65
+    const date = formatDate(startDate, endDate);
66
+    getUserBehaviorSummary({
67
+      ...date,
68
+      activity: props.activity,
69
+      event: props.event,
70
+      eventType: props.eventType,
71
+      buildingId: props.buildingId,
72
+    });
73
+    // getUserBehaviorProfile(formatDate(props.startDate, props.endDate))
74
+  }, [startDate, endDate, props.activity, props.event, props.eventType, props.buildingId]);
75
+
76
+  const [recordList, setList] = useState([]);
77
+  function getUserBehaviorSummary(params) {
78
+    request({
79
+      ...apis.indexEcharts.userBehavior.tsUserBehavior,
80
+      params,
81
+    }).then(data => {
82
+      setData(data || {});
83
+      // setList((data.data.records || []).filter(e => e.activity !== '客户'))
84
+    });
85
+  }
86
+
87
+  const seriesMaker = (data.selectUserBehavior || [])
88
+    .filter(
89
+      e =>
90
+        e.activity !== '客户' &&
91
+        e.activity !== '首页' &&
92
+        e.activity !== 'H5' &&
93
+        e.activity !== '房源' &&
94
+        e.activity !== '其他'&&
95
+        e.activity !== '咨询'&&
96
+        e.activity !== '个人中心',
97
+    )
98
+    .reduce((series, item) => {
99
+      let { date, activityCount, activity } = item;
100
+      date = moment(date).format('YYYY-MM-DD');
101
+      if (!activityCount) activityCount = 0;
102
+
103
+      // 使用对象, 可以去重
104
+      series[`${activity}`] = (series[`${activity}`] || []).concat([[date, activityCount]]);
105
+
106
+      return series;
107
+    }, {});
108
+  console.log(seriesMaker, 'seriesMaker----');
109
+
110
+  const dataZoom = props.dataZoom
111
+    ? [
112
+        {
113
+          type: 'inside',
114
+          start: 0,
115
+          end: 100,
116
+        },
117
+        {
118
+          type: 'slider',
119
+          start: 0,
120
+          end: 100,
121
+        },
122
+      ]
123
+    : undefined;
124
+
125
+  const options = {
126
+    title: {},
127
+    icon: 'rect',
128
+    legend: {
129
+      show: true,
130
+      zlevel: 10,
131
+      itemGap: 100,
132
+    },
133
+    color: ['#F12B3E', '#FE929C', '#647CE1', '#A2B9FF', '#FF844F', '#FFBB9D'],
134
+    tooltip: {
135
+      trigger: 'axis',
136
+    },
137
+    xAxis: { type: 'category' },
138
+    yAxis: {},
139
+    dataZoom,
140
+    series: Object.keys(seriesMaker).map(x => ({
141
+      type: 'line',
142
+      smooth: true,
143
+      name: x,
144
+      data: seriesMaker[x],
145
+    })),
146
+  };
147
+
148
+  return (
149
+    <>
150
+      <Card title="用户行为" headStyle={{ textAlign: 'left' }}>
151
+        <EChart options={options} />
152
+      </Card>
153
+    </>
154
+  );
155
+};
156
+
157
+export default UserBehaviorIndex;

+ 2
- 2
src/pages/statistics/dataReport/components/UserSex.jsx Целия файл

@@ -71,10 +71,10 @@ const UserSource = props => {
71 71
         show: false,
72 72
       },
73 73
       data: [
74
-        { name: '男', value: data.maleNum||0 },
74
+        { name: '男', value: data?.maleNum||0 },
75 75
         {
76 76
           name: '女',
77
-          value: data.femaleNum||0,
77
+          value: data?.femaleNum||0,
78 78
         },
79 79
       ],
80 80
     },

+ 126
- 0
src/pages/statistics/dataReport/components/userSource.jsx Целия файл

@@ -0,0 +1,126 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import echarts from 'echarts/lib/echarts';
3
+import { Card } from 'antd';
4
+import EChart from '@/components/EchartsTest/EChart';
5
+import request from '@/utils/request';
6
+import apis from '@/services/apis';
7
+import moment from 'moment';
8
+import router from 'umi/router';
9
+
10
+const formatDate = (start, end) => {
11
+  const startDate = moment(start).format('YYYY-MM-DDT00:00:00.000') + 'Z';
12
+  const endDate = moment(end).format('YYYY-MM-DDT23:59:59.999') + 'Z';
13
+  return { startDate, endDate };
14
+};
15
+
16
+const UserSource = props => {
17
+  const { startDate = moment().subtract(7, 'day').format('YYYY-MM-DD'), endDate = moment().format('YYYY-MM-DD') } = props;
18
+  const [xData, setxData] = useState([]);
19
+  const [fromData, setFromData] = useState([]);
20
+  const [registerData, setRegisterData] = useState([]);
21
+  //柱图
22
+  useEffect(() => {
23
+    userResource(formatDate(startDate, endDate));
24
+  }, []);
25
+
26
+  function userResource(params) {
27
+    request({
28
+      ...apis.indexEcharts.selectPersonFrom,
29
+      params,
30
+    }).then(data => {
31
+
32
+      setxData(data.tdWxDicts.map(x => x.sceneAlias));
33
+      setFromData(data.tdWxDicts.map(x => x.fromData));
34
+      setRegisterData(data.tdWxDicts.map(x => x.registerSum));
35
+      // props.onSuccess(data)
36
+    });
37
+  }
38
+
39
+  const subtitle = '最近7天';
40
+  const baroptions = {
41
+    title: {},
42
+    xAxis: {
43
+      type: 'category',
44
+      data: xData,
45
+      axisLabel: { rotate: 45 },
46
+    },
47
+    legend: {
48
+      left: '20%',
49
+      data: ['所有用户', '注册用户'],
50
+    },
51
+
52
+    tooltip: {},
53
+
54
+    yAxis: {},
55
+    series: [
56
+      {
57
+        type: 'bar',
58
+        name: '所有用户',
59
+        datasetIndex: 0,
60
+        barWidth: 20,
61
+        data: fromData,
62
+        itemStyle: {
63
+          normal: {
64
+            barBorderRadius: [20, 20, 0, 0],
65
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
66
+              {
67
+                offset: 0,
68
+                color: '#FFC4A8',
69
+              },
70
+              {
71
+                offset: 1,
72
+                color: '#FF7E49',
73
+              },
74
+            ]),
75
+            shadowColor: 'rgba(0, 0, 0, 0.4)',
76
+          },
77
+        },
78
+      },
79
+      {
80
+        type: 'bar',
81
+        name: '注册用户',
82
+        barWidth: 20,
83
+        data: registerData,
84
+        itemStyle: {
85
+          normal: {
86
+            barBorderRadius: [20, 20, 0, 0],
87
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
88
+              {
89
+                offset: 0,
90
+                color: '#FE939D',
91
+              },
92
+              {
93
+                offset: 1,
94
+                color: '#F0293C',
95
+              },
96
+            ]),
97
+            shadowColor: 'rgba(0, 0, 0, 0.4)',
98
+          },
99
+        },
100
+      },
101
+    ],
102
+    // dataset: {
103
+    //   id: 'bar',
104
+    //   dimensions: ['fromName', 'userCount', 'registered'],
105
+    //   source: source,
106
+    // },
107
+  };
108
+
109
+  const barstyle = {
110
+    width: '100%',
111
+    // height: '480px',
112
+    // minWidth: '400px'
113
+  };
114
+
115
+  return (
116
+    <>
117
+      <Card title="用户来源" headStyle={{ textAlign: 'left' }}>
118
+        {/* <p onClick={()=>router.push('/statistical/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> */}
119
+
120
+        <EChart options={baroptions} style={barstyle} />
121
+      </Card>
122
+    </>
123
+  );
124
+};
125
+
126
+export default UserSource;

+ 35
- 4
src/pages/statistics/dataReport/index.jsx Целия файл

@@ -7,10 +7,17 @@ import request from '@/utils/request';
7 7
 import apis from '@/services/apis';
8 8
 import Count from './components/Count';
9 9
 import SourceRole from './components/SourceRole';
10
+import UserSource from './components/UserSource';
11
+import UserBehavior from './components/UserBehavior';
12
+import UserActive from './components/UserActive';
13
+
10 14
 import UserSex from './components/UserSex';
11 15
 import UserConversion from './components/UserConversion';
16
+import NewUsers from './components/NewUsers';
17
+
12 18
 import BuildingStatistic from './BuildingStatistic';
13 19
 import CityNums from './CityNums';
20
+import IntentionalCustomers from './components/IntentionalCustomers';
14 21
 
15 22
 const DataReport = props => {
16 23
   const [data, setData] = useState([]);
@@ -20,25 +27,49 @@ const DataReport = props => {
20 27
       <div style={{ marginBottom: '20px' }}>
21 28
         <Count></Count>
22 29
       </div>
30
+      <div style={{ marginBottom: '20px' }}>
31
+        <Row gutter={16} style={{ textAlign: 'center' }}>
32
+          <Col span={16}>
33
+            <UserSource></UserSource>
34
+          </Col>
35
+          <Col span={8}>
36
+            <SourceRole></SourceRole>
37
+          </Col>
38
+        </Row>
39
+      </div>
23 40
       <div style={{ marginBottom: '20px' }}>
24 41
         <CityNums></CityNums>
25 42
       </div>
43
+      <div style={{ marginBottom: '20px' }}>
44
+        <UserBehavior></UserBehavior>
45
+      </div>
26 46
       <div style={{ marginBottom: '20px' }}>
27 47
         <Row gutter={16} style={{ textAlign: 'center' }}>
28
-          <Col span={8}>
29
-            <SourceRole></SourceRole>
48
+          <Col span={16}>
49
+            <UserActive></UserActive>
30 50
           </Col>
31 51
           <Col span={8}>
32 52
             <UserSex></UserSex>
33 53
           </Col>
54
+        </Row>
55
+      </div>
56
+      <div style={{ marginBottom: '20px' }}>
57
+        <Row gutter={16} style={{ textAlign: 'center' }}>
58
+          <Col span={16}>
59
+            <NewUsers></NewUsers>
60
+          </Col>
34 61
           <Col span={8}>
35 62
             <UserConversion></UserConversion>
36 63
           </Col>
37 64
         </Row>
38 65
       </div>
39
-      <div style={{ marginBottom: '20px' }}>
40
-        <BuildingStatistic></BuildingStatistic>
66
+       <div style={{ marginBottom: '20px' }}>
67
+        <IntentionalCustomers></IntentionalCustomers>
41 68
       </div>
69
+      
70
+      {/* <div style={{ marginBottom: '20px' }}>
71
+        <BuildingStatistic></BuildingStatistic>
72
+      </div> */}
42 73
     </>
43 74
   );
44 75
 };

+ 37
- 0
src/pages/statistics/dataReport/newAdd.jsx Целия файл

@@ -0,0 +1,37 @@
1
+import React, { Component, useState, useEffect } from 'react';
2
+import { Card, Row, Col, Statistic, Icon } from 'antd';
3
+// import IndexEcharts from './components/indexEcharts';
4
+// import Swiper from './swiper/index';
5
+import router from 'umi/router';
6
+import request from '@/utils/request';
7
+import apis from '@/services/apis';
8
+import Count from './components/Count';
9
+import SourceRole from './components/SourceRole';
10
+import UserSource from './components/UserSource';
11
+import UserBehavior from './components/UserBehavior';
12
+import UserActive from './components/UserActive';
13
+
14
+import UserSex from './components/UserSex';
15
+import UserConversion from './components/UserConversion';
16
+import NewUsers from './components/NewUsers';
17
+
18
+import BuildingStatistic from './BuildingStatistic';
19
+import CityNums from './CityNums';
20
+import TimeSelect from '../compents/TimeSelect';
21
+import IntentionalCustomers from './components/IntentionalCustomers';
22
+const newAdd = props => {
23
+  const [data, setData] = useState([]);
24
+
25
+  const onTimeChange=()=>{
26
+
27
+  }
28
+
29
+  return (
30
+    <Card>
31
+      <TimeSelect onChange={onTimeChange}  ></TimeSelect>
32
+      <NewUsers simple={true}></NewUsers>
33
+      <IntentionalCustomers  simple={true}></IntentionalCustomers>
34
+    </Card>
35
+  );
36
+};
37
+export default newAdd;

+ 1
- 1
src/services/apis.js Целия файл

@@ -1997,7 +1997,7 @@ export default {
1997 1997
     },
1998 1998
     activityDetailTableData: {
1999 1999
       method: 'GET',
2000
-      url: `${prefix}/statistics/activityList`,
2000
+      url: `${prefix}/activityStatistical/activityStatisDetail`,
2001 2001
       action: 'admin.contract.list.get',
2002 2002
     },
2003 2003
     activityDetailTableDataExport: {