生产实习——基于vue框架的web前端开发

目录

 

1 AirC首页

1.1 需求分析

1.2 原型设计

1.3 结果展示

1.4 优化思路

1.5 源代码

2 网格管理子页面

2.1 需求分析

2.2 原型设计

2.3 结果展示

2.4 优化思路

2.5 源代码

3 设备管理子页面

3.1 需求分析

3.2 原型设计

3.3 结果展示

3.4 优化思路

3.5 源代码

4 实习总结


1 AirC首页

1.1 需求分析

  1. 查看网格及切换网格;
  2. 查看描述信息
  3. 查看空气质量参数
  4. 查看气象参数
  5. 查看监控设备在所有监控网点中的排名;
  6. 查看站点视频,点击可以播放视频;
  7. 查看历史记录,有变化趋势图,同时也可以导出保存。

1.2 原型设计

1.3 结果展示

  • 1.查询某设备实时气象参数和空气质量参数

用户点击下拉选框选择希望查询的设备序列号,选好之后点击查询按钮,前端根据用户选择的序列号向后端发送get请求,并将获取的response中的相应值(PM2.5、PM10、SO2、CO2、NO2、O3、温度、湿度、风速、风向、光照、气压)赋值给全局变量,并更新页面显示的值,弹出获取气象参数成功的提示。

  • 2.清空设备序列号输入框

前端向后端发送get请求,五请求参数。获取空气质量参数成功后,在右下角展示出PM2.5,PM10,SO2,CO,NO2这5种气体含量的变化趋势,将鼠标移至某一天的位置处,还能显示这一天这5种气体的具体含量,同时还支持导出图表下载到本地。

  • 3.设备AQI排名信息

前端向后端发送get请求,无请求参数。获取排名数据成功后,在右上角的图表展示出设备排名、设备序列号、AQI以及污染详情。

  • 4.近7天的空气质量参数

前端向后端发送get请求,五请求参数。获取空气质量参数成功后,在右下角展示出PM2.5,PM10,SO2,CO,NO2这5种气体含量的变化趋势,将鼠标移至某一天的位置处,还能显示这一天这5种气体的具体含量,同时还支持导出图表下载到本地。

1.4 优化思路

  1. 可供查询的设备应该要扩充范围到所有设备;
  2. 在排名表格中,增加滚动条,使用户能够下滑看到更多排名信息;
  3. 空气质量参数为静态数据,可以通过数据格式转换获取对应的数据值;
  4. 用户可自行选择数据的时间时间间隔,每小时,每天,每周,每月,每小时之类。

1.5 源代码

<template>
    <div id="Index">
        <!-- 占位 -->
        <div>
            <!-- 搜索相关开始 -->
            <el-select v-model="value" placeholder="请选择设备序列号" style="width:300px;height:50px;border:1px solid #fff;margin:15px">
                <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value">
                </el-option>
            </el-select>
            <!-- <el-button 
            type="primary" 
            style="background-color:#BFDFAF; border-color:#BFDFAF;" 
            @click='Search' icon="el-icon-search">查 询</el-button> -->
            <el-button 
            type="primary" 
            style="background-color:#BFDFAF; border-color:#BFDFAF;" 
            @click='Search' icon="el-icon-search">查 询</el-button>
            <el-button @click="clearText" icon="el-icon-delete">清 空</el-button>
            <!-- 搜索相关结束 -->
            <div style="width:100%;height:50px;text-align:center;border:1px solid #fff;font-size:15">
                <h3>该设备实时气象参数和空气质量参数如下</h3>
            </div>
            <br>
            <div style="width:100%;height:30px;border:1px solid #fff;margin:0 auto;">
                <span slot="title">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    PM2.5:{{PM25}}
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    PM10:{{PM10}}
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    SO2:{{SO2}}
                </span>
            </div>
            <div style="width:100%;height:30px;border:1px solid #fff;margin:0 auto;">
                <span slot="title">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    CO2:{{CO2}}
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    NO2:{{NO2}}
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    O3:{{O3}}
                </span>
            </div>
        </div>
        <div>
            <el-table
            title="监控设备排名"
            :data="tableData"
            style="width: 100%;height:100%"
            :header-cell-style="{'text-align':'center'}"
            :cell-style="{'text-align':'center'}">
            <el-table-column
                prop="rank"
                label="排名"
                width="50">
            </el-table-column>
            <el-table-column
                prop="serialnum"
                label="设备序列号"
                width="150">
            </el-table-column>
            <el-table-column
                prop="AQI"
                label="AQI"
                width="200">
            </el-table-column>
            <el-table-column
                prop="desc"
                label="详情"
                width="200">
            </el-table-column>
            </el-table>
        </div>
        <!-- <div id='echart3'></div> -->
        <div>
            <div id='temperature' style="height:30%;float:left;border:1px solid #fff;margin:5px auto">
                <img src="../assets/温度计.png" alt="" align="center">
			        <span slot="title">{{Temperature}}</span>
            </div>
            <div id='windspeed' style="height:30%;float:right;border:1px solid #fff;margin:5px auto">
                <img src="../assets/风.png" alt="" align="center">
			        <span slot="title">{{WindSpeed}}</span>
            </div>
            <div id='humidity' style="height:30%;float:left;border:1px solid #fff;margin:5px auto">
                <img src="../assets/水滴.png" alt="" align="center">
			        <span slot="title">{{Humidity}}</span>
            </div>
            <div id='winddirection' style="height:30%;float:right;border:1px solid #fff;margin:5px auto">
                <img src="../assets/风向标.png" alt="" align="center">
			        <span slot="title">{{WindDirection}}</span>
            </div>
            <div id='light' style="height:30%;float:left;border:1px solid #fff;margin:5px auto">
                <img src="../assets/太阳.png" alt="" align="center">
			        <span slot="title">{{Light}}</span>
            </div>
            <div id='airpressure' style="height:30%;float:right;border:1px solid #fff;margin:5px auto">
                <img src="../assets/压力.png" alt="" align="center">
			        <span slot="title">{{AirPressure}}</span>
            </div>
        </div>
        <div id='echart4'></div>
    </div>
