基于React+antd的环境监测网站的设计与实现

发布于:2022-12-14 ⋅ 阅读:(1055) ⋅ 点赞:(0)

目录
引言 4
1.系统概述 5
1.1 系统开发方法 5
1.2 系统开发技术 5
2.系统调研及可行性分析 8
2.1系统调研 8
2.2系统总体目标 9
2.3可行性分析 10
2.3.1项目基本要求 10
2.3.2系统总体目标 10
3.系统分析 11
3.1系统需求分析 11
3.1.1功能需求 11
3.1.2非功能性需求 11
4.系统设计 12
4.1概要设计 12
4.1.1网站结构设计 12
4.1.2功能模块图 13
4.2数据设计 13
5.系统的实现 14
5.1React基础配置 14
5.2页面头部组件设计与实现 17
5.3页面导航条组件设计与实现 18
5.4分析页面组件设计与实现 22
5.5监控页面组件设计与实现 25
5.6工作台页面组件设计与实现 28
5.7项目列表和项目详情页面组件设计与实现 30
5.8人员信息页面组件设计与实现 33
5.9新建项目页面组件设计与实现 33
5.10财务管理页面组件设计与实现 37
5.11排行榜页面组件设计与实现 38
6.系统测试 40
6.1系统测试的重要性和目的 40
6.2测试方法 40
6.3系统模块测试 41
结论 42
参考文献及网站 43
附录:程序源代码获取及使用方式 44
3.系统分析
3.1系统需求分析
经过以上对本系统的调研确定总体目标及可行性分析后,下面将对系统在功能上以及性能上进行进一步的需求分析。明确系统功能的组成和分布以及对设备性能的最低要求及推荐配置。
3.1.1功能需求
系统的功能模块大体如下:
(1)首页
有分析页,展示当日的天气状况和时间,展示环境指数的当日评分的各个地区的排名。
有监控页,实时监控环境指数的分值,可以查看哪个用于提交的数值。
有工作台,可以让登录的用户查看自己负者的项目和项目进度,并根据自己线下的工作更新项目进度。
(2)列表页
有项目页,可以查看全部项目的进度和详情信息。
有人员信息页,可以查看全部人员的详细信息。
(3)操作页
可以新建项目,可以管理财务相关功能。
3.1.2非功能性需求
系统的非功能模块大体如下。
(1)易用性需求:界面的易用性不错、界面美观。
(2)安全性需求:用户操作具有相对安全性,不会造成密码泄露等安全隐患。
(3)运行环境约束:本文转载自http://www.biyezuopin.vip/onews.asp?id=15050暂时只兼容电脑端页面以及需要拥有网络的环境,页面源代码文件需要在装有Node.jsde 电脑上进行npm运行,打包好的页面文件需要在服务器上才可运行。

4.系统设计
4.1概要设计
4.1.1网站结构设计
网站目录结构如下:
(1)app文件夹
actions文件夹:接口返回数据处理。
components文件夹:存放全局组件,如导航条,头部信息等。
constans文件夹:存放全局的方法。
containers文件夹:存放各个页面的组件代码。
reducers文件夹:接口数据中转站,根据不同接口的数据进行分配。
routes文件夹:页面路由管理,定义各个页面组件,让各个页面可以使用 LInk跳转以及js触发跳转并传参。
static文件夹:有css文件夹、font文件夹、img文件夹、img文件夹、js文件夹,分别存放全局css样式,font样式,全局图片和全局js代码。
stores文件夹:定义React中的基础组件store,用于存储状态信息。
Inde.html文件:页面主页。
main.Jsx文件:页面进入时最先加载main.jsx文件。
(2)node_modules文件夹
React的依赖包,用于代码解析和插件管理,里面文件很多,一般用npm进行下载。
(3)package.json文件
定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。就是上面的node_modules文件夹。
(4)webpack.config.js文件
可以看做是模块打包机,主要功能是分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
(5)webpack.production.config.js文件
和webpack.config.js文件功能相同,在项目打包时用到。

4.1.2功能模块图
网站一级功能模块分为查看数据,项目管理和财务管理。
查看数据下包含了查看当日天气,时间和用户所在管理的地区。查看环境数据和全国排行榜以及网站的人员信息。
项目管理下包含了新建项目和更改项目。
财务管理下包含了分配和回收资金。

