Procházet zdrojové kódy

Merge branch 'master' of http://git.ycjcjy.com/nanyang/machinery-admin

李志伟 před 3 roky
rodič
revize
8f8594d01e

+ 21
- 9
src/components/ECharts/index.jsx Zobrazit soubor

@@ -1,10 +1,11 @@
1
-import React, { useEffect, useRef } from 'react';
1
+import React, { forwardRef, useEffect, useRef, useImperativeHandle } from 'react';
2 2
 import classNames from 'classnames';
3
+// import * as echarts from 'echarts';
3 4
 // 按需导入模块
4 5
 // 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
5 6
 import * as echarts from 'echarts/core';
6 7
 // 引入图表,图表后缀都为 Chart
7
-import { LineChart } from 'echarts/charts';
8
+import { BarChart, PieChart } from 'echarts/charts';
8 9
 // 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
9 10
 import {
10 11
   TitleComponent,
@@ -12,11 +13,12 @@ import {
12 13
   GridComponent,
13 14
   DatasetComponent,
14 15
   TransformComponent,
16
+  LegendComponent,
15 17
 } from 'echarts/components';
16 18
 // 标签自动布局,全局过渡动画等特性
17 19
 import { LabelLayout, UniversalTransition } from 'echarts/features';
18 20
 // 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
19
-import { CanvasRenderer } from 'echarts/renderers';
21
+import { SVGRenderer } from 'echarts/renderers';
20 22
 
21 23
 // 注册必须的组件
22 24
 echarts.use([
@@ -25,21 +27,27 @@ echarts.use([
25 27
   GridComponent,
26 28
   DatasetComponent,
27 29
   TransformComponent,
28
-  LineChart,
30
+  BarChart,
31
+  PieChart,
29 32
   LabelLayout,
30 33
   UniversalTransition,
31
-  CanvasRenderer,
34
+  SVGRenderer,
35
+  LegendComponent,
32 36
 ]);
33 37
 
34 38
 import Styles from './style.less';
35 39
 
36
-export default (props) => {
40
+export default forwardRef((props, ref) => {
37 41
   const domRef = useRef();
38 42
   const echartsRef = useRef();
39 43
 
40 44
   useEffect(() => {
41 45
     echartsRef.current = echarts.init(domRef.current);
42
-    echartsRef.current.setOption(props.option);
46
+    window.onresize = function () {
47
+      echartsRef.current.resize();
48
+    };
49
+
50
+    return () => echartsRef.current.dispose();
43 51
   }, []);
44 52
 
45 53
   useEffect(() => {
@@ -58,7 +66,11 @@ export default (props) => {
58 66
     }
59 67
   }, [props.loading]);
60 68
 
61
-  const classList = classNames(Styles.echarts, props.className);
69
+  useImperativeHandle(ref, () => ({
70
+    echart: echartsRef,
71
+  }));
72
+
73
+  const classList = classNames(Styles.echart, props.className);
62 74
 
63 75
   return <div className={classList} ref={domRef} />;
64
-};
76
+});

+ 1
- 1
src/components/ECharts/style.less Zobrazit soubor

@@ -1,5 +1,5 @@
1 1
 .echart {
2 2
   width: 100%;
3 3
   height: 100%;
4
-  min-height: 400px;
4
+  min-height: 200px;
5 5
 }

+ 5
- 11
src/components/ScreenBox/SquareBox/index.jsx Zobrazit soubor

@@ -1,19 +1,13 @@
1
-
2
-
3
-import './style.less'
1
+import './style.less';
4 2
 export default (props) => {
5
-
6
-
7 3
   return (
8
-    <div className="SquareBox-box">
4
+    <div className="SquareBox-box" style={props.style}>
9 5
       <div className="border_corner border_corner_left_top" />
10 6
       <div className="border_corner border_corner_right_top" />
11 7
       <div className="border_corner border_corner_left_bottom" />
12 8
       <div className="border_corner border_corner_right_bottom" />
13 9
       {/* 内容 */}
14
-      <div className="SquareBox-body">
15
-        {props.children}
16
-      </div>
10
+      <div className="SquareBox-body">{props.children}</div>
17 11
     </div>
18
-  )
19
-}
12
+  );
13
+};

+ 3
- 1
src/components/ScreenBox/SquareBox/style.less Zobrazit soubor

@@ -1,8 +1,10 @@
1 1
 .SquareBox-box {
2 2
   position: relative;
3
+  height: 100%;
3 4
 }
4 5
 .SquareBox-body {
5
-  padding: 20px;
6
+  height: 100%;
7
+  padding: 0 20px;
6 8
   color: #fff;
7 9
   background: rgba(8, 40, 90, 0.4);
8 10
   border: 2px solid rgba(61, 129, 240, 0.5);

+ 7
- 6
src/components/ScreenBox/TitleBox/style.less Zobrazit soubor

@@ -1,23 +1,24 @@
1 1
 .TitleBox {
2
-  // width: 163px;
3 2
   display: inline-block;
4 3
   align-items: center;
4
+  height: 38px;
5 5
   margin-bottom: 10px;
6
-  padding: 11px 11px 9px 11px;
6
+  padding: 0 12px;
7
+  line-height: 38px;
7 8
   border-radius: 4px;
8 9
   box-shadow: 0px 0px 10px 0px #3d81f0 inset;
9 10
 
10 11
   .TitleBox-ListBox {
11 12
     display: inline-block;
12
-    width: 13px;
13
-    height: 13px;
14
-    margin-right: 10px;
13
+    width: 10px;
14
+    height: 10px;
15 15
     background: linear-gradient(0deg, #0c49c6, #3bd6e8);
16 16
   }
17 17
   .TitleBox-ListBox-value {
18
+    margin-left: 12px;
18 19
     color: transparent;
19 20
     font-weight: 800;
20
-    font-size: 17px;
21
+    font-size: 18px;
21 22
     background: linear-gradient(0deg, #0c49c6, #3bd6e8);
22 23
     background-clip: text;
23 24
   }

+ 20
- 0
src/global.less Zobrazit soubor

@@ -56,6 +56,26 @@ ol {
56 56
   }
57 57
 }
58 58
 
59
+.full-height {
60
+  height: 100%;
61
+}
62
+
63
+.flex {
64
+  display: flex;
65
+}
66
+
67
+.flex-column {
68
+  flex-direction: column;
69
+}
70
+
71
+.flex-0 {
72
+  flex: 0;
73
+}
74
+
75
+.flex-1 {
76
+  flex: 1;
77
+}
78
+
59 79
 .amap-marker-label {
60 80
   background: transparent;
61 81
   border: none;

+ 15
- 0
src/pages/MonitoringScreen/components/BasicChart.jsx Zobrazit soubor

@@ -0,0 +1,15 @@
1
+import React from 'react';
2
+import SquareBox from '@/components/ScreenBox/SquareBox';
3
+import TitleBox from '@/components/ScreenBox/TitleBox';
4
+import ECharts from '@/components/ECharts';
5
+
6
+export default (props) => {
7
+  return (
8
+    <div style={{ height: '100%' }}>
9
+      <TitleBox value={props.title} />
10
+      <SquareBox style={{ height: 'calc(100% - 48px)', minHeight: '200px', maxHeight: '350px' }}>
11
+        <ECharts option={props.option} />
12
+      </SquareBox>
13
+    </div>
14
+  );
15
+};

+ 5
- 0
src/pages/MonitoringScreen/components/ColorFont.jsx Zobrazit soubor

@@ -0,0 +1,5 @@
1
+import React from 'react';
2
+
3
+export default (props) => {
4
+  return <font color={props.color}>{props.children}</font>;
5
+};

+ 17
- 0
src/pages/MonitoringScreen/components/List/Item.jsx Zobrazit soubor

@@ -0,0 +1,17 @@
1
+import React from 'react';
2
+import classNames from 'classnames';
3
+import Styles from './style.less';
4
+
5
+export default (props) => {
6
+  const classList = classNames(Styles['screen-item'], {
7
+    [Styles['yellow-item']]: props.color !== 'green',
8
+    [Styles['green-item']]: props.color === 'green',
9
+  });
10
+
11
+  return (
12
+    <div className={classList}>
13
+      <div />
14
+      <div>{props.children}</div>
15
+    </div>
16
+  );
17
+};

+ 24
- 0
src/pages/MonitoringScreen/components/List/index.jsx Zobrazit soubor

@@ -0,0 +1,24 @@
1
+import React from 'react';
2
+import classNames from 'classnames';
3
+import Item from './Item';
4
+import Styles from './style.less';
5
+
6
+export default (props) => {
7
+  const { title, color, children } = props;
8
+
9
+  const classList = classNames(Styles['list-title'], {
10
+    [Styles['yellow-title']]: color !== 'green',
11
+    [Styles['green-title']]: color === 'green',
12
+  });
13
+
14
+  return (
15
+    <div className={Styles['screen-list']}>
16
+      <div className={classList}>
17
+        <div>{title}</div>
18
+      </div>
19
+      {React.Children.map(children, (child) => (
20
+        <Item color={color}>{child}</Item>
21
+      ))}
22
+    </div>
23
+  );
24
+};

+ 92
- 0
src/pages/MonitoringScreen/components/List/style.less Zobrazit soubor

@@ -0,0 +1,92 @@
1
+.screen-list {
2
+  .list-title {
3
+    position: relative;
4
+    padding: 0 20px;
5
+
6
+    & > div {
7
+      height: 48px;
8
+      color: #ffffff;
9
+      font-weight: bold;
10
+      font-size: 18px;
11
+      line-height: 48px;
12
+
13
+      background: linear-gradient(0deg, #ffcf84 0%, #fb9900 93.84765625%);
14
+      background-clip: text;
15
+      -webkit-text-fill-color: transparent;
16
+    }
17
+
18
+    &::before {
19
+      position: absolute;
20
+      top: 50%;
21
+      left: 0;
22
+      width: 10px;
23
+      height: 10px;
24
+      background: linear-gradient(0deg, #ffcf84, #fb9900);
25
+      transform: translateY(-50%);
26
+      content: ' ';
27
+    }
28
+  }
29
+
30
+  .yellow-title {
31
+    &::before {
32
+      background: linear-gradient(0deg, #ffcf84, #fb9900);
33
+    }
34
+  }
35
+
36
+  .green-title {
37
+    & > div {
38
+      background: linear-gradient(0deg, #9fffc5 0%, #44f68b 93.84765625%);
39
+      background-clip: text;
40
+      -webkit-text-fill-color: transparent;
41
+    }
42
+
43
+    &::before {
44
+      background: linear-gradient(0deg, #9fffc5, #44f68b);
45
+    }
46
+  }
47
+
48
+  .screen-item {
49
+    position: relative;
50
+    padding: 0 20px;
51
+
52
+    & > div {
53
+      height: 48px;
54
+      color: #fff;
55
+      font-size: 16px;
56
+      line-height: 48px;
57
+
58
+      &:first-child {
59
+        position: absolute;
60
+        top: 0;
61
+        left: 0;
62
+        width: 100%;
63
+        height: 100%;
64
+        background: linear-gradient(0deg, rgba(61, 129, 240, 0.24), rgba(61, 129, 240, 0));
65
+        opacity: 0.5;
66
+      }
67
+    }
68
+
69
+    &::before {
70
+      position: absolute;
71
+      top: 50%;
72
+      left: 0;
73
+      width: 4px;
74
+      height: 8px;
75
+      background: #fb9900;
76
+      transform: translateY(-40%);
77
+      content: ' ';
78
+    }
79
+  }
80
+
81
+  .yellow-item {
82
+    &::before {
83
+      background: #fb9900;
84
+    }
85
+  }
86
+
87
+  .green-item {
88
+    &::before {
89
+      background: #25e1aa;
90
+    }
91
+  }
92
+}

+ 76
- 0
src/pages/MonitoringScreen/components/MachineryStatus.jsx Zobrazit soubor

@@ -0,0 +1,76 @@
1
+import React, { useEffect, useMemo, useRef } from 'react';
2
+import * as echarts from 'echarts/core';
3
+import BasicChart from './BasicChart';
4
+import deepCopy from '@/utils/deepCopy';
5
+import { hex2Rgb } from '@/utils/color';
6
+
7
+const colorList = ['#FB9900', '#23E8AE', '#E63404', '#51D4FF', '#B8B2A9', '#C579FF'].map((x) => {
8
+  const rgb = hex2Rgb(x);
9
+  return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
10
+    {
11
+      offset: 0,
12
+      color: x, // 0% 处的颜色
13
+    },
14
+    {
15
+      offset: 0.5,
16
+      color: x, // 50% 处的颜色
17
+    },
18
+    {
19
+      offset: 1,
20
+      color: `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 0)`, // 100% 处的颜色
21
+    },
22
+  ]);
23
+});
24
+
25
+const defaultOpt = {
26
+  tooltip: {},
27
+  grid: {
28
+    left: 10,
29
+    containLabel: true,
30
+  },
31
+  xAxis: {
32
+    type: 'category',
33
+    splitLine: {
34
+      show: false,
35
+    },
36
+    axisTick: {
37
+      show: false,
38
+    },
39
+    axisLabel: {
40
+      color: '#fff',
41
+    },
42
+  },
43
+  yAxis: {
44
+    type: 'value',
45
+    splitLine: {
46
+      lineStyle: {
47
+        color: ['rgba(255, 255, 255, 0.1)'],
48
+        type: 'dashed',
49
+      },
50
+    },
51
+    axisTick: {
52
+      show: false,
53
+    },
54
+    axisLabel: {
55
+      color: '#fff',
56
+    },
57
+  },
58
+  series: [
59
+    {
60
+      type: 'bar',
61
+    },
62
+  ],
63
+};
64
+
65
+export default (props) => {
66
+  const option = useMemo(() => deepCopy(defaultOpt), []);
67
+  option.xAxis.data = props.source.map((x) => x.name);
68
+  option.series[0].data = props.source.map((x, i) => ({
69
+    value: x.value,
70
+    itemStyle: {
71
+      color: colorList[i % 6],
72
+    },
73
+  }));
74
+
75
+  return <BasicChart title="农机状态统计" option={option} />;
76
+};

+ 88
- 0
src/pages/MonitoringScreen/components/MachineryType.jsx Zobrazit soubor

@@ -0,0 +1,88 @@
1
+import React, { useMemo } from 'react';
2
+import * as echarts from 'echarts/core';
3
+import BasicChart from './BasicChart';
4
+import deepCopy from '@/utils/deepCopy';
5
+import { hex2Rgb } from '@/utils/color';
6
+
7
+const colorList = ['#FB9900', '#23E8AE', '#E63404'].map((x) => {
8
+  const rgb = hex2Rgb(x);
9
+  return new echarts.graphic.LinearGradient(0, 1, 1, 1, [
10
+    {
11
+      offset: 0,
12
+      color: `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 0)`, // 0% 处的颜色
13
+    },
14
+    {
15
+      offset: 0.5,
16
+      color: x, // 50% 处的颜色
17
+    },
18
+    {
19
+      offset: 1,
20
+      color: x, // 100% 处的颜色
21
+    },
22
+  ]);
23
+});
24
+
25
+const defaultOpt = {
26
+  tooltip: {},
27
+  legend: {},
28
+  grid: {
29
+    left: 10,
30
+    containLabel: true,
31
+  },
32
+  xAxis: {
33
+    type: 'value',
34
+    splitLine: {
35
+      show: false,
36
+    },
37
+    axisTick: {
38
+      show: false,
39
+    },
40
+    axisLabel: {
41
+      show: false,
42
+    },
43
+  },
44
+  yAxis: {
45
+    type: 'category',
46
+    axisLine: {
47
+      show: false,
48
+    },
49
+    axisTick: {
50
+      show: false,
51
+    },
52
+    axisLabel: {
53
+      color: '#fff',
54
+      width: 40,
55
+      overflow: 'truncate',
56
+    },
57
+  },
58
+  series: [
59
+    {
60
+      type: 'bar',
61
+      encode: {
62
+        x: 'value',
63
+        y: 'key',
64
+      },
65
+      label: {
66
+        show: true,
67
+        color: '#fff',
68
+        textBorderWidth: 0,
69
+        position: 'right',
70
+        // align: 'right',
71
+      },
72
+      showBackground: true,
73
+    },
74
+  ],
75
+};
76
+
77
+export default (props) => {
78
+  const option = useMemo(() => deepCopy(defaultOpt), []);
79
+  option.yAxis.data = props.source.map((x) => x.name);
80
+  option.series[0].data = props.source.map((x, i) => ({
81
+    value: x.value,
82
+    itemStyle: {
83
+      color: colorList[i % 3],
84
+    },
85
+  }));
86
+
87
+  return <BasicChart title="农机类型统计" option={option} />;
88
+};

+ 42
- 0
src/pages/MonitoringScreen/components/WorkArea.jsx Zobrazit soubor

@@ -0,0 +1,42 @@
1
+import React, { useEffect, useMemo, useRef } from 'react';
2
+import BasicChart from './BasicChart';
3
+import deepCopy from '@/utils/deepCopy';
4
+
5
+const defaultOpt = {
6
+  tooltip: {
7
+    trigger: 'item',
8
+    formatter: '{b} : {c} ({d}%)',
9
+  },
10
+  legend: {
11
+    orient: 'vertical',
12
+    left: 'right',
13
+    bottom: '5%',
14
+    textStyle: { color: '#fff' },
15
+  },
16
+  toolbox: {},
17
+  series: [
18
+    {
19
+      type: 'pie',
20
+      radius: ['30%', '60%'],
21
+      roseType: 'area',
22
+      itemStyle: {
23
+        borderRadius: 5,
24
+      },
25
+      label: {
26
+        color: '#fff',
27
+        formatter: '{b} \n{d}%',
28
+      },
29
+      // labelLine: {
30
+      //   length: 10,
31
+      //   length2: 36,
32
+      // },
33
+    },
34
+  ],
35
+};
36
+
37
+export default (props) => {
38
+  const option = useMemo(() => deepCopy(defaultOpt), []);
39
+  option.series[0].data = props.source;
40
+
41
+  return <BasicChart title="农机作业量面积统计" option={option} />;
42
+};

+ 53
- 0
src/pages/MonitoringScreen/components/WorkData.jsx Zobrazit soubor

@@ -0,0 +1,53 @@
1
+import React, { useEffect, useMemo, useRef } from 'react';
2
+import BasicChart from './BasicChart';
3
+import deepCopy from '@/utils/deepCopy';
4
+
5
+const defaultOpt = {
6
+  tooltip: {
7
+    trigger: 'item',
8
+    formatter: '{b} : {c} ({d}%)',
9
+  },
10
+  legend: {
11
+    orient: 'vertical',
12
+    left: 'left',
13
+    top: '5%',
14
+    textStyle: { color: '#fff' },
15
+  },
16
+  toolbox: {},
17
+  series: [
18
+    {
19
+      type: 'pie',
20
+      radius: ['30%', '60%'],
21
+      itemStyle: {
22
+        borderRadius: 5,
23
+      },
24
+      // itemStyle: {
25
+      //   borderRadius: 10,
26
+      //   borderColor: '#fff',
27
+      //   borderWidth: 1,
28
+      // },
29
+      label: {
30
+        show: false,
31
+        position: 'center',
32
+      },
33
+      emphasis: {
34
+        label: {
35
+          color: '#fff',
36
+          show: true,
37
+          fontSize: '28',
38
+          fontWeight: 'bold',
39
+        },
40
+      },
41
+      labelLine: {
42
+        show: false,
43
+      },
44
+    },
45
+  ],
46
+};
47
+
48
+export default (props) => {
49
+  const option = useMemo(() => deepCopy(defaultOpt), []);
50
+  option.series[0].data = props.source;
51
+
52
+  return <BasicChart title="农机作业数统计" option={option} />;
53
+};

+ 95
- 15
src/pages/MonitoringScreen/index.jsx Zobrazit soubor

@@ -7,24 +7,50 @@ import { FullscreenOutlined } from '@ant-design/icons';
7 7
 import { Button } from 'antd';
8 8
 import ScreenHeader from '@/components/ScreenBox/ScreenHeader';
9 9
 import GeoMap from '@/components/GeoMap';
10
+import StatisCard from '@/components/ScreenBox/StatisCard';
11
+import SquareBox from '@/components/ScreenBox/SquareBox';
10 12
 import { useFullScreen } from './hook';
11
-import DateCommponetsLeft from './DateCommponetsLeft';
12
-import DateCommponetsBottomRight from './DateCommponetsBottomRight';
13
-import DateCommponetsBottomLeft from './DateCommponetsBottomLeft';
13
+import MachineryType from './components/MachineryType';
14
+import MachineryStatus from './components/MachineryStatus';
14 15
 
16
+import WorkArea from './components/WorkArea';
17
+import List from './components/List';
18
+import ColorFont from './components/ColorFont';
19
+import WorkData from './components/WorkData';
15 20
 import Styles from './style.less';
16
-import StatisCard from '@/components/ScreenBox/StatisCard';
21
+
17 22
 export default (props) => {
18 23
   const screenRef = useRef();
19
-  const [height, setHeight] = useState('auto');
24
+  const [height, setHeight] = useState('1080px');
20 25
   const { isFullScreen, toggleFullScreen } = useFullScreen(screenRef);
21 26
 
22
-  useEffect(() => {
23
-    const container = document.querySelector('main.ant-layout-content');
24
-    const header = container.querySelector('.ant-pro-page-container-warp');
27
+  const [machineryTypeData, setMachineryTypeData] = useState([
28
+    { name: '收割机', value: 200 },
29
+    { name: '播种机', value: 100 },
30
+    { name: '农药机', value: 50 },
31
+  ]);
32
+
33
+  const [machineryStatusData, setMachineryStatusData] = useState([
34
+    { name: '预约', value: 350 },
35
+    { name: '作业', value: 900 },
36
+    { name: '闲置', value: 650 },
37
+    { name: '离线', value: 180 },
38
+    { name: '维修', value: 380 },
39
+  ]);
40
+
41
+  const [workData, setWorkData] = useState([
42
+    { name: '收割机', value: 35 },
43
+    { name: '播种机', value: 35 },
44
+    { name: '农药机', value: 30 },
45
+    { name: '其他', value: 180 },
46
+  ]);
25 47
 
26
-    setHeight(`${container.offsetHeight - header.offsetHeight}px`);
27
-  }, []);
48
+  const [workAreaData, setWorkAreaData] = useState([
49
+    { name: '收割机', value: 350 },
50
+    { name: '播种机', value: 900 },
51
+    { name: '农药机', value: 650 },
52
+    { name: '其他', value: 180 },
53
+  ]);
28 54
 
29 55
   return (
30 56
     <PageHeaderWrapper
@@ -45,9 +71,16 @@ export default (props) => {
45 71
           <div className={Styles['grail-header']}>
46 72
             <ScreenHeader weather="多云 21-28 °C" />
47 73
           </div>
48
-          <div className={classNames(Styles['grail-container'], Styles['pd-tp-40'])}>
74
+          <div className={classNames(Styles['grail-container'], Styles['pd-tp-30'])}>
49 75
             <div className={Styles['grail-left']}>
50
-              <DateCommponetsLeft />
76
+              <div className="flex flex-column full-height">
77
+                <div className="flex-0" style={{ height: '250px' }}>
78
+                  <MachineryType source={machineryTypeData} />
79
+                </div>
80
+                <div className="flex-1" style={{ marginTop: '30px' }}>
81
+                  <MachineryStatus source={machineryStatusData} />
82
+                </div>
83
+              </div>
51 84
             </div>
52 85
             <div className={classNames(Styles['grail-content'], Styles['pd-lr-40'])}>
53 86
               <div className={Styles['statis-container']}>
@@ -56,13 +89,60 @@ export default (props) => {
56 89
                 <StatisCard color="#F5CC5C" icon="icon3" value={168} title="总预约数(台)" />
57 90
                 <StatisCard color="#C579FF" icon="icon4" value={1568} title="总服务数(台)" />
58 91
               </div>
59
-              <GeoMap></GeoMap>
92
+              <GeoMap />
60 93
             </div>
61 94
             <div className={Styles['grail-right']}>
62
-              <DateCommponetsBottomRight />
95
+              <div className="flex flex-column full-height">
96
+                <div className="flex-0" style={{ height: '250px' }}>
97
+                  <WorkData source={workData} />
98
+                </div>
99
+                <div className="flex-1" style={{ marginTop: '30px' }}>
100
+                  <WorkArea source={workAreaData} />
101
+                </div>
102
+              </div>
63 103
             </div>
64 104
           </div>
65
-          <div className={classNames(Styles['grail-footer'], Styles['pd-tp-40'])}></div>
105
+          <div className={classNames(Styles['grail-footer'], Styles['pd-tp-30'])}>
106
+            <SquareBox>
107
+              <div className="flex">
108
+                <div className="flex-1">
109
+                  <List title="预约订单">
110
+                    <div>
111
+                      <ColorFont color="#F5CC5C">[快乐每一天]</ColorFont> 32s前预约了一台收割机,
112
+                      <ColorFont color="#44F68B">[收割机001]</ColorFont> 接到了此订单!
113
+                    </div>
114
+                    <div>
115
+                      <ColorFont color="#F5CC5C">[幸福人生]</ColorFont> 58分钟前预约了一台收割机,
116
+                      <ColorFont color="#44F68B">[播种机008]</ColorFont> 接到了此订单!尽快赶到!
117
+                    </div>
118
+                    <div>
119
+                      <ColorFont color="#F5CC5C">[灿烂人生]</ColorFont> 2个小时前预约了一台收割机,
120
+                      <ColorFont color="#44F68B">[收割机007]</ColorFont>{' '}
121
+                      接到了此订单!正在赶往目的地!
122
+                    </div>
123
+                  </List>
124
+                </div>
125
+                <div className={classNames('flex-0', Styles['footer-middle'])} />
126
+                <div className="flex-1">
127
+                  <List title="作业订单" color="green">
128
+                    <div>
129
+                      <ColorFont color="#44F68B">[收割机001]</ColorFont>
130
+                      32s前接到了一个订单,距离目的地还有3.2公里,请农户耐心等待!
131
+                    </div>
132
+                    <div>
133
+                      <ColorFont color="#44F68B">[播种机008]</ColorFont>{' '}
134
+                      2分钟前接到一个订单,距离目的地还有3.8公里,请农户耐心等待!
135
+                    </div>
136
+                    <div>
137
+                      <ColorFont color="#44F68B">[收割机007]</ColorFont>{' '}
138
+                      2个小时前接到一个订单,距离目的地还有3.8公里,请农户耐心等待!
139
+                    </div>
140
+                  </List>
141
+                </div>
142
+              </div>
143
+            </SquareBox>
144
+            <div className={Styles['pd-tp-30']} style={{ height: '30px' }} />
145
+          </div>
66 146
         </div>
67 147
       </div>
68 148
     </PageHeaderWrapper>

+ 11
- 2
src/pages/MonitoringScreen/style.less Zobrazit soubor

@@ -28,6 +28,7 @@
28 28
     .grail-container {
29 29
       display: flex;
30 30
       flex: 1;
31
+      align-items: stretch;
31 32
       height: 100%;
32 33
 
33 34
       .grail-left,
@@ -57,6 +58,14 @@
57 58
     display: flex;
58 59
     margin-bottom: 30px;
59 60
   }
61
+
62
+  .footer-middle {
63
+    width: 1px;
64
+    margin: 0 30px;
65
+    background: #03122a;
66
+    border: 1px solid #204a89;
67
+    opacity: 0.26;
68
+  }
60 69
 }
61 70
 
62 71
 .pd-lr-40 {
@@ -64,6 +73,6 @@
64 73
   padding-left: 40px;
65 74
 }
66 75
 
67
-.pd-tp-40 {
68
-  padding-top: 40px;
76
+.pd-tp-30 {
77
+  padding-top: 30px;
69 78
 }

+ 18
- 0
src/utils/color.js Zobrazit soubor

@@ -0,0 +1,18 @@
1
+export function hex2Rgb(hex) {
2
+  let color = hex.toLowerCase();
3
+
4
+  // 如果只有三位的值,需变成六位,如:#fff => #ffffff
5
+  if (color.length === 4) {
6
+    let colorNew = '#';
7
+    for (var i = 1; i < 4; i += 1) {
8
+      colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
9
+    }
10
+    color = colorNew;
11
+  }
12
+  // 处理六位的颜色值,转为RGB
13
+  const colors = [];
14
+  for (var i = 1; i < 7; i += 2) {
15
+    colors.push(parseInt('0x' + color.slice(i, i + 2)));
16
+  }
17
+  return colors;
18
+}

+ 12
- 0
src/utils/deepCopy.js Zobrazit soubor

@@ -0,0 +1,12 @@
1
+/**
2
+ * 极简版本的深拷贝
3
+ * @param {*} obj
4
+ * @returns
5
+ */
6
+export default function deepCopy(obj) {
7
+  let _obj = Array.isArray(obj) ? [] : {};
8
+  for (let i in obj) {
9
+    _obj[i] = typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i];
10
+  }
11
+  return _obj;
12
+}