</template>

<script type="text/javascript">
    var echarts = require('echarts');
    import china from 'echarts/map/js/china.js';
    // 哪里需要请求数据 就在哪里导入
    import  axios from '@/http/axios.js';
    export default{
        data(){
            return{
                //show: false
                tableData: [],
                Temperature:'',
                Humidity:'',
                WindSpeed:'',
                WindDirection:'',
                Light:'',
                AirPressure:'',
                AirIndex:[],
                PM25:'',
                PM10:'',
                SO2:'',
                CO2:'',
                NO2:'',
                O3:'',

                options: [{
                value: 'ASN11000010',
                label: 'ASN11000010'
                }, {
                value: 'ASN11000011',
                label: 'ASN11000011'
                }, {
                value: 'ASN11000012',
                label: 'ASN11000012'
                }, {
                value: 'ASN11000013',
                label: 'ASN11000013'
                }, {
                value: 'ASN11000014',
                label: 'ASN11000014'
                }, {
                value: 'ASN11000015',
                label: 'ASN11000015'
                }],
                value: 'ASN11000010'
            }
        },
        created(){
            this.GetAllData();
        },
        mounted(){
            this.drawEchart4();
        },
        methods:{
            Search(){
                let url2='/nowdevicedata/'+this.value+'/get_single';
                axios.get(url2)
                .then((response)=>{
                    console.log(response);
                    this.Temperature='温度:'+response.data.data[0]['Temperature']+'℃';
                    this.Humidity='湿度:'+response.data.data[0]['Humidity']+'%';
                    this.WindSpeed='风速:'+response.data.data[0]['WindSpeed']+'级';
                    this.WindDirection='风向:'+this.transfer2(response.data.data[0]['WindDirection']);
                    //transfer2(response.data.data[0]['WindDirection']);
                    this.Light='光照:'+response.data.data[0]['Light']+'lx';
                    this.AirPressure='气压:'+response.data.data[0]['AirPressure']+'Pa';
                    this.PM25=response.data.data[0]['PM25'];
                    this.PM10=response.data.data[0]['PM10'];
                    this.SO2=response.data.data[0]['SO2'];
                    this.CO2=response.data.data[0]['CO2'];
                    this.NO2=response.data.data[0]['NO2'];
                    this.O3=response.data.data[0]['O3'];
                    console.log("气象参数:",
                    [this.Temperature,this.Humidity,this.WindSpeed,this.WindDirection,this.Light,this.AirPressure]);
                    this.$notify.success({
                        title: '成功',
                        message: '获取气象参数成功'
                    });
                }).catch((error)=>{
                    //错误提醒
                    this.$notify.error({
                        title: '失败',
                        message: '获取气象参数失败'
                    });
                })
            },
            clearText(){
                this.value='';
                this.GetAllData();
            },
            GetAllData(){
                this.Search();
                let url1='/alldevicedata/AQI';
                // 第二个参数 请求的参数
                axios.get(url1)
                .then((response)=>{
                    // 后台传来什么样的值
                    console.log(response);
                    this.tableData=response.data.data;
                    this.$notify.success({
                        title: '成功',
                        message: '获取排名数据成功'
                    });
                }).catch((error)=>{
                    //错误提醒
                    this.$notify.error({
                        title: '失败',
                        message: '获取排名数据失败'
                    });
                })
                
                let url3='/alldevicedata/Avg';
                axios.get(url3)
                .then((response)=>{
                    console.log(response);
                    /*this.tableData=response.data.data.results;
                    this.total=response.data.data.count;
                    //map 数组里所有值进行统一操作  item  子的数组中单个值本身
                    this.tableData=response.data.data.results.map((item)=>{
                        //item.is_active=item.is_active?'可用':'禁用'
                        return item;
                    })
                    console.log("表格数据:",this.tableData);*/
                    this.$notify.success({
                        title: '成功',
                        message: '获取空气质量参数成功'
                    });
                }).catch((error)=>{
                    //错误提醒
                    this.$notify.error({
                        title: '失败',
                        message: '获取空气质量参数失败'
                    });
                })
            },
            transfer2(type){
                if(type==='WN'){
                    return '西北风'
                }else if(type==='ES'){
                    return '东南风'
                }else if(type==='WS'){
                    return '西南风'
                }else if(type==='EN'){
                    return '东北风'
                }else if(type==='S'){
                    return '南风'
                }else if(type==='W'){
                    return '西风'
                }else if(type==='N'){
                    return '北风'
                }else if(type==='E'){
                    return '东风'
                }else{
                    return type
                }
            },
            drawEchart4(){
                var myChart = echarts.init(document.getElementById('echart4'));
                var option = {
                    title: {
                        text: '空气质量参数'
                    },
                    tooltip: {
                        trigger: 'axis',
                        axisPointer: {
                            type: 'cross',
                            label: {
                                backgroundColor: '#6a7985'
                            }
                        }
                    },
                    legend: {
                        data: ['PM2.5', 'PM10', 'SO2', 'CO', 'NO2']
                    },
                    toolbox: {
                        feature: {
                            saveAsImage: {}
                        }
                    },
                    grid: {
                        left: '3%',
                        right: '4%',
                        bottom: '3%',
                        containLabel: true
                    },
                    xAxis: [
                        {
                            type: 'category',
                            boundaryGap: false,
                            data: ['6天前', '5天前', '4天前', '3天前', '2天前', '1天前', '今天']
                        }
                    ],
                    yAxis: [
                        {
                            type: 'value'
                        }
                    ],
                    series: [
                        {
                            name: 'PM2.5',
                            type: 'line',
                            stack: '总量',
                            areaStyle: {},
                            data: [114.27, 109.58, 106.23, 116.65, 119.67, 124.93, 119.77]
                        },
                        {
                            name: 'PM10',
                            type: 'line',
                            stack: '总量',
                            areaStyle: {},
                            data: [124.36, 109.01, 107.08, 127.70, 126.10, 114.93, 117.39]
                        },
                        {
                            name: 'SO2',
                            type: 'line',
                            stack: '总量',
                            areaStyle: {},
                            data: [457.39, 455.83, 483.35, 583.20, 543.11, 495.40, 486.57]
                        },
                        {
                            name: 'CO',
                            type: 'line',
                            stack: '总量',
                            areaStyle: {},
                            data: [49.60, 49.17, 48.55, 50.42, 50.02, 49.55, 51.33]
                        },
                        {
                            name: 'NO2',
                            type: 'line',
                            stack: '总量',
                            label: {
                                normal: {
                                    show: true,
                                    position: 'top'
                                }
                            },
                            areaStyle: {},
                            data: [1841.89, 2005.73, 2024.41, 2116.98, 1931.17, 1971.21, 2059.63]
                        }
                    ]
                };
                myChart.setOption(option);
                window.addEventListener('resize',function(){
                    myChart.resize()
                })
            },
            
        }
    }
