张涛 2 jaren geleden
bovenliggende
commit
b50852a912

+ 2
- 1
config/config.js Bestand weergeven

@@ -8,7 +8,8 @@ const { REACT_APP_ENV } = process.env;
8 8
 
9 9
 export default defineConfig({
10 10
   define: {
11
-    API_BASE: 'http://machine.njyunzhi.com',
11
+    // API_BASE: 'http://machine.njyunzhi.com',
12
+    API_BASE: 'http://192.168.89.147',
12 13
   },
13 14
   hash: true,
14 15
   history: {

+ 1
- 1
config/proxy.js Bestand weergeven

@@ -11,7 +11,7 @@ export default {
11 11
     // localhost:8000/api/** -> https://preview.pro.ant.design/api/**
12 12
     '/api/': {
13 13
       // 要代理的地址
14
-      target: 'http://127.0.0.1:7080',
14
+      target: 'http://192.168.89.147:7080',
15 15
       // target: 'http://192.168.89.76:7080',
16 16
       // target: 'http://machine.njyunzhi.com',
17 17
       // 配置了这个可以从 http 代理到 https

+ 64
- 0
src/components/Bar/index copy.jsx Bestand weergeven

@@ -0,0 +1,64 @@
1
+import React, { useMemo } from 'react';
2
+
3
+import ECharts from '@/components/ECharts';
4
+
5
+const labelOption = {
6
+  show: true,
7
+  formatter: '{c}',
8
+  position: 'insideTop',
9
+  distance: -20,
10
+  fontSize: 16,
11
+  rich: {
12
+    name: {}
13
+  }
14
+};
15
+
16
+export default (props) => {
17
+  const { opt, title, h } = props
18
+  const titleList = opt.map(item => { return { name: item.title } })
19
+  const colorList = opt.map(item => { return item.color })
20
+  const seriesList = opt.map(item => {
21
+    return {
22
+      name: item.title,
23
+      type: 'bar',
24
+      label: labelOption,
25
+      emphasis: {
26
+        focus: 'series'
27
+      },
28
+      data: item.valueList
29
+    }
30
+  })
31
+  const defaultOpt = {
32
+    title: {
33
+      text: title,
34
+      left: 'center',
35
+    },
36
+    tooltip: {
37
+      trigger: 'axis',
38
+      axisPointer: {
39
+        type: 'shadow'
40
+      },
41
+      extraCssText: 'height:100px;'
42
+    },
43
+    color: colorList,
44
+    legend: {
45
+      top: 'bottom',
46
+      data: titleList,
47
+    },
48
+    xAxis: [
49
+      {
50
+        type: 'category',
51
+        axisTick: { show: false },
52
+        data: opt[0].keyList
53
+      }
54
+    ],
55
+    yAxis: [
56
+      {
57
+        type: 'value'
58
+      }
59
+    ],
60
+    series: seriesList
61
+  }
62
+  const option = useMemo(() => defaultOpt, []);
63
+  return <div style={{ height: h, width: '100%' }}> <ECharts option={option} /></div>;
64
+};

+ 123
- 47
src/components/Bar/index.jsx Bestand weergeven

@@ -1,4 +1,4 @@
1
-import React, { useMemo } from 'react';
1
+import React, { useEffect, useMemo, useState } from 'react';
2 2
 
3 3
 import ECharts from '@/components/ECharts';
4 4
 
@@ -9,56 +9,132 @@ const labelOption = {
9 9
   distance: -20,
10 10
   fontSize: 16,
11 11
   rich: {
12
-    name: {}
13
-  }
12
+    name: {},
13
+  },
14 14
 };
15 15
 
16 16
 export default (props) => {
17
-  const { opt, title, h } = props
18
-  const titleList = opt.map(item => { return { name: item.title } })
19
-  const colorList = opt.map(item => { return item.color })
20
-  const seriesList = opt.map(item => {
21
-    return {
22
-      name: item.title,
23
-      type: 'bar',
24
-      label: labelOption,
25
-      emphasis: {
26
-        focus: 'series'
17
+  const { opt, optL, title, h } = props;
18
+  // console.log(optL);
19
+  // console.log(opt);
20
+  const dataL = [];
21
+  opt.forEach((it, ind) => {
22
+    optL.forEach((its) => {
23
+      if (its.name == it.name) {
24
+        dataL.push(its.value);
25
+        // dataL.push({
26
+        // name: it.name,
27
+        // value: its.value,
28
+        // });
29
+      }
30
+    });
31
+  });
32
+  const dataLs = useMemo(() => dataL, [dataL]);
33
+
34
+  // 亩
35
+  const dataX = opt.map((it) => it.name);
36
+  const dataVal = opt.map((it) => it.value);
37
+  // 台
38
+  const colors = ['#E94F05', '#5470C6', '#91CC75'];
39
+  const option = useMemo(
40
+    () => ({
41
+      color: colors,
42
+      title: {
43
+        text: title,
44
+        left: 'center',
27 45
       },
28
-      data: item.valueList
29
-    }
30
-  })
31
-  const defaultOpt = {
32
-    title: {
33
-      text: title,
34
-      left: 'center',
35
-    },
36
-    tooltip: {
37
-      trigger: 'axis',
38
-      axisPointer: {
39
-        type: 'shadow'
46
+      tooltip: {
47
+        trigger: 'axis',
48
+        axisPointer: {
49
+          type: 'cross',
50
+        },
51
+        extraCssText: 'width:auto;height:auto',
40 52
       },
41
-      extraCssText: 'height:100px;'
42
-    },
43
-    color: colorList,
44
-    legend: {
45
-      top: 'bottom',
46
-      data: titleList,
47
-    },
48
-    xAxis: [
49
-      {
53
+      xAxis: {
50 54
         type: 'category',
51
-        axisTick: { show: false },
52
-        data: opt[0].keyList
53
-      }
54
-    ],
55
-    yAxis: [
56
-      {
57
-        type: 'value'
58
-      }
59
-    ],
60
-    series: seriesList
61
-  }
62
-  const option = useMemo(() => defaultOpt, []);
63
-  return <div style={{ height: h, width: '100%' }}> <ECharts option={option} /></div>;
55
+        data: dataX,
56
+        axisLabel: { interval: 0, rotate: 40 },
57
+        name: '合作社',
58
+      },
59
+      yAxis: [
60
+        {
61
+          type: 'value',
62
+          name: '台',
63
+          position: 'left',
64
+          alignTicks: true,
65
+          axisLine: {
66
+            show: true,
67
+            lineStyle: {
68
+              color: colors[0],
69
+            },
70
+          },
71
+          axisLabel: {
72
+            formatter: '{value} 台',
73
+          },
74
+        },
75
+        {
76
+          type: 'value',
77
+          name: '亩',
78
+          position: 'right',
79
+          alignTicks: true,
80
+          axisLine: {
81
+            show: true,
82
+            lineStyle: {
83
+              color: colors[1],
84
+            },
85
+          },
86
+          axisLabel: {
87
+            formatter: '{value} 亩',
88
+          },
89
+        },
90
+        // {
91
+        //   type: 'value',
92
+        //   name: '流量',
93
+        //   position: 'right',
94
+        //   alignTicks: true,
95
+        //   axisLine: {
96
+        //     show: true,
97
+        //     lineStyle: {
98
+        //       color: colors[2],
99
+        //     },
100
+        //   },
101
+        // axisLabel: {
102
+        //   formatter: '{value} ',
103
+        // },
104
+        // },
105
+      ],
106
+      dataZoom: {
107
+        show: true,
108
+        start: 0,
109
+        end: 100,
110
+      },
111
+      grid: {
112
+        height: '55%',
113
+      },
114
+      series: [
115
+        {
116
+          name: '设备',
117
+          data: dataLs,
118
+          type: 'line',
119
+        },
120
+        {
121
+          name: '作业',
122
+          data: dataVal,
123
+          type: 'bar',
124
+          yAxisIndex: 1,
125
+        },
126
+        // {
127
+        //   data: dataVal,
128
+        //   type: 'bar',
129
+        //   yAxisIndex: 2,
130
+        // },
131
+      ],
132
+    }),
133
+    [dataLs, dataVal, dataX],
134
+  );
135
+  return (
136
+    <div style={{ height: h, width: '100%' }}>
137
+      <ECharts option={option} />
138
+    </div>
139
+  );
64 140
 };

+ 149
- 0
src/components/BarPerson/index.jsx Bestand weergeven

@@ -0,0 +1,149 @@
1
+import React, { useEffect, useMemo, useState } from 'react';
2
+
3
+import ECharts from '@/components/ECharts';
4
+
5
+const labelOption = {
6
+  show: true,
7
+  formatter: '{c}',
8
+  position: 'insideTop',
9
+  distance: -20,
10
+  fontSize: 16,
11
+  rich: {
12
+    name: {},
13
+  },
14
+};
15
+
16
+export default (props) => {
17
+  const { opt, optP, title, h } = props;
18
+  const dataL = [];
19
+  opt.forEach((it, ind) => {
20
+    optP.forEach((its) => {
21
+      if (its.name == it.name) {
22
+        dataL.push(its.value);
23
+        // dataL.push({
24
+        // name: it.name,
25
+        // value: its.value,
26
+        // });
27
+      }
28
+    });
29
+  });
30
+
31
+  const dataPerson = useMemo(() => dataL, [dataL]);
32
+
33
+  // 亩
34
+  const dataX = opt.map((it) => it.name);
35
+  const dataVal = opt.map((it) => it.value);
36
+  // 人
37
+  const colors = ['#E94F05', '#5470C6', '#91CC75'];
38
+
39
+  const option = useMemo(
40
+    () => ({
41
+      color: colors,
42
+      title: {
43
+        text: title,
44
+        left: 'center',
45
+      },
46
+      tooltip: {
47
+        trigger: 'axis',
48
+        axisPointer: {
49
+          type: 'cross',
50
+        },
51
+        extraCssText: 'width:auto;height:auto',
52
+      },
53
+      xAxis: {
54
+        type: 'category',
55
+        data: dataX,
56
+        axisLabel: { interval: 0, rotate: 40 },
57
+        name: '合作社',
58
+      },
59
+      yAxis: [
60
+        {
61
+          type: 'value',
62
+          name: '人',
63
+          position: 'left',
64
+          alignTicks: true,
65
+          axisLine: {
66
+            show: true,
67
+            lineStyle: {
68
+              color: colors[0],
69
+            },
70
+          },
71
+          axisLabel: {
72
+            formatter: '{value} 人',
73
+          },
74
+        },
75
+        {
76
+          type: 'value',
77
+          name: '亩',
78
+          position: 'right',
79
+          alignTicks: true,
80
+          axisLine: {
81
+            show: true,
82
+            lineStyle: {
83
+              color: colors[1],
84
+            },
85
+          },
86
+          axisLabel: {
87
+            formatter: '{value} 亩',
88
+          },
89
+        },
90
+        // {
91
+        //   type: 'value',
92
+        //   name: '流量',
93
+        //   position: 'right',
94
+        //   alignTicks: true,
95
+        //   axisLine: {
96
+        //     show: true,
97
+        //     lineStyle: {
98
+        //       color: colors[2],
99
+        //     },
100
+        //   },
101
+        // axisLabel: {
102
+        //   formatter: '{value} ',
103
+        // },
104
+        // },
105
+      ],
106
+      dataZoom: {
107
+        show: true,
108
+        start: 0,
109
+        end: 100,
110
+      },
111
+      grid: {
112
+        height: '55%',
113
+      },
114
+      series: [
115
+        {
116
+          name: '人',
117
+          data: dataPerson,
118
+          type: 'line',
119
+          showBackground: true,
120
+        },
121
+        {
122
+          name: '作业',
123
+          data: dataVal,
124
+          type: 'bar',
125
+          yAxisIndex: 1,
126
+          showBackground: true,
127
+          backgroundStyle: {
128
+            color: '#FFFF',
129
+          },
130
+        },
131
+        // {
132
+        //   data: dataVal,
133
+        //   type: 'bar',
134
+        //   yAxisIndex: 2,
135
+        //   showBackground: true,
136
+        //   backgroundStyle: {
137
+        //     color: '#EE6666',
138
+        //   },
139
+        // },
140
+      ],
141
+    }),
142
+    [dataPerson, dataVal, dataX],
143
+  );
144
+  return (
145
+    <div style={{ height: h, width: '100%' }}>
146
+      <ECharts option={option} />
147
+    </div>
148
+  );
149
+};

+ 4
- 1
src/components/ECharts/index.jsx Bestand weergeven

@@ -5,7 +5,7 @@ import classNames from 'classnames';
5 5
 // 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
6 6
 import * as echarts from 'echarts/core';
7 7
 // 引入图表,图表后缀都为 Chart
8
-import { BarChart, PieChart } from 'echarts/charts';
8
+import { BarChart, PieChart, LineChart } from 'echarts/charts';
9 9
 // 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
10 10
 import {
11 11
   TitleComponent,
@@ -15,6 +15,7 @@ import {
15 15
   TransformComponent,
16 16
   LegendComponent,
17 17
   ToolboxComponent,
18
+  DataZoomComponent,
18 19
 } from 'echarts/components';
19 20
 // 标签自动布局,全局过渡动画等特性
20 21
 import { LabelLayout, UniversalTransition } from 'echarts/features';
@@ -35,6 +36,8 @@ echarts.use([
35 36
   SVGRenderer,
36 37
   LegendComponent,
37 38
   ToolboxComponent,
39
+  DataZoomComponent,
40
+  LineChart,
38 41
 ]);
39 42
 
40 43
 import Styles from './style.less';

+ 30
- 0
src/components/WelcomeCard/index copy.jsx Bestand weergeven

@@ -0,0 +1,30 @@
1
+import up from '@/assets/welcome/up.png';
2
+import down from '@/assets/welcome/down.png';
3
+import './style.less';
4
+
5
+import { createFromIconfontCN } from '@ant-design/icons';
6
+
7
+const WCard = (props) => {
8
+  const { value } = props;
9
+  //隔三位加一个逗号
10
+  function toThousands(num) {
11
+    return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
12
+  }
13
+  const MyIcon = createFromIconfontCN({
14
+    scriptUrl: '//at.alicdn.com/t/font_2904679_h2r1om69sid.js', // 在 iconfont.cn 上生成
15
+  });
16
+  return (
17
+    <div className="wcard">
18
+      <MyIcon type={value.icon} className="wImg" style={{ color: value.color }} />
19
+      <div className="wright">
20
+        <div className="title">{value.title}</div>
21
+        <div className="value">{toThousands(value.value)}</div>
22
+        <div className="percentage">
23
+          <img className="wicon" src={value.percentage > 0 ? up : down} />
24
+          同比上月&nbsp;&nbsp;{Math.abs(value.percentage)}%
25
+        </div>
26
+      </div>
27
+    </div>
28
+  );
29
+};
30
+export default WCard;

+ 14
- 16
src/components/WelcomeCard/index.jsx Bestand weergeven

@@ -1,13 +1,11 @@
1
-import up from '@/assets/welcome/up.png'
2
-import down from '@/assets/welcome/down.png'
3
-import './style.less'
4
-
1
+import up from '@/assets/welcome/up.png';
2
+import down from '@/assets/welcome/down.png';
3
+import './style.less';
5 4
 
6 5
 import { createFromIconfontCN } from '@ant-design/icons';
7 6
 
8
-
9
-const WCard = (props) => {
10
-  const { value } = props
7
+const WCard = ({ value }) => {
8
+  // const {  } = props;
11 9
   //隔三位加一个逗号
12 10
   function toThousands(num) {
13 11
     return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
@@ -16,14 +14,14 @@ const WCard = (props) => {
16 14
     scriptUrl: '//at.alicdn.com/t/font_2904679_h2r1om69sid.js', // 在 iconfont.cn 上生成
17 15
   });
18 16
   return (
19
-    <div className='wcard'>
20
-      <MyIcon type={value.icon} className='wImg' style={{ color: value.color }} />
21
-      <div className='wright'>
22
-        <div className='title'>{value.title}</div>
23
-        <div className='value'>{toThousands(value.value)}</div>
24
-        <div className='percentage'><img className='wicon' src={value.percentage > 0 ? up : down} />同比上月&nbsp;&nbsp;{Math.abs(value.percentage)}%</div>
17
+    <div className="wcard">
18
+      <MyIcon type={value?.icon || ''} className="wImg" style={{ color: value?.color || '' }} />
19
+      <div className="wright">
20
+        <div className="title">{value?.title}</div>
21
+        <div className="value">{toThousands(value?.value)}</div>
22
+        {/* <div className='percentage'><img className='wicon' src={value.percentage > 0 ? up : down} />同比上月&nbsp;&nbsp;{Math.abs(value.percentage)}%</div> */}
25 23
       </div>
26 24
     </div>
27
-  )
28
-}
29
-export default WCard
25
+  );
26
+};
27
+export default WCard;

+ 19
- 12
src/components/WelcomeCard/style.less Bestand weergeven

@@ -1,32 +1,39 @@
1
-.wcard{
1
+.wcard {
2 2
   display: flex;
3 3
   align-items: center;
4 4
   padding: 16px 32px;
5 5
   background: #fff;
6 6
   width: 320px;
7
-  .wImg{
7
+
8
+  .wImg {
8 9
     width: 65px;
9 10
     height: 65px;
10 11
     margin-right: 64px;
11
-    svg{
12
+
13
+    svg {
12 14
       width: 100%;
13
-      height:100%
15
+      height: 100%
14 16
     }
15 17
   }
16
-  .wright{
18
+
19
+  .wright {
17 20
     text-align: right;
18
-    .title{}
19
-    .value{
20
-      color:rgb(26, 182, 202);
21
-      font-size: 30px;
21
+
22
+    // .title {}
23
+
24
+    .value {
25
+      color: rgb(26, 182, 202);
26
+      font-size: 25px;
22 27
       margin: 16px 0;
23 28
     }
24
-    .percentage{
29
+
30
+    .percentage {
25 31
       color: gray;
26
-      .wicon{
32
+
33
+      .wicon {
27 34
         width: 20px;
28 35
         height: 20px;
29 36
       }
30
-    }    
37
+    }
31 38
   }
32 39
 }

+ 169
- 0
src/pages/Welcome copy.jsx Bestand weergeven

@@ -0,0 +1,169 @@
1
+import React, { useState, useRef } from 'react';
2
+import { PageContainer } from '@ant-design/pro-layout';
3
+import { Card, Row, Col } from 'antd';
4
+import { useIntl } from 'umi';
5
+import WCard from '@/components/WelcomeCard'
6
+import { Swiper, SwiperSlide } from 'swiper/react';
7
+import { Autoplay } from 'swiper';
8
+import 'swiper/css';
9
+import Bar from '@/components/Bar/index.jsx';
10
+import Pie from '@/components/Pie';
11
+import PieArea from '@/components/PieArea';
12
+import { history } from 'umi';
13
+import { getDispatchList } from '@/services/dispatch'
14
+import './Welcome.less'
15
+import { useEffect } from 'react';
16
+
17
+const Welcome = () => {
18
+  const intl = useIntl();
19
+  const topData = [
20
+    {
21
+      icon: 'icon-icon',
22
+      color: '#1cbbb4',
23
+      title: '注册用户',
24
+      value: 580239,
25
+      percentage: 32.6
26
+    },
27
+    {
28
+      icon: 'icon-show_gongsiguanli_fill',
29
+      color: '#8dc63f',
30
+      title: '合作社数',
31
+      value: 2017,
32
+      percentage: 5.6
33
+    },
34
+    {
35
+      icon: 'icon-tuolaji',
36
+      color: '#a5673f',
37
+      title: '农用机数',
38
+      value: 2000,
39
+      percentage: 42.6
40
+    },
41
+    {
42
+      icon: 'icon-dingdanguanli',
43
+      color: '#8799a3',
44
+      title: '订单数',
45
+      value: 2075994,
46
+      percentage: -1.6
47
+    },
48
+  ]
49
+  const centerData = [
50
+    {
51
+      title: '预约订单',
52
+      color: '#70d4d4',
53
+      keyList: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
54
+      valueList: [320, 332, 301, 334, 390, 88, 320, 332, 301, 334, 390, 88]
55
+    },
56
+    {
57
+      title: '完成订单',
58
+      color: '#c3b6e6',
59
+      keyList: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
60
+      valueList: [220, 182, 191, 234, 290, 256, 220, 182, 191, 234, 290, 356]
61
+    }
62
+  ]
63
+
64
+  const [machineryStatus, setMachineryStatus] = useState([
65
+    {
66
+      color: '#70d4d4',
67
+      keyList: ['预约', '作业', '闲置', '离线', '维修'],
68
+      valueList: [350, 900, 650, 180, 380],
69
+    }
70
+  ])
71
+
72
+  const [workData, setWorkData] = useState([
73
+    { name: '收割机', value: 35 },
74
+    { name: '播种机', value: 35 },
75
+    { name: '农药机', value: 30 },
76
+    { name: '其他', value: 180 },
77
+  ]);
78
+  const [workAreaData, setWorkAreaData] = useState([
79
+    { name: '收割机', value: 350 },
80
+    { name: '播种机', value: 900 },
81
+    { name: '农药机', value: 650 },
82
+    { name: '其他', value: 180 },
83
+  ]);
84
+  const [dispatchList, setDispatchList] = useState([])
85
+  const goDispatch = (val) => {
86
+    history.push(`../OrderManage/dispatch.jsx?id=${val.orderId}`);
87
+  }
88
+  useEffect(() => {
89
+    getDispatchList({ isWarn: true, pageSize: 500 }).then((res) => {
90
+      setDispatchList(res.records)
91
+    })
92
+  }, [])
93
+  return (
94
+    <PageContainer>
95
+      <div className="welcome">
96
+        <div className="head">
97
+          <Row justify='space-between'>
98
+            <Col flex='320px'>
99
+              <WCard value={topData[0]} />
100
+            </Col>
101
+            <Col flex='320px'>
102
+              <WCard value={topData[1]} />
103
+            </Col>
104
+            <Col flex='320px'>
105
+              <WCard value={topData[2]} />
106
+            </Col>
107
+            <Col flex='320px'>
108
+              <WCard value={topData[3]} />
109
+            </Col>
110
+          </Row>
111
+        </div>
112
+
113
+        <Row justify='space-between'>
114
+          <Col span={16}>
115
+            <Card style={{ marginTop: '32px' }}>
116
+              <Bar h='500px' title='本年度预约订单数据概览' opt={centerData} />
117
+            </Card>
118
+          </Col>
119
+          <Col span={7} >
120
+            <Card title='待调度订单' style={{ marginTop: '32px', height: '548px' }} >
121
+              {
122
+                dispatchList.length <= 8 ?
123
+                  <div style={{ height: '448px', width: '100%' }}>
124
+                    {dispatchList.map(item =>
125
+                      <div style={{ height: '60px' }} key={item.orderId} onClick={() => goDispatch(item)} >
126
+                        {(item.personName || item.phone) + ' 于 ' + item.createDate + ' 下了一单请您尽快处理!'}
127
+                      </div>
128
+                    )}
129
+                  </div> :
130
+                  <Swiper
131
+                    height={60}
132
+                    style={{ height: '448px' }}
133
+                    autoplay={{
134
+                      delay: 1500,
135
+                      disableOnInteraction: false,
136
+                    }}
137
+                    loop
138
+                    loopAdditionalSlides={8}
139
+                    modules={[Autoplay]}
140
+                    direction="vertical"
141
+                  >
142
+                    {dispatchList.map((item) => (
143
+                      <SwiperSlide key={item.orderId} onClick={() => goDispatch(item)}>
144
+                        {(item.personName || item.phone) + ' 于 ' + item.createDate + ' 下了一单请您尽快处理!'}
145
+                      </SwiperSlide>
146
+                    ))}
147
+                  </Swiper>
148
+              }
149
+
150
+            </Card>
151
+          </Col>
152
+        </Row>
153
+        <div className='flex bottom'>
154
+          <Card className='flex-1 card'>
155
+            <Bar h='300px' title='农机状态统计' opt={machineryStatus} />
156
+          </Card>
157
+          <Card className='flex-1 card'>
158
+            <PieArea opt={workAreaData} />
159
+          </Card>
160
+          <Card className='flex-1 card'>
161
+            <Pie opt={workData} />
162
+          </Card>
163
+        </div>
164
+      </div>
165
+    </PageContainer>
166
+  );
167
+};
168
+
169
+export default Welcome;

+ 226
- 94
src/pages/Welcome.jsx Bestand weergeven

@@ -1,73 +1,111 @@
1
-import React, { useState, useRef } from 'react';
1
+import React, { useState, useRef, useEffect } from 'react';
2 2
 import { PageContainer } from '@ant-design/pro-layout';
3 3
 import { Card, Row, Col } from 'antd';
4 4
 import { useIntl } from 'umi';
5
-import WCard from '@/components/WelcomeCard'
5
+import WCard from '@/components/WelcomeCard';
6 6
 import { Swiper, SwiperSlide } from 'swiper/react';
7 7
 import { Autoplay } from 'swiper';
8 8
 import 'swiper/css';
9 9
 import Bar from '@/components/Bar/index.jsx';
10
+import BarPerson from '@/components/BarPerson/index.jsx';
10 11
 import Pie from '@/components/Pie';
11 12
 import PieArea from '@/components/PieArea';
12 13
 import { history } from 'umi';
13
-import { getDispatchList } from '@/services/dispatch'
14
-import './Welcome.less'
15
-import { useEffect } from 'react';
14
+import { getDispatchList } from '@/services/dispatch';
15
+import {
16
+  getSummary2,
17
+  getAreaTotalOrg,
18
+  getDeviceTotalOrg,
19
+  getAreaTotalPerson,
20
+  getDeviceTotalPerson,
21
+} from '@/services/welcome';
22
+import './Welcome.less';
16 23
 
17 24
 const Welcome = () => {
18 25
   const intl = useIntl();
19
-  const topData = [
20
-    {
21
-      icon: 'icon-icon',
22
-      color: '#1cbbb4',
23
-      title: '注册用户',
24
-      value: 580239,
25
-      percentage: 32.6
26
-    },
27
-    {
28
-      icon: 'icon-show_gongsiguanli_fill',
29
-      color: '#8dc63f',
30
-      title: '合作社数',
31
-      value: 2017,
32
-      percentage: 5.6
33
-    },
34
-    {
35
-      icon: 'icon-tuolaji',
36
-      color: '#a5673f',
37
-      title: '农用机数',
38
-      value: 2000,
39
-      percentage: 42.6
40
-    },
41
-    {
42
-      icon: 'icon-dingdanguanli',
43
-      color: '#8799a3',
44
-      title: '订单数',
45
-      value: 2075994,
46
-      percentage: -1.6
47
-    },
48
-  ]
26
+  const [topData, setTopData] = useState([
27
+    // {
28
+    //   icon: 'icon-show_gongsiguanli_fill',
29
+    //   color: '#8dc63f',
30
+    //   title: '合作社',
31
+    //   value: 2017 + '个',
32
+    //   // percentage: 5.6,
33
+    // },
34
+    // {
35
+    //   icon: 'icon-icon',
36
+    //   color: '#1cbbb4',
37
+    //   title: '人员',
38
+    //   value: 580239 + '个',
39
+    //   // percentage: 32.6,
40
+    // },
41
+    // {
42
+    //   icon: 'icon-tuolaji',
43
+    //   color: '#a5673f',
44
+    //   title: '设备',
45
+    //   value: 2000 + '台',
46
+    //   // percentage: 42.6,
47
+    // },
48
+    // {
49
+    //   icon: 'icon-dingdanguanli',
50
+    //   color: '#8799a3',
51
+    //   title: '作业',
52
+    //   value: 2075994 + '亩',
53
+    //   // percentage: -1.6,
54
+    // },
55
+  ]);
56
+
57
+  const [categoryData, setCategoryData] = useState([]);
58
+  const [lineData, setLineData] = useState([]);
59
+  const [personData, setPersonData] = useState([]);
60
+  const [persondData, setPersDonData] = useState([]);
49 61
   const centerData = [
50 62
     {
51 63
       title: '预约订单',
52 64
       color: '#70d4d4',
53
-      keyList: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
54
-      valueList: [320, 332, 301, 334, 390, 88, 320, 332, 301, 334, 390, 88]
65
+      keyList: [
66
+        '一月',
67
+        '二月',
68
+        '三月',
69
+        '四月',
70
+        '五月',
71
+        '六月',
72
+        '七月',
73
+        '八月',
74
+        '九月',
75
+        '十月',
76
+        '十一月',
77
+        '十二月',
78
+      ],
79
+      valueList: [320, 332, 301, 334, 390, 88, 320, 332, 301, 334, 390, 88],
55 80
     },
56 81
     {
57 82
       title: '完成订单',
58 83
       color: '#c3b6e6',
59
-      keyList: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
60
-      valueList: [220, 182, 191, 234, 290, 256, 220, 182, 191, 234, 290, 356]
61
-    }
62
-  ]
84
+      keyList: [
85
+        '一月',
86
+        '二月',
87
+        '三月',
88
+        '四月',
89
+        '五月',
90
+        '六月',
91
+        '七月',
92
+        '八月',
93
+        '九月',
94
+        '十月',
95
+        '十一月',
96
+        '十二月',
97
+      ],
98
+      valueList: [220, 182, 191, 234, 290, 256, 220, 182, 191, 234, 290, 356],
99
+    },
100
+  ];
63 101
 
64 102
   const [machineryStatus, setMachineryStatus] = useState([
65 103
     {
66 104
       color: '#70d4d4',
67 105
       keyList: ['预约', '作业', '闲置', '离线', '维修'],
68 106
       valueList: [350, 900, 650, 180, 380],
69
-    }
70
-  ])
107
+    },
108
+  ]);
71 109
 
72 110
   const [workData, setWorkData] = useState([
73 111
     { name: '收割机', value: 35 },
@@ -81,86 +119,180 @@ const Welcome = () => {
81 119
     { name: '农药机', value: 650 },
82 120
     { name: '其他', value: 180 },
83 121
   ]);
84
-  const [dispatchList, setDispatchList] = useState([])
122
+  const [dispatchList, setDispatchList] = useState([]);
85 123
   const goDispatch = (val) => {
86 124
     history.push(`../OrderManage/dispatch.jsx?id=${val.orderId}`);
87
-  }
125
+  };
88 126
   useEffect(() => {
89 127
     getDispatchList({ isWarn: true, pageSize: 500 }).then((res) => {
90
-      setDispatchList(res.records)
91
-    })
92
-  }, [])
128
+      setDispatchList(res.records);
129
+    });
130
+  }, []);
131
+  // 卡片展示
132
+  useEffect(() => {
133
+    getSummary2().then((res) => {
134
+      const data = res.map((it) => {
135
+        return {
136
+          title:
137
+            it.name == 'person'
138
+              ? '人员'
139
+              : it.name == 'org'
140
+              ? '合作社'
141
+              : it.name == 'device'
142
+              ? '设备'
143
+              : '作业',
144
+          value:
145
+            it.name == 'person'
146
+              ? it.value + '个'
147
+              : it.name == 'org'
148
+              ? it.value + '个'
149
+              : it.name == 'device'
150
+              ? it.value + '台'
151
+              : it.value + '亩',
152
+          icon:
153
+            it.name == 'person'
154
+              ? 'icon-icon'
155
+              : it.name == 'org'
156
+              ? 'icon-show_gongsiguanli_fill'
157
+              : it.name == 'device'
158
+              ? 'icon-tuolaji'
159
+              : 'icon-dingdanguanli',
160
+          color:
161
+            it.name == 'person'
162
+              ? '#1cbbb4'
163
+              : it.name == 'org'
164
+              ? '#8dc63f'
165
+              : it.name == 'device'
166
+              ? '#a5673f'
167
+              : '#8799a3',
168
+        };
169
+      });
170
+      setTopData(data);
171
+    });
172
+  }, []);
173
+  // 柱状图展示亩
174
+  useEffect(() => {
175
+    getAreaTotalOrg().then((res) => {
176
+      setCategoryData(res);
177
+    });
178
+  }, []);
179
+
180
+  // 柱状图展示设备
181
+  useEffect(() => {
182
+    getDeviceTotalOrg().then((res) => {
183
+      setLineData(res);
184
+    });
185
+  }, []);
186
+
187
+  // 柱状图 人员作业统计
188
+
189
+  useEffect(() => {
190
+    getAreaTotalPerson().then((res) => {
191
+      setPersonData(res);
192
+    });
193
+  }, []);
194
+
195
+  // 柱状图 人员设备统计
196
+
197
+  useEffect(() => {
198
+    getDeviceTotalPerson().then((res) => {
199
+      setPersDonData(res);
200
+    });
201
+  }, []);
202
+
93 203
   return (
94 204
     <PageContainer>
95 205
       <div className="welcome">
96 206
         <div className="head">
97
-          <Row justify='space-between'>
98
-            <Col flex='320px'>
207
+          <Row justify="space-between">
208
+            <Col flex="320px">
99 209
               <WCard value={topData[0]} />
100 210
             </Col>
101
-            <Col flex='320px'>
211
+            <Col flex="320px">
102 212
               <WCard value={topData[1]} />
103 213
             </Col>
104
-            <Col flex='320px'>
214
+            <Col flex="320px">
105 215
               <WCard value={topData[2]} />
106 216
             </Col>
107
-            <Col flex='320px'>
217
+            <Col flex="320px">
108 218
               <WCard value={topData[3]} />
109 219
             </Col>
110 220
           </Row>
111 221
         </div>
112
-
113
-        <Row justify='space-between'>
114
-          <Col span={16}>
222
+        <Row justify="space-between">
223
+          <Col span={24}>
115 224
             <Card style={{ marginTop: '32px' }}>
116
-              <Bar h='500px' title='本年度预约订单数据概览' opt={centerData} />
225
+              <Bar h="500px" title="合作社数据统计" opt={categoryData} optL={lineData} />
117 226
             </Card>
118 227
           </Col>
119
-          <Col span={7} >
120
-            <Card title='待调度订单' style={{ marginTop: '32px', height: '548px' }} >
121
-              {
122
-                dispatchList.length <= 8 ?
123
-                  <div style={{ height: '448px', width: '100%' }}>
124
-                    {dispatchList.map(item =>
125
-                      <div style={{ height: '60px' }} key={item.orderId} onClick={() => goDispatch(item)} >
126
-                        {(item.personName || item.phone) + ' 于 ' + item.createDate + ' 下了一单请您尽快处理!'}
127
-                      </div>
128
-                    )}
129
-                  </div> :
130
-                  <Swiper
131
-                    height={60}
132
-                    style={{ height: '448px' }}
133
-                    autoplay={{
134
-                      delay: 1500,
135
-                      disableOnInteraction: false,
136
-                    }}
137
-                    loop
138
-                    loopAdditionalSlides={8}
139
-                    modules={[Autoplay]}
140
-                    direction="vertical"
141
-                  >
142
-                    {dispatchList.map((item) => (
143
-                      <SwiperSlide key={item.orderId} onClick={() => goDispatch(item)}>
144
-                        {(item.personName || item.phone) + ' 于 ' + item.createDate + ' 下了一单请您尽快处理!'}
145
-                      </SwiperSlide>
146
-                    ))}
147
-                  </Swiper>
148
-              }
149
-
228
+        </Row>
229
+        <Row justify="space-between">
230
+          <Col span={24}>
231
+            <Card style={{ marginTop: '32px' }}>
232
+              <BarPerson h="500px" title="人员数据统计" opt={personData} optP={persondData} />
150 233
             </Card>
151 234
           </Col>
152 235
         </Row>
153
-        <div className='flex bottom'>
154
-          <Card className='flex-1 card'>
155
-            <Bar h='300px' title='农机状态统计' opt={machineryStatus} />
236
+        {/* <Row justify="space-between">
237
+          <Col span={16}>
238
+            <Card style={{ marginTop: '32px' }}>
239
+              <Bar h="500px" title="本年度预约订单数据概览" opt={centerData} />
240
+            </Card>
241
+          </Col>
242
+          <Col span={7}>
243
+            <Card title="待调度订单" style={{ marginTop: '32px', height: '548px' }}>
244
+              {dispatchList.length <= 8 ? (
245
+                <div style={{ height: '448px', width: '100%' }}>
246
+                  {dispatchList.map((item) => (
247
+                    <div
248
+                      style={{ height: '60px' }}
249
+                      key={item.orderId}
250
+                      onClick={() => goDispatch(item)}
251
+                    >
252
+                      {(item.personName || item.phone) +
253
+                        ' 于 ' +
254
+                        item.createDate +
255
+                        ' 下了一单请您尽快处理!'}
256
+                    </div>
257
+                  ))}
258
+                </div>
259
+              ) : (
260
+                <Swiper
261
+                  height={60}
262
+                  style={{ height: '448px' }}
263
+                  autoplay={{
264
+                    delay: 1500,
265
+                    disableOnInteraction: false,
266
+                  }}
267
+                  loop
268
+                  loopAdditionalSlides={8}
269
+                  modules={[Autoplay]}
270
+                  direction="vertical"
271
+                >
272
+                  {dispatchList.map((item) => (
273
+                    <SwiperSlide key={item.orderId} onClick={() => goDispatch(item)}>
274
+                      {(item.personName || item.phone) +
275
+                        ' 于 ' +
276
+                        item.createDate +
277
+                        ' 下了一单请您尽快处理!'}
278
+                    </SwiperSlide>
279
+                  ))}
280
+                </Swiper>
281
+              )}
282
+            </Card>
283
+          </Col>
284
+        </Row> */}
285
+        {/* <div className="flex bottom">
286
+          <Card className="flex-1 card">
287
+            <Bar h="300px" title="农机状态统计" opt={machineryStatus} />
156 288
           </Card>
157
-          <Card className='flex-1 card'>
289
+          <Card className="flex-1 card">
158 290
             <PieArea opt={workAreaData} />
159 291
           </Card>
160
-          <Card className='flex-1 card'>
292
+          <Card className="flex-1 card">
161 293
             <Pie opt={workData} />
162 294
           </Card>
163
-        </div>
295
+        </div> */}
164 296
       </div>
165 297
     </PageContainer>
166 298
   );

+ 27
- 0
src/services/welcome.js Bestand weergeven

@@ -0,0 +1,27 @@
1
+import request from '@/utils/request';
2
+
3
+/*
4
+卡片数据展示*/
5
+export const getSummary2 = () => request('/summary2');
6
+
7
+/*
8
+柱状图数据展示 亩
9
+*/
10
+
11
+export const getAreaTotalOrg = () => request('/area-total-org');
12
+
13
+/*
14
+柱状图数据展示 设备
15
+*/
16
+export const getDeviceTotalOrg = () => request('/device-total-org');
17
+
18
+/*
19
+柱状图  人员作业统计
20
+*/
21
+
22
+export const getAreaTotalPerson = () => request('/area-total-person');
23
+/*
24
+柱状图 人员设备统计
25
+*/
26
+
27
+export const getDeviceTotalPerson = () => request('/device-total-person');