Quellcode durchsuchen

Merge branch 'dev' of http://git.ycjcjy.com/ubpa/pc-admin into dev

李志伟 vor 3 Jahren
Ursprung
Commit
49ce3bff10

+ 2
- 1
package.json Datei anzeigen

@@ -48,7 +48,7 @@
48 48
   "dependencies": {
49 49
     "@amap/amap-jsapi-loader": "^1.0.1",
50 50
     "@ant-design/icons": "^4.7.0",
51
-    "@ant-design/pro-card": "^1.18.34",
51
+    "@ant-design/pro-card": "^1.20.2",
52 52
     "@ant-design/pro-descriptions": "^1.10.0",
53 53
     "@ant-design/pro-form": "^1.52.0",
54 54
     "@ant-design/pro-layout": "^6.32.0",
@@ -58,6 +58,7 @@
58 58
     "ali-oss": "^6.17.1",
59 59
     "antd": "^4.17.0",
60 60
     "classnames": "^2.3.0",
61
+    "echarts": "^5.3.2",
61 62
     "lodash": "^4.17.0",
62 63
     "md5": "^2.3.0",
63 64
     "moment": "^2.29.1",

+ 62
- 0
src/components/echart/echart.jsx Datei anzeigen

@@ -0,0 +1,62 @@
1
+import React, { useEffect, useRef } from 'react'
2
+// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
3
+import * as echarts from 'echarts/core';
4
+// 引入柱状图图表,图表后缀都为 Chart
5
+import { BarChart } from 'echarts/charts';
6
+// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
7
+import {
8
+  TitleComponent,
9
+  TooltipComponent,
10
+  GridComponent,
11
+  DatasetComponent,
12
+  TransformComponent,
13
+  DataZoomComponent,
14
+} from 'echarts/components';
15
+// 标签自动布局,全局过渡动画等特性
16
+import { LabelLayout, UniversalTransition } from 'echarts/features';
17
+// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
18
+import { CanvasRenderer } from 'echarts/renderers';
19
+
20
+// 注册必须的组件
21
+echarts.use([
22
+  TitleComponent,
23
+  TooltipComponent,
24
+  GridComponent,
25
+  DatasetComponent,
26
+  DataZoomComponent,
27
+  TransformComponent,
28
+  BarChart,
29
+  LabelLayout,
30
+  UniversalTransition,
31
+  CanvasRenderer
32
+]);
33
+
34
+export default (props) => {
35
+  const { className, style, option } = props
36
+
37
+  const chartRef = useRef()
38
+  const domRef = useRef()
39
+
40
+  const styleMerged = {
41
+    height: '100%',
42
+    ...style || {}
43
+  }
44
+
45
+  useEffect(() => {
46
+    chartRef.current = echarts.init(domRef.current)
47
+
48
+    return () => {
49
+      chartRef.current.dispose()
50
+    }
51
+  }, [])
52
+
53
+  useEffect(() => {
54
+    if (chartRef.current && option) {
55
+      chartRef.current.setOption(option)
56
+    }
57
+  }, [option])
58
+
59
+  return (
60
+    <div className={className} style={styleMerged} ref={domRef} />
61
+  )
62
+}

+ 111
- 0
src/pages/dashboard/components/BannerStatis.jsx Datei anzeigen

@@ -0,0 +1,111 @@
1
+import { useEffect, useState } from 'react';
2
+import { history } from 'umi';
3
+import { Card, Row, Col } from 'antd'
4
+import { AppstoreOutlined, MacCommandOutlined, TeamOutlined, UsergroupDeleteOutlined, UsergroupAddOutlined } from '@ant-design/icons'
5
+import { getcomm } from '@/services/comm';
6
+import StatisCard from './StatisCard';
7
+import StatisGroup from './StatisGroup';
8
+
9
+const colorList = [
10
+  { backColor: '#126BAE', frontColor: '#fff' },
11
+  { backColor: '#66A9C9', frontColor: '#fff' },
12
+  { backColor: '#08507b', frontColor: '#fff' },
13
+]
14
+
15
+export default (props) => {
16
+  const [cardData, setCardData] = useState({})
17
+  
18
+  const toAbnormal = () => {
19
+    history.push('../resume-work/abnormal');
20
+  }
21
+
22
+  useEffect(() => {
23
+    getcomm().then((res) => {
24
+      setCardData(res || {});
25
+    })
26
+  }, [])
27
+
28
+  const abnormalNum = (cardData.todayReportNum || 0) - (cardData.todayNormalNum || 0)
29
+
30
+  return (
31
+    <Row justify='space-around' gutter={24} >
32
+      <Col span={8}>
33
+        <StatisGroup
34
+          title="企业"
35
+          data1={{ title: '企业总数', value: cardData.orgTotalNum || 0 }}
36
+          data2={{ title: '无数据企业', value: cardData.noDataOrgNum || 0 }}
37
+          {...colorList[0]}
38
+          icon={<AppstoreOutlined />}
39
+        />
40
+      </Col>
41
+      <Col span={8}>
42
+        <StatisGroup
43
+          title="上报人次"
44
+          data1={{ title: '今日提交', value: cardData.todayReportNum || 0 }}
45
+          data2={{ title: '昨日提交', value: cardData.yestodayReportNum || 0 }}
46
+          {...colorList[1]}
47
+          icon={<TeamOutlined />}
48
+        />
49
+      </Col>
50
+      <Col span={8}>
51
+        <StatisGroup
52
+          title="今日概况"
53
+          data1={{ title: '正常人次', value: cardData.todayNormalNum || 0 }}
54
+          data2={{ title: '异常人次', value: abnormalNum }}
55
+          {...colorList[2]}
56
+          icon={<UsergroupDeleteOutlined />}
57
+          onClick2={toAbnormal}
58
+        />
59
+      </Col>
60
+      {/* <Col span={4}>
61
+        <StatisCard
62
+          title="企业总数"
63
+          value={cardData?.orgTotalNum || 0}
64
+          icon={<AppstoreOutlined />}
65
+          {...colorList[0]}
66
+        />
67
+      </Col>
68
+      <Col span={4}>
69
+        <StatisCard
70
+          title="无数据企业"
71
+          value={`${cardData?.noDataOrgNum || 0} / ${cardData?.orgTotalNum || 0}`}
72
+          icon={<MacCommandOutlined />}
73
+          {...colorList[1]}
74
+        />
75
+      </Col>
76
+      <Col span={4}>
77
+        <StatisCard
78
+          title="今日提交总人数"
79
+          value={cardData?.todayReportNum || 0}
80
+          icon={<TeamOutlined />}
81
+          {...colorList[2]}
82
+        />
83
+      </Col>
84
+      <Col span={4}>
85
+        <StatisCard
86
+          title="昨日提交总人数"
87
+          value={cardData?.yestodayReportNum || 0}
88
+          icon={<TeamOutlined />}
89
+          {...colorList[3]}
90
+        />
91
+      </Col>
92
+      <Col span={4}>
93
+        <StatisCard
94
+          title="今日正常人数"
95
+          value={cardData?.todayNormalNum || 0}
96
+          icon={<UsergroupDeleteOutlined />}
97
+          {...colorList[4]}
98
+        />
99
+      </Col>
100
+      <Col span={4}>
101
+        <StatisCard
102
+          title="今日异常人数"
103
+          value={(cardData?.todayReportNum || 0) - (cardData?.todayNormalNum || 0)}
104
+          icon={<UsergroupAddOutlined />}
105
+          {...colorList[5]}
106
+          onClick={toAbnormal}
107
+        />
108
+      </Col> */}
109
+    </Row>
110
+  )
111
+}

+ 0
- 131
src/pages/dashboard/components/OrgScollList/index.jsx Datei anzeigen

@@ -1,131 +0,0 @@
1
-import { Row, Col, List } from 'antd'
2
-import { useEffect, useState, useRef } from 'react';
3
-import moment from 'moment';
4
-
5
-import './style.less'
6
-
7
-export default (props) => {
8
-  const { list } = props
9
-  let scrollTimeout = null;
10
-  const [listHeight, setListHeight] = useState(0);
11
-  const [hoverState, setHoverState] = useState(false);
12
-  const scrollRef = useRef();
13
-  const formatterTime = (val) => {
14
-    return val ? moment(val).format('YYYY-MM-DD HH:mm') : '';
15
-  };
16
-  const computeHeight = () => {
17
-    scrollTimeout = setTimeout(() => {
18
-      setListHeight(scrollRef.current && scrollRef.current.offsetHeight || 0)
19
-    }, 0)
20
-  };
21
-  useEffect(() => {
22
-    if (list != []) {
23
-      computeHeight()
24
-    }
25
-  }, [list])
26
-
27
-  return (
28
-    <>
29
-      <Row>
30
-        <Col span={8} align='center'>
31
-          <span className='tableHead'>企业名称</span>
32
-        </Col>
33
-        <Col span={8} align='center'>
34
-          <span className='tableHead'>创建时间</span>
35
-        </Col>
36
-        <Col span={8} align='center'>
37
-          <span className='tableHead'>历史最多人次</span>
38
-        </Col>
39
-      </Row>
40
-      {
41
-        list?.length > 12 ?
42
-          <div
43
-            className={listHeight > 200 ? 'scroll' : ''}
44
-            style={{ marginLeft: '10px', marginTop: '20px' }}
45
-            onMouseEnter={() => setHoverState(true)}
46
-            onMouseLeave={() => setHoverState(false)}
47
-          >
48
-            <div className={`scroll-list ${hoverState ? 'hover' : ''}`}
49
-              style={{ animationDuration: `${list.length}s` }}
50
-              ref={scrollRef}>
51
-              <List
52
-                id="scrollList"
53
-                dataSource={list}
54
-                renderItem={(item, index) => (
55
-                  <List.Item>
56
-                    <Row style={{ width: '100%' }}>
57
-                      <Col span={8}>
58
-                        {item.orgName}
59
-                      </Col>
60
-                      <Col span={8} align='center'>
61
-                        {formatterTime(item.createDate)}
62
-                      </Col>
63
-                      <Col span={8} align='center'>
64
-                        {item.totalReportNum || <span style={{ color: 'red' }} >0</span>}
65
-                      </Col>
66
-                    </Row>
67
-                  </List.Item>
68
-                )}
69
-              />
70
-            </div>
71
-            {
72
-              list.length > 2 &&
73
-              <div
74
-                className={`scroll-list ${hoverState ? 'hover' : ''}`}
75
-                style={{ animationDuration: `${list.length}s` }}
76
-                ref={scrollRef}>
77
-                <List
78
-                  dataSource={list}
79
-                  renderItem={(item, index) => (
80
-                    <List.Item>
81
-                      <Row style={{ width: '100%' }}>
82
-                        <Col span={8}>
83
-                          {item.orgName}
84
-                        </Col>
85
-                        <Col span={8} align='center'>
86
-                          {formatterTime(item.createDate)}
87
-                        </Col>
88
-                        <Col span={8} align='center'>
89
-                          {item.totalReportNum || <span style={{ color: 'red' }} >0</span>}
90
-                        </Col>
91
-                      </Row>
92
-                    </List.Item>
93
-                  )}
94
-                />
95
-              </div>
96
-            }
97
-          </div>
98
-          : list?.length > 0 &&
99
-          <div
100
-            style={{ marginLeft: '10px', marginTop: '20px' }}
101
-            onMouseEnter={() => setHoverState(true)}
102
-            onMouseLeave={() => setHoverState(false)}
103
-          >
104
-            <div className={`scroll-list`}
105
-              style={{ animationDuration: `${list.length}s` }}
106
-              ref={scrollRef}>
107
-              <List
108
-                id="scrollList"
109
-                dataSource={list}
110
-                renderItem={(item, index) => (
111
-                  <List.Item>
112
-                    <Row style={{ width: '100%' }}>
113
-                      <Col span={8}>
114
-                        {item.orgName}
115
-                      </Col>
116
-                      <Col span={8} align='center'>
117
-                        {formatterTime(item.createDate)}
118
-                      </Col>
119
-                      <Col span={8} align='center'>
120
-                        {item.totalReportNum || <span style={{ color: 'red' }} >0</span>}
121
-                      </Col>
122
-                    </Row>
123
-                  </List.Item>
124
-                )}
125
-              />
126
-            </div>
127
-          </div>
128
-      }
129
-    </>
130
-  )
131
-}

+ 0
- 26
src/pages/dashboard/components/OrgScollList/style.less Datei anzeigen

@@ -1,26 +0,0 @@
1
-.scroll {
2
-  height: 600px;  
3
-  overflow: hidden;  
4
-  .scroll-list {  
5
-    animation: moveup 7s linear infinite normal;
6
-
7
-    // 动画名称 执行时间 动画方式: 匀速 动画次数:无限次infinite 动画方向
8
-
9
-    &.hover {  
10
-      animation-play-state: paused;  
11
-    }  
12
-  }  
13
-}  
14
-
15
-@keyframes moveup {  
16
-  0% {  
17
-    transform: translateY(0);  
18
-  }  
19
-  100% {  
20
-    transform: translateY(-100%);  
21
-  }  
22
-}
23
-
24
-.tableHead{
25
-  color: rgb(40, 165, 255);
26
-}

+ 103
- 0
src/pages/dashboard/components/OrgSummary.jsx Datei anzeigen

@@ -0,0 +1,103 @@
1
+import { useEffect, useState, useCallback } from 'react';
2
+import Echart from '@/components/echart/echart'
3
+import { Card } from 'antd'
4
+import { getList } from '@/services/org'
5
+
6
+const barOption = {
7
+  color: ['#08507b'],
8
+  tooltip: {
9
+    trigger: 'axis',
10
+    axisPointer: {
11
+      type: 'shadow'
12
+    },
13
+    formatter: (params) => `人次: ${params[0].data.totalReportNum || 0}`
14
+  },
15
+  grid: {
16
+    containLabel: true,
17
+    left: 0,
18
+    top: 0,
19
+    right: 60,
20
+    bottom: 0,
21
+  }, 
22
+  yAxis: {
23
+    type: 'category',
24
+    axisLabel: {
25
+      // rotate: 45,
26
+      formatter: (value) => value.length > 10 ? value.substring(0, 10) + '...' : value,
27
+      color: (value, index) => 'black'
28
+    },
29
+  },
30
+  xAxis: {
31
+    type: 'value',
32
+  },
33
+  dataZoom: [
34
+    {
35
+      type: 'slider',
36
+      yAxisIndex: [0],
37
+      start: 100,
38
+      end: 80,
39
+      // width: 10,
40
+      // fillerColor: '#08507b',
41
+      selectedDataBackground: {
42
+        areaStyle: { color: '#08507b', },
43
+        lineStyle: { color: '#08507b', width: 1 },
44
+      }
45
+    },
46
+    {
47
+      type: 'inside',
48
+      yAxisIndex: [0],
49
+      start: 100,
50
+      end: 80
51
+    }
52
+  ],
53
+  dataset: {
54
+    dimensions: ['orgName', 'totalReportNum'],
55
+    source: [],
56
+  },
57
+  series: [
58
+    {
59
+      type: 'bar',
60
+    },
61
+  ]
62
+}
63
+
64
+export default (props) => {
65
+  const [loading, setLoading] = useState(false)
66
+  const [list, setList] = useState([])
67
+
68
+  const option = {
69
+    ...barOption,
70
+    dataset: {
71
+      ...barOption.dataset,
72
+      source: list
73
+    },
74
+    yAxis: {
75
+      ...barOption.yAxis,
76
+      axisLabel: {
77
+        ...barOption.yAxis.axisLabel,
78
+        color: value => list.filter(x => x.orgName === value)[0].totalReportNum ? 'black' : 'red'
79
+      }
80
+    }
81
+  }
82
+  
83
+  const queryList = useCallback(() => {
84
+    setLoading(true)
85
+
86
+    getList({ pageSize: 500, qType: 'statis' }).then((res) => {
87
+      setLoading(false)
88
+      setList((res.records || []).reverse())
89
+    }).catch(err => {
90
+      setLoading(false)
91
+    })
92
+  }, [])
93
+  
94
+  useEffect(() => {
95
+    queryList()
96
+  }, [])
97
+
98
+  return (
99
+    <Card title='企业数据总览' loading={loading} bodyStyle={{height: 600}}>
100
+      <Echart option={option} />
101
+    </Card>
102
+  )
103
+}

+ 113
- 0
src/pages/dashboard/components/ReportList.jsx Datei anzeigen

@@ -0,0 +1,113 @@
1
+import moment from 'moment'
2
+import { Card, List, Badge, Space, Carousel } from 'antd'
3
+import { useCallback, useEffect, useMemo, useState } from 'react'
4
+import { getList } from '@/services/work'
5
+import { random } from '@/utils/number'
6
+
7
+const colorList = [
8
+  '#a8071a',
9
+  '#ad2102',
10
+  '#ad4e00',
11
+  '#ad6800',
12
+  '#ad8b00',
13
+  '#5b8c00',
14
+  '#237804',
15
+  '#006d75',
16
+  '#0050b3',
17
+  '#10239e',
18
+  '#391085',
19
+  '#9e1068',
20
+]
21
+
22
+const Avatar = (props) => {
23
+  const style = useMemo(() => {
24
+    let r = random(0, colorList.length)
25
+    if (r >= 12) r = 0;
26
+    const color = colorList[r];
27
+
28
+    return {
29
+      background: color,
30
+      color: '#fff',
31
+      width: '48px',
32
+      height: '48px',
33
+      fontSize: '1.8em',
34
+      lineHeight: '48px',
35
+      textAlign: 'center',
36
+    }
37
+  }, [])
38
+
39
+  return <div style={style}>{props.children}</div>
40
+}
41
+
42
+
43
+const Content = (props) => {
44
+  const { item } = props;
45
+
46
+  const abnormal = item.antigenIsNormal === 0 || item.nucleicIsNormal === 0
47
+  const status = abnormal ? 'error' : 'success'
48
+
49
+  return (
50
+    <Space size="large">
51
+      <span><Badge status={status} /> { abnormal ? '异常' : '正常' }</span>
52
+      <span>{moment(item.createDate).format('HH:mm')}</span>
53
+    </Space>
54
+  )
55
+}
56
+
57
+export default (props) => {
58
+  const [loading, setLoading] = useState(false)
59
+  const [list, setList] = useState([])
60
+
61
+  const queryList = useCallback(() => {
62
+    setLoading(true)
63
+    getList(
64
+      {
65
+        pageSize: 50, // 过多会很卡
66
+        start: moment().format('YYYY-MM-DD'),
67
+        end: moment().format('YYYY-MM-DD'),
68
+        isAll: true
69
+      }).then(res => {
70
+        setLoading(false)
71
+        setList((res.records || []).reverse())
72
+      }).catch(er => {
73
+        setLoading(false)
74
+      })
75
+  }, [])
76
+
77
+  useEffect(() => {
78
+    queryList()
79
+  }, [])
80
+
81
+  return (
82
+    <Card title="今日提交记录" loading={loading} bodyStyle={{ height: '600px' }}>
83
+      <List style={{ height: '100%', overflow: 'hidden' }} itemLayout="horizontal">
84
+        <Carousel
85
+          autoplay
86
+          infinite
87
+          rtl
88
+          slidesToShow={8}
89
+          slidesToScroll={1}
90
+          dot={false}
91
+          dotPosition="right"
92
+          style={{ height: '100%' }}
93
+        >
94
+          {
95
+            list.map(item => (
96
+              <div key={item.formId} style={{ display: 'flex' }}>
97
+                <List.Item>
98
+                  <List.Item.Meta
99
+                    avatar={<Avatar>{item.orgName.substring(0,1)}</Avatar>}
100
+                    title={item.userName}
101
+                    con
102
+                    description={item.orgName}
103
+                  />
104
+                  <Content item={item} />
105
+                </List.Item>
106
+              </div>
107
+            ))
108
+          }
109
+        </Carousel>
110
+      </List>
111
+    </Card>
112
+  )
113
+}

+ 0
- 131
src/pages/dashboard/components/ResumeWorkScollList/index.jsx Datei anzeigen

@@ -1,131 +0,0 @@
1
-import { Row, Col, List } from 'antd'
2
-import { useEffect, useState, useRef } from 'react';
3
-import moment from 'moment';
4
-
5
-import './style.less'
6
-
7
-export default (props) => {
8
-  const { list } = props
9
-  let scrollTimeout = null;
10
-  const [listHeight, setListHeight] = useState(0);
11
-  const [hoverState, setHoverState] = useState(false);
12
-  const scrollRef = useRef();
13
-  const formatterTime = (val) => {
14
-    return val ? moment(val).format('YYYY-MM-DD HH:mm') : '';
15
-  };
16
-  const computeHeight = () => {
17
-    scrollTimeout = setTimeout(() => {
18
-      setListHeight(scrollRef.current && scrollRef.current.offsetHeight || 0)
19
-    }, 0)
20
-  };
21
-  useEffect(() => {
22
-    if (list != []) {
23
-      computeHeight()
24
-    }
25
-  }, [list])
26
-
27
-  return (
28
-    <>
29
-      <Row>
30
-        <Col span={8} align='center'>
31
-          <span className='tableHead'>企业名称</span>
32
-        </Col>
33
-        <Col span={8} align='center'>
34
-          <span className='tableHead'>姓名</span>
35
-        </Col>
36
-        <Col span={8} align='center'>
37
-          <span className='tableHead'>申请时间</span>
38
-        </Col>
39
-      </Row>
40
-      {list?.length > 12 ?
41
-        <div
42
-          className={listHeight > 200 ? 'scroll' : ''}
43
-          style={{ marginLeft: '10px', marginTop: '20px' }}
44
-          onMouseEnter={() => setHoverState(true)}
45
-          onMouseLeave={() => setHoverState(false)}
46
-        >
47
-          <div className={`scroll-list ${hoverState ? 'hover' : ''}`}
48
-            style={{ animationDuration: `${list.length}s` }}
49
-            ref={scrollRef}>
50
-            <List
51
-              id="scrollList"
52
-              dataSource={list}
53
-              renderItem={(item, index) => (
54
-                <List.Item>
55
-                  <Row style={{ width: '100%' }}>
56
-                    <Col span={8}>
57
-                      {item.orgName}
58
-                    </Col>
59
-                    <Col span={8} align='center'>
60
-                      {item.userName}
61
-                    </Col>
62
-                    <Col span={8} align='center'>
63
-                      {formatterTime(item.createDate)}
64
-                    </Col>
65
-                  </Row>
66
-                </List.Item>
67
-              )}
68
-            />
69
-          </div>
70
-          {
71
-            list.length > 2 &&
72
-            <div
73
-              className={`scroll-list ${hoverState ? 'hover' : ''}`}
74
-              style={{ animationDuration: `${list.length}s` }}
75
-              ref={scrollRef}>
76
-              <List
77
-                dataSource={list}
78
-                renderItem={(item, index) => (
79
-                  <List.Item>
80
-                    <Row style={{ width: '100%' }}>
81
-                      <Col span={8}>
82
-                        {item.orgName}
83
-                      </Col>
84
-                      <Col span={8} align='center'>
85
-                        {item.userName}
86
-                      </Col>
87
-                      <Col span={8} align='center'>
88
-                        {formatterTime(item.createDate)}
89
-                      </Col>
90
-                    </Row>
91
-                  </List.Item>
92
-                )}
93
-              />
94
-            </div>
95
-          }
96
-        </div>
97
-        : list?.length > 0 &&
98
-        <div
99
-          style={{ marginLeft: '10px', marginTop: '20px' }}
100
-          onMouseEnter={() => setHoverState(true)}
101
-          onMouseLeave={() => setHoverState(false)}
102
-        >
103
-          <div className={`scroll-list`}
104
-            style={{ animationDuration: `${list.length}s` }}
105
-            ref={scrollRef}>
106
-            <List
107
-              id="scrollList"
108
-              dataSource={list}
109
-              renderItem={(item, index) => (
110
-                <List.Item>
111
-                  <Row style={{ width: '100%' }}>
112
-                    <Col span={8}>
113
-                      {item.orgName}
114
-                    </Col>
115
-                    <Col span={8} align='center'>
116
-                      {item.userName}
117
-                    </Col>
118
-                    <Col span={8} align='center'>
119
-                      {formatterTime(item.createDate)}
120
-                    </Col>
121
-                  </Row>
122
-                </List.Item>
123
-              )}
124
-            />
125
-          </div>
126
-        </div>
127
-
128
-      }
129
-    </>
130
-  )
131
-}

+ 0
- 26
src/pages/dashboard/components/ResumeWorkScollList/style.less Datei anzeigen

@@ -1,26 +0,0 @@
1
-.scroll {
2
-  height: 600px;  
3
-  overflow: hidden;  
4
-  .scroll-list {  
5
-    animation: moveup 7s linear infinite normal;
6
-
7
-    // 动画名称 执行时间 动画方式: 匀速 动画次数:无限次infinite 动画方向
8
-
9
-    &.hover {  
10
-      animation-play-state: paused;  
11
-    }  
12
-  }  
13
-}  
14
-
15
-@keyframes moveup {  
16
-  0% {  
17
-    transform: translateY(0);  
18
-  }  
19
-  100% {  
20
-    transform: translateY(-100%);  
21
-  }  
22
-}
23
-
24
-.tableHead{
25
-  color: rgb(40, 165, 255);
26
-}

+ 41
- 0
src/pages/dashboard/components/StatisCard.jsx Datei anzeigen

@@ -0,0 +1,41 @@
1
+import React from 'react'
2
+import { Statistic, Card } from 'antd';
3
+
4
+const iconDivStyle = {
5
+  position: 'absolute',
6
+  top: 20,
7
+  right: 20,
8
+}
9
+
10
+const iconStyle = {
11
+  fontSize: '5em',
12
+  color: '#fff',
13
+  opacity: 0.3,
14
+}
15
+
16
+export default (props) => {
17
+  const { title, value, icon, backColor = '#fff', frontColor='#000', onClick } = props
18
+
19
+  const bodyStyle = {
20
+    background: backColor,
21
+    overflow: 'hidden',
22
+    position: 'relative',
23
+  }
24
+
25
+  return (
26
+    <Card bodyStyle={bodyStyle} onClick={onClick}>
27
+      <Statistic
28
+        title={title}
29
+        value={value}
30
+        valueStyle={{ color: frontColor }}
31
+      />
32
+      {
33
+        icon && (
34
+          <div style={iconDivStyle}>
35
+            {React.cloneElement(icon, { style: iconStyle })}
36
+          </div>
37
+        )
38
+      }
39
+    </Card>
40
+  )
41
+}

+ 74
- 0
src/pages/dashboard/components/StatisGroup.jsx Datei anzeigen

@@ -0,0 +1,74 @@
1
+import React, { useState } from 'react';
2
+import { StatisticCard } from '@ant-design/pro-card';
3
+
4
+const { Divider } = StatisticCard;
5
+const iconDivStyle = {
6
+  position: 'absolute',
7
+  top: '4px',
8
+  right: '-30px',
9
+}
10
+
11
+const iconStyle = {
12
+  fontSize: '10em',
13
+  color: '#fff',
14
+  opacity: 0.45,
15
+}
16
+
17
+export default (props) => {
18
+  const { title, data1, data2, icon, onClick1, onClick2, backColor = '#fff', frontColor='#000' } = props
19
+
20
+  const headStyle = {
21
+    background: backColor,
22
+    color: frontColor,
23
+  }
24
+
25
+  const bodyStyle = {
26
+    background: backColor,
27
+    color: frontColor,
28
+    position: 'relative',
29
+    overflow: 'hidden',
30
+  }
31
+
32
+  const groupBodyStyle = {
33
+    ...bodyStyle,
34
+    padding: 0,
35
+  }
36
+
37
+  const valueStyle = {
38
+    color: frontColor
39
+  }
40
+
41
+  const headTitleStyle = {
42
+    color: frontColor,
43
+    fontSize: '19px',
44
+    fontWeight: 700,
45
+    letterSpacing: '2px',
46
+  }
47
+
48
+  const titleStyle = {
49
+    color: frontColor,
50
+  }
51
+
52
+  return (
53
+    <StatisticCard.Group title={<div style={headTitleStyle}>{title}</div>} headStyle={headStyle} bodyStyle={groupBodyStyle}>
54
+      <StatisticCard
55
+        bodyStyle={bodyStyle}
56
+        statistic={{ ...data1, title: (<div style={titleStyle}>{data1.title}</div>), valueStyle }}
57
+        onClick={onClick1}
58
+      />
59
+      <Divider type="vertical" />
60
+      <StatisticCard
61
+        bodyStyle={bodyStyle}
62
+        statistic={{ ...data2, title: (<div style={titleStyle}>{data2.title}</div>), valueStyle }}
63
+        onClick={onClick2}
64
+      />
65
+      {
66
+        icon && (
67
+          <div style={iconDivStyle}>
68
+            {React.cloneElement(icon, { style: iconStyle })}
69
+          </div>
70
+        )
71
+      }
72
+    </StatisticCard.Group>
73
+  )
74
+}

+ 13
- 133
src/pages/dashboard/index.jsx Datei anzeigen

@@ -1,140 +1,20 @@
1
-import { useEffect, useState } from 'react';
2
-import { Card, Row, Col, Empty } from 'antd'
3
-import { PageHeaderWrapper } from '@ant-design/pro-layout';
4
-import moment from 'moment';
5
-import { history } from 'umi';
6
-import { getList as getOrgList } from '@/services/org'
7
-import { getList as getResumeWorkList } from '@/services/work'
8
-import { getcomm } from '@/services/comm';
9
-import ResumeWorkScollList from './components/ResumeWorkScollList';
10
-import OrgScollList from './components/OrgScollList';
11
-import './style.less'
1
+import React from 'react';
2
+import { Space, Row, Col } from 'antd'
3
+import ReportList from './components/ReportList';
4
+import OrgSummary from './components/OrgSummary';
5
+import BannerStatis from './components/BannerStatis';
12 6
 
13
-export default (props) => {
14
-  const [cardData, setCardData] = useState()
15
-  const [orgList, setOrgList] = useState([])
16
-  const [resumeWorkList, setResumeWorkList] = useState([])
17
-  const nowDate = () => {
18
-    var strArray = moment(Date.now()).format('YYYY/MM/DD').split("/");
19
-    strArray = strArray.map(function (val) {
20
-      if (val[0] == "0") {
21
-        return val.slice(1);
22
-      } else {
23
-        return val;
24
-      }
25
-    });
26
-    return strArray.join("/");
27
-  }
28
-  const header = (
29
-    <Row justify='space-between' align='middle' >
30
-      <Col span={2}>
31
-        <img src="./wordLogo.png" />
32
-      </Col>
33
-      <Col style={{ fontSize: '24px', fontWeight: 'bold' }}>ubpa-疫情防控管理平台</Col>
34
-      <Col span={2} style={{ textAlign: 'right' }}>{nowDate()}</Col>
35
-    </Row>
36
-  )
37
-  const goDashboard=()=>{
38
-    history.push('../resume-work/abnormal');
39
-  }
40
-
41
-  useEffect(() => {
42
-    getcomm().then((res) => {
43
-      setCardData(res);
44
-    })
45
-    getOrgList({ pageSize: 500 }).then((res) => {
46
-      setOrgList(res.records)
47
-    })
48
-    getResumeWorkList(
49
-      {
50
-        pageSize: 500,
51
-        start: moment(Date.now()).format('YYYY-MM-DD'),
52
-        end: moment(Date.now()).format('YYYY-MM-DD'),
53
-        isAll: true
54
-      }).then(res => {
55
-        setResumeWorkList(res.records)
56
-      })
57
-  }, [])
7
+export default (props) => {  
58 8
   return (
59
-    <PageHeaderWrapper content={header} className='dashboardPage'>
60
-      <Row justify='space-around' >
61
-        <Col span={4}>
62
-          <Card className='dashboardCard'>
63
-            <div>
64
-              企业总数
65
-            </div>
66
-            <div className='amount'>
67
-              {cardData?.orgTotalNum || 0}
68
-            </div>
69
-          </Card>
70
-          <Card className='dashboardCard' style={{ marginTop: '24px' }}>
71
-            <div>
72
-              无数据企业
73
-            </div>
74
-            <div className='amount'>
75
-              {cardData?.noDataOrgNum || 0}/{cardData?.orgTotalNum || 0}
76
-            </div>
77
-          </Card>
78
-        </Col>
79
-        <Col span={4}>
80
-          <Card className='dashboardCard'>
81
-            <div>
82
-              今日提交总人数
83
-            </div>
84
-            <div className='amount'>
85
-              {cardData?.todayReportNum || 0}
86
-            </div>
87
-          </Card>
88
-          <Card className='dashboardCard' style={{ marginTop: '24px' }}>
89
-            <div>
90
-              昨日提交总人数
91
-            </div>
92
-            <div className='amount'>
93
-              {cardData?.yestodayReportNum || 0}
94
-            </div>
95
-          </Card>
96
-        </Col>
97
-        <Col span={4}>
98
-          <Card className='dashboardCard'>
99
-            <div>
100
-              今日正常人数
101
-            </div>
102
-            <div className='amount' style={{ color: 'green' }}>
103
-              {cardData?.todayNormalNum || 0}
104
-            </div>
105
-          </Card>
106
-          <Card className='dashboardCard' style={{ marginTop: '24px' }} onClick={goDashboard}>
107
-            <div>
108
-              今日异常人数
109
-            </div>
110
-            <div className='amount' style={{ color: 'red' }}>
111
-              {(cardData?.todayReportNum || 0) - (cardData?.todayNormalNum || 0)}
112
-            </div>
113
-          </Card>
114
-        </Col>
115
-      </Row>
116
-      <Row>
117
-        <Col span={12}>
118
-          <Card style={{ marginTop: '16px', height: '736px' }} title='企业数据总览'>
119
-            {orgList != [] ?
120
-              <OrgScollList list={orgList} /> :
121
-              <div style={{ height: '624px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
122
-                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
123
-              </div>
124
-            }
125
-          </Card>
126
-        </Col>
9
+    <Space direction="vertical" size="large" style={{ width: '100%' }}>
10
+      <BannerStatis />
11
+
12
+      <Row gutter={24}>
13
+        <Col span={12}><OrgSummary /></Col>
127 14
         <Col span={12}>
128
-          <Card style={{ marginTop: '16px', height: '736px' }} title='今日数据提交记录'>
129
-            {resumeWorkList != [] ?
130
-              <ResumeWorkScollList list={resumeWorkList} /> :
131
-              <div style={{ height: '624px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
132
-                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
133
-              </div>
134
-            }
135
-          </Card>
15
+          <ReportList />
136 16
         </Col>
137 17
       </Row>
138
-    </PageHeaderWrapper>
18
+    </Space>
139 19
   )
140 20
 }

+ 0
- 7
src/pages/dashboard/style.less Datei anzeigen

@@ -1,7 +0,0 @@
1
-.dashboardPage{
2
-  .dashboardCard{
3
-    text-align: center;
4
-    font-size: 20px;
5
-    .amount{margin-top: 16px;}
6
-  }
7
-}

+ 2
- 2
src/pages/resumework/abnormal/index.jsx Datei anzeigen

@@ -12,8 +12,8 @@ export default (props) => {
12 12
   const columns = [
13 13
     {
14 14
       title: '企业名称',
15
-      dataIndex: 'orgId',
16
-      key: 'orgId',
15
+      dataIndex: 'orgName',
16
+      key: 'orgName',
17 17
     },
18 18
     {
19 19
       title: '申请人',

+ 7
- 0
src/utils/number.js Datei anzeigen

@@ -0,0 +1,7 @@
1
+
2
+
3
+export function random (min, max) {
4
+  const range = max - min;
5
+  const rand = Math.random()
6
+  return min + Math.floor(Math.round(rand * range))
7
+}