</script>

<style type="text/css" scoped>
#Index{
    height:100%;
    width:100%;
    /* 布局方式 */
    display: flex;
    /* 显示方式 空位置 不连在一起的 */
    justify-content: space-around;
    /* 位置操作可否换行 可以换行 */
    flex-wrap: wrap;
}
#Index div{
    width: calc(50% - 5px);
    height:calc(50% - 5px);
    border:1px solid #ccc;
}
</style>

2 网格管理子页面

2.1 需求分析

  1. 输入网格相关信息并添加进系统。
  2. 查看所有网格的信息。
  3. 为网格绑定设备或解绑设备。
  4. 删除网格的信息以及与之相绑定的设备信息。
  5. 修改并保存工程信息。

2.2 原型设计

  • 网格列表展示

  • 新增网格

  • 查询网格编号

  • 查询网格名称

  • 修改网格

  • 网格绑定/解绑设备

  • 删除网格

2.3 结果展示

  • 1.网格列表展示

  • 2.新增网格

点击新增网格按钮,弹出新增网格模态框,填好必填字段(标红色星号)后,点击确认按钮即可通过post请求将新增网格信息提交到后端,请求参数为该表单的值;如果必填字段为空白则会有对应的提示语。

  • 3.根据网格编号查询网格

在网格编号输入框内输入网格编号点击查询按钮,前端向后端提交get请求,参数为输入的网格编号。若该网格编号存在于数据库中,则表格更改为该网格的信息;若该网格编号不存在于数据库中,则提示查询失败。

  • 4.清空网格编号输入

点击清空按钮,输入框中的内容全部清空,且重新获取网格列表数据。

  • 5.修改网格信息

点击网格操作一栏的修改按钮,弹出修改网格模态框,模态框中的数据与该网格存在数据库中的数据对应。修改完成后,点击底部的确定按钮,就会将前端的操作提交put请求到后端,请求参数为修改后的表单值,并重新获取网格列表数据。若点击取消按钮或右上角的×号,则会取消修改操作,数据库中的数据不改变。

  • 6.将网格绑定/解绑对应的设备

点击网格操作一栏的绑定/解绑按钮,弹出绑定设备/解绑设备模态框。用户输入设备序列号后,点击底部的确定按钮,前端就会根据输入的设备序列号提交put请求到后端执行数据库表的更新操作,请求参数为该网格编号,后端将该设备的gridBelong属性置为该网格编号。若点击取消按钮或右上角的×号,则会取消修改操作,数据库中的数据不改变。

  • 7.删除网格

点击网格操作一栏的删除按钮,弹出是否确认删除提示框。若点击确认按钮,就会通过delete方法将前端操作提交到后端执行数据库表的delete操作,删除网格表内对应的元组。若点击取消按钮或右上角的×号,则会取消修改操作,数据库中的数据不改变。

2.4 优化思路

  1. 新增/修改网格模态框中,对输入经纬度、占地面积进行数值验证;
  2. 解绑设备增加验证功能,验证该网格是否已经与此设备绑定;
  3. 通过网格编号和网格名称的模糊查询;
  4. 提交查询时自动调整当前页为第一页。

2.5 源代码