/*
 *监控页页面
 */
'use strict';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Row, Col, Tabs, Button, Icon, Card, Avatar, List, Spin } from 'antd';
import { formatTime } from '@app/constants/CommonFn.jsx';
import {monitorData, getTimeMonitorData} from '@app/constants/DataSource.jsx';
import './Monitor.css';
const TabPane = Tabs.TabPane;
const ReactHighcharts = require('react-highcharts');
const Highcharts = require('highcharts');

class Monitor extends Component {
	constructor(props) {
  	super(props);
		this.state = {
      loading:true,
      loadingMore: false,
      showLoadingMore: true,
      data: monitorData
    };
    this.timer1=1;
    this.timer2=2;
    this.timer3=3;
    this.timer4=4;
    getTimeMonitorData(() => {
      this.setState({data:monitorData})
    });
 	}

  componentDidMount(){
    let config1 = this.formChart({
        clock:this.clockTime,
        wholeNum:90,
        timer:'timer1'
      });
    let config2 = this.formChart({
        clock:this.clockTime,
        wholeNum:80,
        timer:'timer2'
      });
    let config3 = this.formChart({
        clock:this.clockTime,
        wholeNum:80,
        timer:'timer3'
      });
    let config4 = this.formChart({
        clock:this.clockTime,
        wholeNum:85,
        timer:'timer4'
      });
    this.timer5 = setTimeout(() => {
      this.setState({loading:false});
      Highcharts.chart('config1',config1);
      Highcharts.chart('config2',config2);
      Highcharts.chart('config3',config3);
      Highcharts.chart('config4',config4);
    },500);
  }

 	componentWillUnmount(){
		clearInterval(this.timer1);
    clearInterval(this.timer2);
    clearInterval(this.timer3);
    clearInterval(this.timer4);
    clearTimeout(this.timer5);
	}

  clockTime = (timer,wholeNum,series,series1) => {
    this[timer] = setInterval(function () {
                var x = (new Date()).getTime()+1000*60*60*8, // current time
                    y = wholeNum + ((-1)^Math.ceil(Math.random()*10))*(Math.ceil(Math.random()*100)/100);
                series.addPoint([x, y], false, true);
                    y = wholeNum + ((-1)^Math.ceil(Math.random()*10))*(Math.ceil(Math.random()*100)/100);
                series1.addPoint([x, y], true, true);
            }, 1000);
  }


  formChart = (option) => {
  	let config = {
		 	chart: {
        type: 'spline',
        marginRight: 10,
        events: {
	        load: function () {
            var series = this.series[0],
            		series1 = this.series[1],
                chart = this;
                option.clock(option.timer,option.wholeNum,series,series1);
	        }
        }
	    },
	    title: {
        text: '实时数据'
	    },
	    tooltip:{
	    	dateTimeLabelFormats:{
	    		millisecond:"%b %e, %H:%M:%S"
	    	}
	    },
	    xAxis: {
        type: 'datetime',
        tickPixelInterval: 150,
        dateTimeLabelFormats:{
        	millisecond: '%H:%M:%S',
        }
	    },
	    yAxis: {
        title: {
          text: '值'
        },
        max:100,
        min:50
	    },
	    legend: {
        enabled: true
	    },
	    exporting: {
	        enabled: false
	    },
	    credits:{
        enabled: false // 禁用版权信息
      },
	    series: [{
        name: '分值',
        data: (function () {
          var data = [],
              time = (new Date()).getTime()+1000*60*60*8,
              i;
          for (i = -100; i <= 0; i += 1) {
              data.push({
                  x: time + i * 1000,
                  y: option.wholeNum + ((-1)^Math.ceil(Math.random()*10))*(Math.ceil(Math.random()*100)/100)
              });
          }
          return data;
        }()),
        color:'#008CFF'
	    },{
        name: '平均值',
        data: (function () {
          var data = [],
              time = (new Date()).getTime()+1000*60*60*8,
              i;
          for (i = -100; i <= 0; i += 1) {
              data.push({
                  x: time + i * 1000,
                  y: option.wholeNum + ((-1)^Math.ceil(Math.random()*10))*(Math.ceil(Math.random()*100)/100)
              });
          }
          return data;
        }()),
        color:'#FF0000'
	    },]
		};
		return config;
	}