// 两个模态框的问题 怎么区分? 网格的绑定/解绑设备 设备的详情 已解决
//修改弹出日期,是NaN
//查询函数Search
//分页参数不太懂
//数据交互是个大问题!!!
<template>
	<div id="grid">
		<!-- 搜索相关开始 -->
		<el-button 
		type="primary" 
    icon="el-icon-circle-plus"
		style="background-color:#BFDFAF; border-color:#BFDFAF; margin-right:80px;" 
		@click='Add'>新增网格</el-button>
		<el-input id="input_id" v-model="input_id" placeholder="请输入网格编号"
    style="width: 200px; margin-right:30px;" clearable></el-input>
		<el-input id="input_name" v-model="input_name" placeholder="请输入网格名称"
    style="width: 200px; margin-right:30px;" clearable></el-input>
		<el-button 
		type="primary" 
		style="background-color:#BFDFAF; border-color:#BFDFAF;" 
		@click='Search' icon="el-icon-search">查 询</el-button>
    <el-button @click="clearText" icon="el-icon-delete">清 空</el-button>
    <!-- 搜索相关结束 -->

		<!-- 表格开始 -->
		<el-table
		:data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)"
		style="width: 100%"
		:header-cell-style="{'text-align':'center'}"
    :cell-style="{'text-align':'center'}">
		<el-table-column prop="gridNumber" label="网格编号"  width="150"></el-table-column>
		<el-table-column prop="gridName" label="网格名称"  width="150"></el-table-column>
		<el-table-column prop="type" label="类型"  width="100">
    <template slot-scope="scope">
        {{transfer(scope.row.type)}}
    </template>
    </el-table-column>
		<el-table-column prop="lastStartTime" label="时间" width='180'></el-table-column> 
		<el-table-column prop="gridAdminAccount" label="负责人" width='70'></el-table-column> 
		<el-table-column prop="longitude,latitude" label="经纬度" width='150'>
      <template slot-scope="scope">
        {{scope.row.longitude.toFixed(2)}},{{scope.row.latitude.toFixed(2)}}
      </template>
    </el-table-column> 
		<el-table-column prop="constructionUnits" label="施工单位" width='150'></el-table-column>
		<el-table-column label="操作" width="200">
		<template slot-scope="scope">
			<el-button @click="Edit(scope.row)" type="text" size="small">修改</el-button>
			<el-button @click="Bind(scope.row)" type="text" size="small">绑定</el-button>
			<el-button @click='Unbind(scope.row)' type="text" size="small">解绑</el-button>
			<el-button @click="Delete(scope.row)" type="text" size="small">删除</el-button>
		</template>
		</el-table-column>
		</el-table>
		<!-- 表格结束 -->

		<!-- 表单开始 -->
		<el-dialog :title="title" :visible.sync="dialogFormVisible" custom-class="customWidth">
		<el-form :model="form"  :rules='rules' ref="Form">
			<!-- {{form}} -->
			<el-form-item label="网格编号" prop='gridNumber' :label-width="formLabelWidth">
			<el-input v-model="form.gridNumber" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="网格名称" prop='gridName'  :label-width="formLabelWidth">
			<el-input  v-model="form.gridName" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="详细地址" prop='address' :label-width="formLabelWidth">
			<el-input   v-model="form.address" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="经度" prop='longitude'  :label-width="formLabelWidth">
			<el-input   v-model="form.longitude" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="纬度" prop='latitude'  :label-width="formLabelWidth">
			<el-input   v-model="form.latitude" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="管理员" prop='gridAdminAccount'  :label-width="formLabelWidth">
			<el-input   v-model="form.gridAdminAccount" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="检测时间" :label-width="formLabelWidth">
			<el-date-picker v-model="form.lastStartTime" type="date" placeholder="选择日期" style="width:300px">
			</el-date-picker>
			</el-form-item>
			<el-form-item label="施工单位" prop='constructionUnits'  :label-width="formLabelWidth">
			<el-input   v-model="form.constructionUnits" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="类型" :label-width="formLabelWidth" prop='type'>
			<el-select v-model="form.type" placeholder="请选择网格类型" style="width:300px">
				<el-option label="化工厂" value="1"></el-option>
				<el-option label="建筑工地" value="2"></el-option>
				<el-option label="发电厂" value="3"></el-option>
				<el-option label="街道" value="4"></el-option>
				<el-option label="搅拌站" value="5"></el-option>
			</el-select>
			</el-form-item>
			<el-form-item label="占地面积" prop='coverSize'  :label-width="formLabelWidth">
			<el-input   v-model="form.coverSize" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="相关单位" prop='relateUnit'  :label-width="formLabelWidth">
			<el-input   v-model="form.relateUnit" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
      <el-form-item label="工程信息" prop='projectInformation'  :label-width="formLabelWidth">
			<el-input   v-model="form.projectInformation" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
		</el-form>

		<div slot="footer" class="dialog-footer">
			<el-button @click="dialogFormVisible = false">取 消</el-button>
			<el-button type="primary" @click="BtnOk('Form')"
      style="background-color:#BFDFAF; border-color:#BFDFAF;">确 定</el-button>
		</div>
		</el-dialog>
		<!-- 表单结束 -->

    <!-- 表单开始 --> 
		<el-dialog :title="title" :visible.sync="dialogFormVisible2" custom-class="customWidth">
		<el-form :model="form2"  :rules='rules2' ref="Form2">
			<!-- {{form2}} -->
      <el-form-item label="设备编号" prop='serialnum' :label-width="formLabelWidth">
			<el-input v-model="form2.serialnum" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
    </el-form>

		<div slot="footer" class="dialog-footer">
			<el-button @click="dialogFormVisible2 = false">取 消</el-button>
			<el-button type="primary" @click="BtnOk2('Form2')"
      style="background-color:#BFDFAF; border-color:#BFDFAF;">确 定</el-button>
		</div>
		</el-dialog>
    <!--表单结束 -->


		<!-- 分页开始 -->
		<div class="page" style="position: absolute; bottom: 40px;right: 20px;">
			<el-pagination
        background
        layout="prev, pager, next"
        :total="total"
        :page-size="pageSize"
        :current-page.sync="currentPage"
        @current-change="handleCurrentChange"
        >
      </el-pagination>
		</div>
		<!-- 分页结束 -->
	</div>
</template>

<script type="text/javascript">
import {formatDate } from '@/common/date.js'
// 哪里需要请求数据 就在哪里导入
import  axios from '@/http/axios.js'
export default{
  data(){
    return{
      input_id:'',
      input_name:'',
      tableData: [],
      //模态框的相关数据
      dialogFormVisible:false,
      title:'新增网格',
      form:{
        gridNumber:'',
        gridName:'',
        address:'',
        longitude:'',
        latitude:'',
        gridAdminAccount:'',
        lastStartTime:'',
        constructionUnits:'',
        type:'',
        coverSize:'',
        relateUnit:'',
        projectInformation:''
      },
      formLabelWidth:'100px',
      id:'',
      idDis:false,
      rules: {
        gridNumber:[{required:true,message:'设备编号不能为空'}],
        gridName:[{required:true,message:'设备名称不能为空'}],
        address:[{required:true,message:'地址不能为空'}],
        constructionUnits:[{required:true,message:'施工单位不能为空'}],
        coverSize:[{required:true,message:'占地面积不能为空'}],
        relateUnit:[{required:true,message:'相关单位不能为空'}],
        projectInformation:[{ required: true, message: '工程信息不能为空'}],
      },

      //模态框的相关数据
      dialogFormVisible2:false,
      title:'绑定设备',
      form2:{
        serialnum:''
      },
      formLabelWidth:'100px',
      id:'',
      idDis:false,
      rules2: {
        serialnum:[{required:true,message:'设备序列号不能为空'}],
      },

      //和分页相关的变量 
      total:undefined,  // 总页数
      pageSize:5,
      currentPage:1,
      currentPageData:[], //当前页显示内容
      gridNumber:'',
      gridName:'',
    }
  },
  // search  我希望 在输框里输入数据  search  会跟着变  v-model  双向绑定
  // 数据监听
  // watch:{
  //   'search':function(){
  //     this.GetAllData();
  //     console.log(this.search);
  //   }
  // },
  created(){
    //向后台请求 用户数据
    this.GetAllData();
  },
  methods:{
    transfer(type){
      if(type===1){
        return '化工厂'
      }else if(type===2){
        return '建筑工地'
      }else if(type===3){
        return '发电厂'
      }else if(type===4){
        return '街道'
      }else if(type===5){
        return '搅拌站'
      }
    },
    handleCurrentChange(val){
      //筛选条件变了 重新获取值
      this.GetAllData();
    },
    Search(){
      axios.get('/grid/Grid/'+this.input_id+'/',{
        gridNumber:this.input_id,
      })
      .then((response)=>{
          console.log("如果成功:",response);
          this.tableData=[response.data.data];   //不知道什么原因!!!!!表格的值不更新
          //alert(response.data.data[serialnum])
          console.log(response.data.data)
          this.$notify.success({
          title: '成功',
          message: '查询成功!!!'
        });
      }).catch((error)=>{
        this.$notify.error({
          title: '失败',
          message: '查询失败!!!'
        });
        console.log(error)// 打印失败的信息
      })
    },
    clearText(){
        this.input_id='';
        this.input_name='';
        this.GetAllData();
    },
    GetAllData(){
      // 后台会提供一个接口  
      //axios  访问后台接口  获取数据  
      //this.tableData=获取的数据
      //第一个参数 url
      let url='/grid/get';
      // 第二个参数 请求的参数
      axios.get(url,{
        //分页的参数
        page_size:this.pageSize,
        page:this.currentPage,
        gridNumber:this.gridNumber,
        gridName:this.gridName,
      })
      .then((response)=>{
        // 后台传来什么样的值
        console.log(response);
        //返回正确的对象,包含所有需要的属性
        this.tableData=response.data.data.results;
        this.total=response.data.data.count;
        //map 数组里所有值进行统一操作  item  子的数组中单个值本身
        this.tableData=response.data.data.results.map((item)=>{
          //item.is_active=item.is_active?'可用':'禁用'
          return item;
        })
        this.$notify.success({
          title: '成功',
          message: '获取数据成功'
        });
        console.log("表格数据:",this.tableData);
      }).catch((error)=>{
        //错误提醒
        this.$notify.error({
          title: '失败',
          message: '获取数据失败'
        });

      })
    },
    Add(){
      this.title='新增网格'
      this.dialogFormVisible=true;
      this.form={};
      this.idDis=false;
    },
    //编辑
    Edit(row){
      this.title="编辑网格";
      this.dialogFormVisible=true;
      this.form=row;
      //this.id=row.id;
      this.idDis=true;
    },
    //确认新增的按钮
    BtnOk(formName){
      this.$refs[formName].validate((valid) => {
        if(valid){
          if(this.title=='新增网格'){
              //axios 发送数据到后台
              //转换时间格式
              this.form.lastStartTime=formatDate(this.form.lastStartTime);
              //网址根据实际要改一下
              axios.post('/grid/',this.form)
              .then((response)=>{
                  console.log("如果成功:",response);
                  this.GetAllData();
                  this.$notify.success({
                    title: '成功',
                    message: '新增成功!!!'
                  });
              }).catch((error)=>{
                this.$notify.error({
                  title: '失败',
                  message: '新增失败!!!'
                });
                console.log(error)// 打印失败的信息
              })
          }
          if(this.title=='编辑网格'){
              //转换时间格式
              this.form.lastStartTime=formatDate(this.form.lastStartTime);
              //网址根据实际要改一下
              axios.put('/grid/'+this.form.gridNumber+'/conf',this.form)
              .then((response)=>{
                  console.log("如果成功:",response);
                  this.GetAllData();
                  this.$notify.success({
                    title: '成功',
                    message: '修改成功!!!'
                  });
              }).catch((error)=>{
                this.$notify.error({
                  title: '失败',
                  message: '修改失败'
                });
                console.log(error)// 打印失败的信息
              })
          }
          this.dialogFormVisible=false;
        }else{
          console.log('失败')
        }         
    })
    },
    //绑定
    Bind(row){
      this.title="绑定设备";
      this.dialogFormVisible2=true;
      this.gridNumber=row.gridNumber;
      this.form2={};
      this.idDis=true;
    },
    //解绑
    Unbind(row){
      this.title="解绑设备";
      this.dialogFormVisible2=true;
      this.form2={};
      this.idDis=true;
    },
    //确认绑定的按钮
    BtnOk2(formName){
      this.$refs[formName].validate((valid) => {
        if(valid){
          if(this.title=='绑定设备'){
            //axios 发送数据到后台
            //网址根据实际要改一下
            axios.put('/device/'+this.form2.serialnum+'/conf3',{
              //serialnum:this.form2.serialnum,
              gridBelong:this.gridNumber,
              //gridBelong:'2',
            })
            .then((response)=>{
                console.log("如果成功:",response);
                alert(this.gridNumber);
                this.$notify.success({
                  title: '成功',
                  message: '绑定成功'
                });
            }).catch((error)=>{
              this.$notify.error({
                title: '失败',
                message: '绑定失败'
              });
              console.log(error)// 打印失败的信息
            })
          }
          if(this.title=='解绑设备'){
              //网址根据实际要改一下
              //这里是解绑,可能需要修改一下数据库的连接关系之类的
            axios.put('/device/'+this.form2.serialnum+'/conf3',{
              //serialnum:this.form2.serialnum,
              gridBelong:'',
            })
            .then((response)=>{
                console.log("如果成功:",response);
                this.$notify.success({
                  title: '成功',
                  message: '解绑成功'
                });
            }).catch((error)=>{
              this.$notify.error({
                title: '失败',
                message: '解绑失败'
              });
              console.log(error)// 打印失败的信息
            })
          }
          this.dialogFormVisible2=false;
        }else{
          console.log('失败')
        }
    })
    },
    //删除
    Delete(row){
      this.$confirm('此操作将永久删除该网格, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
           ///  id  ==> 后台  我们要删除  删除  谨慎
           axios.delete('/grid/'+row.gridNumber+'/delete',{
             gridNumber:row.gridNumber,
           })
           .then((response)=>{
             this.$notify.success({
                  title: '成功',
                  message: '删除成功'
                });
             this.GetAllData();
           }).catch((error)=>{
              this.$notify.error({
                  title: '失败',
                  message: '删除失败'
                });
           })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });       
    }
  }
}
</script>