  render() {
  	let config5 = {
  		chart: {
  			plotBackgroundColor: null,
        plotBorderWidth: null,
        plotShadow: false,
        spacing : [20, 0 , 80, 0],
        height:260      
      },
      title: {
        verticalAlign:'middle',
        text: '各项比重',
        style:{'fontSize': '12px'}
      },
      tooltip: {
        pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
      },
      xAxis: {
	      plotBands: [{
          enabled:false
	      }]
      },
      yAxis: {
        plotBands: [{
          enabled:false
        }]
      },
      point: {
        events: {
          mouseOver: function(e) {  // 鼠标滑过时动态更新标题
            chart.setTitle({
                text: e.target.name+ '\t'+ e.target.y + ' %'
            });
          }
      	}
    	},
      plotOptions: {
        pie: {
          allowPointSelect: false,
          cursor: 'pointer',
          dataLabels: {
          	softConnector:false,
            enabled: false , //禁用数据名称
          }
        }
      },
      exporting:{
        enabled:false
      },
      credits:{
        enabled: false // 禁用版权信息
      },
      series: [{
        type: 'pie',
        innerSize: '80%',
        name:'评分比重',
				data: [
	        {name:'污染',y:  50},
	        {name:'空气',y:30},
	        {name:'水质',y:10},
	        {name:'土质',y:20},
	      ]
      }]
  	};

    const { loading, data } = this.state;

    return (
   		<div className = 'monitor'>
   			<Row gutter = {16}>
   				<Col span = {18}>
   					<Card loading = {this.state.loading}>
			  			<Tabs >
						    <TabPane tab={<span><Icon type="bar-chart" />空气质量</span>} key="1" forceRender ={true}>
                  <div id = "config1">1</div>
						    </TabPane>
						    <TabPane tab={<span><Icon type="line-chart" />污染程度</span>} key="2" forceRender ={true}>
						      <div id = 'config2'>2</div>
						    </TabPane>
						    <TabPane tab={<span><Icon type="dot-chart" />水质</span>} key="3" forceRender ={true}>
						      <div id = 'config3'>3</div>
						    </TabPane>
						    <TabPane tab={<span><Icon type="area-chart" />土质</span>} key="4" forceRender ={true}>
						      <div id = 'config4'>4</div>
						    </TabPane>
						  </Tabs>
				  	</Card>
            <Card title="动态" loading = {this.state.loading} className = 'infoList' style = {{marginTop:20}}>
              <List
                className="demo-loadmore-list"
                loading={loading}
                itemLayout="horizontal"
                dataSource={data}
                style = {{height:'auto'}}
                renderItem={item => (
                  <List.Item
                     actions={[<span>{item.ranksId}</span>,<span>{item.date}</span>]}
                  >
                    <List.Item.Meta
                      avatar={<Avatar icon="user" />}
                    />
                    <div><a href="#">{item.name}</a>{item.userAction}了{item.categories}数据,数值为:{item.userIOrD+item.num}</div>
                  </List.Item>
                )}
              />
            </Card>
				  </Col>
				  <Col span = {6}>
   					<Card title = '着重排行' style = {{background:'#fff'}} loading = {this.state.loading}>
							<p><Avatar>1</Avatar><span className = 'paihang'>污染<span><Icon type="caret-down" style = {{color:'#00FF00'}}/>10%</span></span></p>
							<p><Avatar>2</Avatar><span className = 'paihang'>水质<span><Icon type="caret-down" style = {{color:'#00FF00'}}/>8%</span></span></p>
							<p><Avatar>3</Avatar><span className = 'paihang'>空气<span><Icon type="caret-up" style = {{color:'#FF0000'}}/>2%</span></span></p>
							<p><Avatar>4</Avatar><span className = 'paihang'>土质<span><Icon type="caret-up" style = {{color:'#FF0000'}}/>3%</span></span></p>
				  	</Card>
				  	<Card title = '评分比重' style = {{background:'#fff',marginTop:20}} loading = {this.state.loading}>
				  		<ReactHighcharts config={config5}/>
				  	</Card>
				  </Col>
			  </Row>
    	</div>
		);
  }
}

function mapStateToProps(state) {
  return {
  }
}

export default connect(
  mapStateToProps,
  {

	}
)(Monitor)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章