<style type="text/css">
.customWidth{
  width:500px;
}
</style>

3 设备管理子页面

3.1 需求分析

  1. 输入设备相关信息并添加进系统。
  2. 查看所有网格的信息。
  3. 冻结设备使之不能被绑定。
  4. 修改设备参数

3.2 原型设计

  • 设备列表

  • 新增设备

  • 修改设备

  • 查询设备编号

  • 查询设备名称

  • 删除设备

3.3 结果展示

  • 1.设备列表展示

  • 2.激活设备

点击激活设备按钮,弹出激活设备模态框,用户输入设备序列号,点击底部的确认按钮则提交操作到后端。设备序列号是必填字段,如果不填则会有错误提示。前端根据用户输入的设备序列号提交put请求,参数为active,在设备表里将该设备的active属性置为1.

  • 3.通过设备序列号查询设备

在设备序列号输入框内输入设备序列号点击查询按钮,前端向后端提交get请求,参数为输入的设备序列号。若该设备序列号存在于数据库中,则表格更改为该设备的信息;若该设备序列号不存在于数据库中,则提示查询失败。

  • 4.清空输入框

点击清空按钮,输入框中的内容全部清空,且重新获取设备列表数据。

  • 5.查看设备详情

点击操作一栏的详情,弹出设备详情模态框,用户点击确认按钮不会执行任何操作。

  • 6.修改设备信息

点击操作一栏的修改,弹出编辑设备模态框。用户可修改除设备序列号以外的字段,但要保证ip地址和mac地址不为空,不然会有错误提示。修改完成后点击底部的确认按钮,前端向后端提交patch请求,参数为该表单的值,更改数据库设备表中相应字段的值。

  • 7.冻结设备

点击操作一栏的冻结按钮,弹出提示,向用户确认是否冻结该设备。若用户点击确认,则前端根据该设备的序列号向后端发出put请求,active参数为0,后端修改数据库中的该设备active值为0.

3.4 优化思路

  1. 激活设备时要求用户输入该设备密码,并验证密码是否正确。只有正确才可向后台提交激活设备操作;
  2. 激活设备时验证该设备是否已激活,若已经激活则提示用户相关信息;
  3. 查询时的分页问题,同网格子页面的问题;
  4. 查看设备详情时,设置字段显示形式为文本格式,而不是输入框,防止用户做了修改虽然不提交到后端但表单值已经被改的情况。

3.5 源代码

<template>
	<div id="equip">
		<!-- 搜索相关开始 -->
		<el-button 
		type="primary" 
    icon="el-icon-circle-plus"
		style="background-color:#BFDFAF; border-color:#BFDFAF; margin-right:80px;" 
		@click='Add'>激活设备</el-button>
		<el-input id="input_id" v-model="input_id" placeholder="请输入设备序列号"
    style="width: 200px; margin-right:30px;" clearable></el-input>
		<el-input id="input_name" v-model="input_name" placeholder="请输入设备名称"
    style="width: 200px; margin-right:30px;" clearable></el-input>
		<el-button 
		type="primary" 
		style="background-color:#BFDFAF; border-color:#BFDFAF;" 
		@click='Search' icon="el-icon-search">查 询</el-button>
    <el-button @click="clearText" icon="el-icon-delete">清 空</el-button>
    <!-- 搜索相关结束 -->

		<!-- 表格开始 -->
		<el-table
		:data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)"
		style="width: 100%"
		:header-cell-style="{'text-align':'center'}"
    :cell-style="{'text-align':'center'}">
		<el-table-column prop="serialnum" label="设备序列号"  width="150"></el-table-column>
		<el-table-column prop="deviceName" label="设备名称"  width="150"></el-table-column>
		<el-table-column prop="is_active" label="激活情况"  width="100">
      <template slot-scope="scope">
        {{scope.row.active?"已激活":"未激活"}}
      </template>
    </el-table-column>
		<el-table-column prop="is_line" label="在线情况" width='180'>
      <template slot-scope="scope">
        {{scope.row.line?"在线":"离线"}}
      </template>
    </el-table-column> 
		<el-table-column prop="longitude,latitude" label="经纬度" width='150'>
      <template slot-scope="scope">
        {{scope.row.longitude}},{{scope.row.latitude}}
        <!-- {{scope.row.longitude.toFixed(2)}},{{scope.row.latitude.toFixed(2)}} -->
      </template>
    </el-table-column> 
		<el-table-column label="操作" width="200">
		<template slot-scope="scope">
			<el-button @click="Detail(scope.row)" type="text" size="small">详情</el-button>
			<el-button @click="Edit(scope.row)" type="text" size="small">修改</el-button>
			<el-button @click="Delete(scope.row)" type="text" size="small">冻结</el-button>
		</template>
		</el-table-column>
		</el-table>
		<!-- 表格结束 -->

    <!-- 表单开始 --> 
		<el-dialog :title="title" :visible.sync="dialogFormVisible1" custom-class="customWidth">
		<el-form :model="form1"  :rules='rules1' ref="Form1">
			<!-- {{form1}} -->
      <el-form-item label="序列号" prop='serialnum' :label-width="formLabelWidth">
			<el-input v-model="form1.serialnum" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
      <!-- <el-form-item label="密码" prop='devkey' :label-width="formLabelWidth">
			<el-input v-model="form1.devkey" type="devkey" autocomplete="off" style="width:300px"></el-input>
			</el-form-item> -->
    </el-form>

		<div slot="footer" class="dialog-footer">
			<el-button @click="dialogFormVisible2 = false">取 消</el-button>
			<el-button type="primary" @click="BtnOk1('Form1')"
      style="background-color:#BFDFAF; border-color:#BFDFAF;">确 定</el-button>
		</div>
		</el-dialog>
    <!--表单结束 -->

		<!-- 表单开始 -->
		<el-dialog :title="title" :visible.sync="dialogFormVisible2" custom-class="customWidth">
		<el-form :model="form2"  :rules='rules2' ref="Form2">
			<!-- {{form2}} -->
			<el-form-item label="设备序列号" prop='serialnum' :label-width="formLabelWidth">
			<el-input v-model="form2.serialnum" autocomplete="off" style="width:300px" :disabled="true"></el-input>
			</el-form-item>
			<el-form-item label="设备名称" prop='deviceName'  :label-width="formLabelWidth">
			<el-input  v-model="form2.deviceName" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
      <el-form-item label="设备状态" :label-width="formLabelWidth" prop='class'>
          <el-select v-model="form2.line" placeholder="请选择设备状态">
            <el-option label="在线" value="1"></el-option>
            <el-option label="离线" value="0"></el-option>
          </el-select>
        </el-form-item>
			<el-form-item label="ip地址" prop='ip' :label-width="formLabelWidth">
			<el-input   v-model="form2.ip" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="mac地址" prop='mac'  :label-width="formLabelWidth">
			<el-input   v-model="form2.mac" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="视频地址" prop='video'  :label-width="formLabelWidth">
			<el-input   v-model="form2.video" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="摄像头编码" prop='camera'  :label-width="formLabelWidth">
			<el-input   v-model="form2.camera" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="经度" prop='longitude'  :label-width="formLabelWidth">
			<el-input   v-model="form2.longitude" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="纬度" prop='latitude'  :label-width="formLabelWidth">
			<el-input   v-model="form2.latitude" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="PM2.5阈值" prop='PM25T'  :label-width="formLabelWidth">
			<el-input   v-model="form2.PM25T" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="PM2.5校准" prop='PM25C'  :label-width="formLabelWidth">
			<el-input   v-model="form2.PM25C" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="PM10阈值" prop='PM10T'  :label-width="formLabelWidth">
			<el-input   v-model="form2.PM10T" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
			<el-form-item label="PM10校准" prop='PM10C'  :label-width="formLabelWidth">
			<el-input   v-model="form2.PM10C" autocomplete="off" style="width:300px"></el-input>
			</el-form-item>
		</el-form>

		<div slot="footer" class="dialog-footer">
			<el-button @click="dialogFormVisible2 = false">取 消</el-button>
			<el-button type="primary" @click="BtnOk2('Form2')"
      style="background-color:#BFDFAF; border-color:#BFDFAF;">确 定</el-button>
		</div>
		</el-dialog>
		<!-- 表单结束 -->

		<!-- 分页开始 -->
		<div class="page" style="position: absolute; bottom: 40px;right: 20px;">
			<!-- <el-pagination
        background
        layout="prev, pager, next"
        :total="1000">
      </el-pagination> -->
      <el-pagination
        background
        layout="prev, pager, next"
        :total="total"
        :page-size="pageSize"
        :current-page.sync="currentPage"
        @current-change="handleCurrentChange"
        >
      </el-pagination>
		</div>
		<!-- 分页结束 -->
	</div>
</template>

<script type="text/javascript">
import {formatDate } from '@/common/date.js'
// 哪里需要请求数据 就在哪里导入
import  axios from '@/http/axios.js'
export default{
  data(){
    return{
      input_id:'',
      input_name:'',
      tableData: [],

      //模态框的相关数据
      dialogFormVisible1:false,
      title:'激活设备',
      form1:{
        serialnum:'',
        //devkey:''
      },
      formLabelWidth:'100px',
      id:'',
      idDis:false,
      rules1: {
        serialnum:[{required:true,message:'设备编号不能为空'}]
      },

      //模态框的相关数据
      dialogFormVisible2:false,
      title:'详情',
      form2:{
        serialnum:'',
        deviceName:'',
        line:'',
        ip:'',
        mac:'',
        video:'',
        camera:'',
        longitude:'',
        latitude:'',
        PM25T:'',
        PM25C:'',
        PM10T:'',
        PM10C:''
      },
      formLabelWidth:'100px',
      id:'',
      idDis:false,
      rules2: {
        ip:[{required:true,message:'ip地址不能为空'}],
        mac:[{required:true,message:'mac地址不能为空'}],
      },

     //和分页相关的变量 
      total:1,    //总页数,默认为1
      currentPage:1,  //当前页数,默认为1
      pageSize:5,     //每页显示数量
      currentPageData:[], //当前页显示内容
      serialnum:'',
      deviceName:'',
    }
  },
  // search  我希望 在输框里输入数据  search  会跟着变  v-model  双向绑定
  // 数据监听
  // watch:{
  //   'search':function(){
  //     this.GetAllData();
  //     console.log(this.search);
  //   }
  // },
  created(){
    //向后台请求 用户数据
    this.GetAllData();
  },
  methods:{
    handleCurrentChange(val){
      //筛选条件变了 重新获取值
      this.GetAllData();
    },
    clearText(){
        this.input_id='';
        this.input_name='';
        this.GetAllData();
    },
    Search(){
      axios.get('/device/Device/'+this.input_id+'/',{
        serialnum:this.input_id,
      })
        .then((response)=>{
            console.log("如果成功:",response);
            this.tableData=[response.data.data]; 
            //alert(response.data.data[serialnum])
            console.log(response.data.data)
            this.$notify.success({
            title: '成功',
            message: '查询成功!!!'
          });
        }).catch((error)=>{
          this.$notify.error({
            title: '失败',
            message: '查询失败!!!'
          });
          console.log(error)// 打印失败的信息
        })
    },
    GetAllData(){
      // 后台会提供一个接口  
      //axios  访问后台接口  获取数据  
      //this.tableData=获取的数据
      //第一个参数 url
      //let url='http://175.24.65.80:8000/device/get';
      let url='/device/get';
      // 第二个参数 请求的参数
      axios.get(url,{
        //分页的参数
        page_size:this.pageSize,
        page:this.currentPage,
        serialnum:this.serialnum,
        deviceName:this.deviceName,
      })
      .then((response)=>{
        // 后台传来什么样的值
        console.log(response);
        //返回正确的对象,包含所有需要的属性
        this.tableData=response.data.data.results;
        this.total=response.data.data.count;
        //alert(this.total);
        //map 数组里所有值进行统一操作  item  子的数组中单个值本身
        this.tableData=response.data.data.results.map((item)=>{
          //item.line=item.line?'在线':'离线'
          //item.active=item.active?'已激活':'未激活'
          return item;
        })
        console.log("表格数据:",this.tableData);
      }).catch((error)=>{
        //错误提醒
        this.$notify.error({
          title: '失败',
          message: '获取数据失败'
        });

      })
    },
    Add(){
      this.title='激活设备'
      this.dialogFormVisible1=true;
      this.form1={};
      this.idDis=false;
    },
    //确认新增的按钮
    BtnOk1(formName){
      this.$refs[formName].validate((valid) => {
        if(valid){
          if(this.title=='激活设备'){
              //axios 发送数据到后台
              //转换时间格式
              //this.form.date=formatDate(this.form.date);
              //网址根据实际要改一下
              axios.put('/device/'+this.form1.serialnum+'/active',{
                active:1
              })
              .then((response)=>{
                  console.log("如果成功:",response);
                  this.GetAllData();
                  this.$notify.success({
                  title: '成功',
                  message: '激活成功!!!'
                });
              }).catch((error)=>{
                this.$notify.error({
                  title: '失败',
                  message: '激活失败!!!'
                });
                console.log(error)// 打印失败的信息
              })
          }
          this.dialogFormVisible1=false;
        }else{
          console.log('失败')
        }         
    })
    },
	  //详情
    Detail(row){
      this.title="设备详情";
      this.dialogFormVisible2=true;
      this.form2=row;
      //this.id=row.id;
      this.idDis=true;
    },
    //编辑
    Edit(row){
      this.title="编辑设备";
      this.dialogFormVisible2=true;
      this.form2=row;
      //this.id=row.id;
      this.idDis=true;
    },	
    //确认修改的按钮
    BtnOk2(formName){
      this.$refs[formName].validate((valid) => {
        if(valid){
          if(this.title=='设备详情'){
              //axios 发送数据到后台
              //转换时间格式
              //this.form.date=formatDate(this.form.date);
              //网址根据实际要改一下
              /*axios.post('/users/users/',this.form)
              .then((response)=>{
                  console.log("如果成功:",response);
                  this.GetAllData();
              }).catch((error)=>{
                this.$notify.error({
                  title: '失败',
                  message: '新增失败'
                });
                console.log(error)// 打印失败的信息
              })*/
          }
          if(this.title=='编辑设备'){
            //转换时间格式
              //this.form.date=formatDate(this.form.date);
              //网址根据实际要改一下
              axios.patch('/device/'+this.form2.serialnum+'/conf2',this.form2)
              .then((response)=>{
                this.$notify.success({
                  title: '成功',
                  message: '修改成功!!!'
                });
                console.log("如果成功:",response);
                this.GetAllData();
              }).catch((error)=>{
                alert('error!!!');
                this.$notify.error({
                  title: '失败',
                  message: '修改失败!!!'
                });
                console.log(this.form2)// 打印失败的信息
              })
          }
          this.dialogFormVisible2=false;
        }else{
          console.log('失败')
        }         
    })
    },
    //删除
    Delete(row){
      this.$confirm('此操作将永久冻结该设备, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
           ///  id  ==> 后台  我们要删除  删除  谨慎
           axios.put('/device/'+row.serialnum+'/delete',{
             active:0,
           })
           .then((response)=>{
             this.$notify.success({
                  title: '成功',
                  message: '冻结成功!!!'
                });
             this.GetAllData();
           }).catch((error)=>{
              this.$notify.error({
                  title: '失败',
                  message: '冻结失败!!!'
                });
           })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });       
    }
  }
}
</script>

<style type="text/css">
.customWidth{
  width:500px;
}
</style>

4 实习总结

本次实习过程中,我学习了web前端的开发知识,学会了如何用Axure做原型设计,包括界面的布局和按钮触发动作的设计;学会使用vue框架搭建项目,包括html、css、JavaScript这三种语言的用法与作用,页面渲染的方法,vue-router的路由重定向,axios向后端发送请求及接收请求的使用方法,element-ui、echarts、iconfont组件的用法。在短短的三周时间内能收获这么多知识,我感到很充实很开心很满足!

Web前端我做的界面有3个,分别是AirC首页、网格管理页面、设备管理页面。AirC首页包含设备实时气象参数和空气质量参数的查询,设备AQI排名信息和近7天空气质量参数的展示。网格管理页面包含网格的新增、查询、修改、绑定/解绑、删除操作。设备管理页面包含设备的激活、查询、修改、冻结操作。除此之外,还有列表展示、清空输入、表单验证等功能的实现。

在设计过程中我也真真切切地感受到了万事开头难这一真理!不管是原型设计还是前端开发,第一个界面永远需要花费最多的时间做出来。虽然现在看来并没有什么难度,但是最开始进行设计时,每个地方都会遇到bug,可能一上午就在解决bug中度过了,回头一看设计的页面并没有变化多少,未完成的工作只有晚上熬夜加班完成。

我认为我在这次实习过程中收获累累,不仅掌握了web前端项目的开发技能,还与团队中的队员们建立了很好的友谊!很开心能够和大家一起完成这次实习任务,过程中很快乐,就算是我们web前端三人组熬夜通宵写代码那会也是疲惫中带着快乐的!最后很想感谢老师们给予的帮助和队员们的鼓励,没有你们的支持我可能就完不成任务了。感谢学校为我们安排了一次这么好的生产实习活动,感谢实习单位的老师们细致地为我们讲解课程,还耐心地回答我们的各种奇奇怪怪的小问题!

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值