专栏首页智慧城市Web开发---单页面应用(签到日报--技术实现)
原创

Web开发---单页面应用(签到日报--技术实现)

疫情前期,员工分布在各个地区,需要上报个人的健康状态和位置信息,于是做了一个单页面应用(当时钉钉和微信上的健康上报模板还没出现)

本文介绍前端和后台实现。由于是单页面程序,它的实现代码还是比较复杂的。

html代码:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>{{size}}人已签到</title>

    <!-- Bootstrap -->
    <link href="../static/lib/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
      <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>

    <![endif]-->
    <style type="text/css">
        #allmap {
            width: 100%;
            height: 400px;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }

        .BMapLabel {

            display: inline-block;
            max-width: none;
            margin-bottom: none;
            font-weight: 700;
        }

    </style>
    <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=rl0GVGPlvwnpfoaXsm65y9GEM7l1YFn0"></script>
    <script type="text/template" id="panelsTemplate">

        <% _.each(persons,function(item,index){ %>
     <% if ((index%2)==0) %>
     <div class="row">
     <% ; %>
  <div class="col-md-6" role="main">
                    <div class="panel panel-<%if(!!item['updateTime'])%>success<%else%>warning<%;%>" data-name=<%=item['name']%> id="panel_<%=item['name']%>">
                        <div class="panel-heading">
                            <h3 class="panel-title"><%=item['name']%>(<%if(!!item['updateTime'])%><%=item['updateTime']%><%else%>还未签到<%;%>)</h3>
                        </div>
                        <div class="panel-body">
                             
                           
                               <form class="form-horizontal" action="/report" method="post" enctype="multipart/form-data">
                               <input type="hidden" name="latlng" id="latlng" placeholder="0,0" value="<%=item['latlng']%>"/>  
                                <div class="form-group">
                                    <label for="name" class="col-sm-2 control-label">姓名</label>
                                    <div class="col-sm-10">
                                        <input type="text" class="form-control" readonly  name="name"  id="name"  value="<%=item['name']%>" placeholder="姓名">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label for="place" class="col-sm-2 control-label">所在地</label>
                                    <div class="col-sm-10">
                                        <input type="text" class="form-control" name="place" id="place"   placeholder="所在地" value="<%=item['place']%>">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="home" id="home" class="check" <%if(item['home'])%>checked<%else%><%;%>> 在家呆无外出
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="nocough" id="nocough" class="check" <%if(item['nocough'])%>checked<%else%><%;%>> 无发热咳嗽症状
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="health" id="health" class="check" <%if(item['health'])%>checked<%else%><%;%>> 个人状况良好
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="transport" id="transport" class="check" <%if(item['transport'])%>checked<%else%><%;%>> 返程交通受到影响
                                            </label>
                                        </div>
                                    </div>
                                    <div class="form-group">
                                        <label for="description" class="col-sm-2 control-label">其他补充</label>
                                        <div class="col-sm-10">
                                            <textarea class="form-control" name="description" id="description"   rows="3"  placeholder="补充说明"><%=item['description']%></textarea>
                                        </div>
                                    </div>

                                </div>


                                <div class="form-group">
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <button type="submit" class="btn btn-primary btn-lg" style="display: none;">提交</button>
                                        <a href="#top" class="btn btn-default btn-lg active" role="button">返回顶部</a>
                                    </div>
                                </div>
                            </form>
                            
                            
                        </div>
                    </div>
                </div>
            
        <% if ((index%2)==1 || index==persons.length-1) %>
     </div>
     <% ; %>
         <% })%>
    </script>

    <script type="text/template" id="namesTemplate">
        <% _.each(persons,function(item,index){ %>
           <button type="button" class="btn btn-<%if(!!item['updateTime'])%>success<%else%>default<%;%>" data-name=<%=item['name']%>><%=item['name']%></button>
            <% })%>
      </script>
    <script type="text/template" id="recordsTemplate">
        <% _.each(records,function(item,index){ %>
                            <tr>
                                <th scope="row"><%=index+1%></th>
                                <td><%=item['name']%></td>
                                <td><%=item['place']%></td>
                                
                                 <td><span class="glyphicon glyphicon-<%if(!!item['home'])%>ok<%else%>remove<%;%>" aria-hidden="true"></span></td>
                                <td><span class="glyphicon glyphicon-<%if(!!item['nocough'])%>ok<%else%>remove<%;%>" aria-hidden="true"></span>
                                
                               
                                 <td><span class="glyphicon glyphicon-<%if(!!item['health'])%>ok<%else%>remove<%;%>" aria-hidden="true"></span>
                                  
                                 <td><span class="glyphicon glyphicon-<%if(!!item['transport'])%>ok<%else%>remove<%;%>" aria-hidden="true"></span>
                                  <td><%=item['updateTime'].split(' ')[0]%>(<%=item['updateTime'].split(' ')[1]%></span>
                            </tr>
            <% })%>
      </script>


</head>

<body>


    <div class="container bs-docs-container">

        <div class="row" id="top">
            <div class="col-md-3" role="main">
                <button type="button" class="btn btn-success btn-lg btn-block" data-toggle="modal" data-target="#myModal"><a href="#" id="name" class="btn btn-success btn-lg btn-block" role="button" title="点击名字导航到表单"><span>芳名</span><span></span></a></button>
            </div>

            <div class="col-md-3" role="main">

                <button type="button" class="btn btn-info btn-lg btn-block" data-toggle="modal" data-target="#mapModal"><a href="#" id="place" class="btn btn-info btn-lg btn-block" role="button"><span>居住</span><span></span></a> </button>

            </div>
            <div class="col-md-3" role="main">

                <button type="button" class="btn btn-warning btn-lg btn-block" data-toggle="modal" data-target="#queryModal" disabled data-name="*" id="statistics"><a href="#" class="btn btn-warning btn-lg btn-block" role="button">我的统计</a> </button>

            </div>
            <div class="col-md-3" role="main">

                <button type="button" class="btn btn-danger btn-lg btn-block" data-toggle="modal" data-target="#queryModal" data-name="*"><a href="#" class="btn btn-danger btn-lg btn-block" role="button">所有人统计</a> </button>

            </div>

        </div>


        <div class="bs-example" data-example-id="contextual-panels" id="panelsContainter" style="display: none;">
            <div class="row hide">
                <div class="col-md-6" role="main">
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            <h3 class="panel-title">Panel title</h3>
                        </div>
                        <div class="panel-body">
                            <form class="form-horizontal" action="/report" method="post" enctype="multipart/form-data">
                                <input type="hidden" name="latlng" id="latlng" placeholder="0,0">
                                <div class="form-group">
                                    <label for="name" class="col-sm-2 control-label">姓名</label>
                                    <div class="col-sm-10">
                                        <input type="text" class="form-control" readonly name="name" id="name" value="<%=item%>" placeholder="姓名">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label for="place" class="col-sm-2 control-label">所在地</label>
                                    <div class="col-sm-10">
                                        <input type="text" class="form-control" name="place" id="place" placeholder="所在地">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="home" id="home" class="check"> 在家呆无外出
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="nocough" id="nocough" class="check"> 无发热咳嗽症状
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="health" id="health" class="check"> 个人状况良好
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <div class="checkbox">
                                            <label>
                                                <input type="checkbox" name="transport" id="transport" class="check"> 返程交通受到影响
                                            </label>
                                        </div>
                                    </div>
                                    <div class="form-group">
                                        <label for="description" class="col-sm-2 control-label">其他补充</label>
                                        <div class="col-sm-10">
                                            <textarea class="form-control" name="description" id="description" rows="3" placeholder="补充说明"></textarea>
                                        </div>
                                    </div>

                                </div>


                                <div class="form-group">
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <button type="submit" class="btn btn-primary" style="display: none;">提交</button>
                                        <a href="#top" class="btn btn-default btn-lg active" role="button">返回顶部</a>
                                    </div>
                                </div>
                            </form>

                        </div>
                    </div>
                </div>

            </div>

        </div>



    </div>

    <!-- Modal -->
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title" id="myModalLabel">{{size}}人已签到</h4>
                </div>
                <div class="modal-body">

                    <div class="row">
                        <div class="btn-group" role="group">
                            <button type="button" class="btn btn-default" id="clear">清除选择</button>
                            <button type="button" class="btn btn-primary" data-dismiss="modal">确定</button>
                        </div>

                    </div>
                    <div class="row" id="namesContainter"></div>

                </div>
                <div class="modal-footer">

                </div>
            </div>
        </div>
    </div>
    <!-- Modal -->
    <div class="modal fade" id="mapModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title" id="myModalLabel">我的位置</h4>
                </div>
                <div class="modal-body">
                    <div class="btn-group" role="group"><button type="submit" class="btn btn-primary" data-dismiss="modal">确定</button>
                        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button></div>
                    <div id="allmap"></div>
                </div>
                <div class="modal-footer">


                </div>
            </div>
        </div>
    </div>
    <div class="modal fade" id="queryModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog  modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title" id="myModalLabel">签到表</h4>
                </div>
                <div class="modal-body">
                    <div class="row">
                        <div class="col-md-6">
                            <div class="input-group">
                                <span class="input-group-addon">
                                    开始日期
                                </span>
                                <input type="date" class="form-control date" name="place" id="start">

                            </div><!-- /input-group -->
                        </div><!-- /.col-lg-6 -->
                        <div class="col-md-6">
                            <div class="input-group">
                                <span class="input-group-addon">
                                    结束日期
                                </span>
                                <input type="date" class="form-control date" name="place" id="end">
                            </div><!-- /input-group -->
                        </div><!-- /.col-lg-6 -->

                    </div><!-- /.row -->
                    <div class="row">


                        <div class="btn-group" role="group" aria-label="...">
                            <div class="btn-group" role="group">
                                <button type="button" class="btn btn-primary" id="search">查询</button>
                            </div>
                            <div class="btn-group" role="group">
                                <button type="button" class="btn btn-default" id="prev">&laquo;前一天</button>
                            </div>


                            <div class="btn-group" role="group">
                                <button type="button" class="btn btn-default" id="next">后一天&raquo;</button>
                            </div>
                            <div class="btn-group" role="group">
                                <a role="button" class="btn btn-primary" id="export" target="_blank">导出</a>
                            </div>
                        </div>

                    </div><!-- /.row -->
                    <div class="table-responsive">
                        <table class="table table-bordered">
                            <thead>
                                <tr>
                                    <th>#</th>
                                    <th>姓名</th>
                                    <th>所在地</th>
                                    <th>无外出</th>
                                    <th>无发热咳嗽</th>
                                    <th>个人状况良好</th>
                                    <th>返程交通受到影响</th>
                                    <th>签到时间</th>
                                </tr>
                            </thead>
                            <tbody id="recordsContainter">


                            </tbody>
                        </table>
                    </div>
                </div>
                <div class="modal-footer">

                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>

                </div>
            </div>
        </div>
    </div>

    <input type="hidden" id="report" value='{% raw reports%}' />
    <input type="hidden" id="cookie" value='{{ name}}' />
     <input type="hidden" id="company" value='{{ company}}' />
    <!--    <input type="hidden" id="report" value='[]' />-->


    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="../static/lib/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="../static/lib/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <script src="../static/lib/underscore.js"></script>
    <script src="
http://cdn.staticfile.org/moment.js/2.24.0/moment.js"></script>
    <script src="../static/js/report.js"></script>
</body>

</html>

javaScript代码如下:

$(function () {
    function centerAndZoom(){
        map.centerAndZoom(new BMap.Point(113.890598- 0.005, 33.748028+ 0.005), 7);
        
    }
    centerAndZoomOnce=_.once(centerAndZoom);
    fillName = function () {
        var name = $('#name').data('name');
        var address = $('#place').data('address');
        var latlng = $('#place').data('latlng');

        if (!!name && !!address) {
            $('#panelsContainter').find('.panel[data-name=' + name + ']').find('input#place').val(address);
            $('#panelsContainter').find('.panel[data-name=' + name + ']').find('input#latlng').val(latlng);
        }

    };
    // 百度地图API功能
    window.map = null;
    map = new BMap.Map("allmap");

    
    map.enableScrollWheelZoom(true);
    centerAndZoom();
    // 添加带有定位的导航控件
    var navigationControl = new BMap.NavigationControl({
        // 靠左上角位置
        anchor: BMAP_ANCHOR_TOP_LEFT,
        // LARGE类型
        type: BMAP_NAVIGATION_CONTROL_LARGE,
        // 启用显示定位
        enableGeolocation: true
    });
    map.addControl(navigationControl);
    // 添加定位控件
    window.geolocationControl = new BMap.GeolocationControl();
    geolocationControl.addEventListener("locationSuccess", function (e) {
        // 定位成功事件
        var address = '';
        address += e.addressComponent.province;
        address += e.addressComponent.city;
        address += e.addressComponent.district;
        address += e.addressComponent.street;
        address += e.addressComponent.streetNumber;
        alert("当前定位地址为:" + address);
        $("#place").data('address', address);
        fillName();
        $("#place span:first").text(address);
    });
    geolocationControl.addEventListener("locationError", function (e) {

        // 定位失败事件
        alert(e.message);
    });
    //map.addControl(geolocationControl);
    //geolocationControl.Vo.click();
    geolocationControl.location();
    var geolocation = new BMap.Geolocation();

    var label = new BMap.Label("拖拽调整定位", {
        offset: new BMap.Size(-30, -20)
    });
    window.mk = null;
    var myIcon = new BMap.Icon("/static/marker-icon.png", new BMap.Size(25, 41));
    mk = new BMap.Marker(new BMap.Point(114.746873, 33.968261), {
        icon: myIcon
    });
    mk.setLabel(label);

    mk.enableDragging();
    map.addOverlay(mk);
    geolocation.getCurrentPosition(function (r) {
        
        $("#place").data('latlng', r.point.lng + ',' + r.point.lat);

        if (this.getStatus() == BMAP_STATUS_SUCCESS) {
            mk.setPosition(r.point);

            alert('您的位置:' + r.point.lng + ',' + r.point.lat);
        } else {


            alert('failed' + this.getStatus());
        }

        //map.centerAndZoom(new BMap.Point(r.point.lng - 0.005, r.point.lat + 0.005), 16);
    }, {
        enableHighAccuracy: true
    });

    
    

    $('#myModal').delegate('#clear', 'click', function () {
        $('#namesContainter').find('button').removeClass('btn-primary').addClass('btn-default');

    });

    $('#queryModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget)
        var name = button.data('name');

        $(this).data('name', name);
        $("#search").trigger('click');
    })


     $('#mapModal').on('shown.bs.modal', function (event) {
        centerAndZoomOnce();
    })

    $('#myModal').on('shown.bs.modal', function (e) {
        var name = $('#cookie').val();

        $('#namesContainter').find('button[data-name=' + name + ']').removeClass('btn-success btn-default').addClass('btn-primary');
    });
    $('#myModal').on('hidden.bs.modal', function (e) {
        var name = $('#namesContainter').find('button.btn-primary').data('name');
        $('#panelsContainter').find('.panel').find('[type=submit]').hide();
        if (!!name) {

            $('#statistics').attr('disabled', false).data('name', name);
            $('#name').data('name', name).attr('href', "#panel_" + name);
            $('#name span:first').text(name);


            $('#panelsContainter').find('.panel[data-name=' + name + ']').find('[type=submit]').show();

            var col2 = $('#panelsContainter').find('.col-md-6[role="main"]').filter((x, y) => $(y).find('.panel').data('name') == name);
            var row1 = $('#panelsContainter .row:first');
            var col1 = row1.find('.col-md-6[role="main"]:first');
            if (!!col2) {
                var row2 = col2.parent();
                row1.prepend(col2);
                row2.prepend(col1);

            }



            $('#panelsContainter').show();
        } else {
            $('#statistics').attr('disabled', true);
            $('#name').data('name', "").attr('href', "#");
            $('#name span:first').text('芳名');
            $('#panelsContainter').hide();
        }
    });
    var geoc = new BMap.Geocoder();
    $('#mapModal').find("[type=submit]").click(function (e) {
        if (!!mk) {
            var latlng = mk.getPosition();


            $("#place").data('latlng', latlng.lng + ',' + latlng.lat);

            geoc.getLocation(latlng, function (rs) {
                var addComp = rs.addressComponents;
                address = addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber;
                alert(address);
                $("#place span:first").text(address);
                $("#place").data('address', address);
                fillName();
            });
        }
        $('#mapModal').modal('hide');
    });
    $('#namesContainter').delegate('button', 'click', function () {
        $(this).addClass('btn-primary').removeClass('btn-default').siblings().removeClass('btn-primary').addClass('btn-default');

    });
    report = $.parseJSON($("#report").val());
    report.filter((x, y) => !!x['latlng']).forEach((x, y) => {
        var lng = x['latlng'].split(',')[0];
        var lat = x['latlng'].split(',')[1];
        var point = new BMap.Point(lng, lat);

        var marker = new BMap.Marker(point); // 创建标注
        map.addOverlay(marker); // 将标注添加到地图中

        var label = new BMap.Label(x['name'], {
            offset: new BMap.Size(-12, -20)
        });
        marker.setLabel(label);

    });



    $.get('/static/mock/' + $('#company').val() + '.json', function (data) {

        if (location.hostname != "127.0.0.1") {
            //            data = $.parseJSON(data);
        }



        records = _.map(data.result, function (item) {
            var p = _.findWhere(report, {
                'name': item
            });
            if (!!p) {
                return p;
            } else {
                return {
                    "updateTime": "",
                    "name": item,
                    "place": "",
                    "description": "",
                    "nocough": false,
                    "home": false,
                    "health": false,
                    "transport": false
                };
            }
        });




        var panelsTemplate = _.template($('#panelsTemplate').html());
        $("#panelsContainter").html(panelsTemplate({
            persons: records
        }));

        $("#panelsContainter").find('form').submit(function (e) {
            e.preventDefault();

            var item1 = _.object($(this).find('input[placeholder],textarea').map((x, y) => {
                return [[$(y).attr('name'), y.value]]
            }));
            var item2 = _.object($(this).find('input.check').map((x, y) => {
                return [[$(y).attr('name'), y.checked]]
            }));
            var items = _.extend(item1, item2);
            var panel = $(this).parent().parent();
            $.post('report', items, function (data2) {
                var record = data2.result;
                panel.find('.panel-title').text(record['name'] + record['updateTime']);

                alert("保存成功");
                console.log(data2);
            });

        });

        var namesTemplate = _.template($('#namesTemplate').html());
        $("#namesContainter").html(namesTemplate({
            persons: records
        }));

        $(".date").val(moment().format(moment.HTML5_FMT.DATE));

        $("#prev").click(function () {
            $(".date").val(moment($('#start').val()).add(-1, 'day').format(moment.HTML5_FMT.DATE));
            $("#search").trigger('click');

        })
        $("#next").click(function () {

            $(".date").val(moment($('#start').val()).add(1, 'day').format(moment.HTML5_FMT.DATE));
            $("#search").trigger('click');
        })

        var recordsTemplate = _.template($('#recordsTemplate').html());


        $("#search").click(function () {

            var query = {
                start: $('#start').val(),
                end: $('#end').val(),
                name: $('#queryModal').data('name')
            };
            $.get('search', query, function (data) {
                var records = data.result;

                $("#recordsContainter").html(recordsTemplate({
                    records: records
                }));

                console.log(records);
            });
            $('#export').attr('href', location.pathname + 'export?' + $.param(query));
        })


    });

})

后台使用Python 的tornado作为Web框架,使用MongoDB作为数据库。

Python代码如下:

# -*- coding:utf-8 -*-
import os
import pandas as pd
import tornado.web
import tornado.httpserver
import tornado.ioloop

from datetime import datetime,timedelta
from tornado.options import define,options
import json
define('port',default=8099,type=int,help="input your port")
define('company',type=str,help="input your company")
define('db',type=str,help="input your dbName")
import pymongo
mongo=pymongo.MongoClient()
#t=mongo.report.day

oneDay=timedelta(days=1)

def getRecord(record):
    record['_id']=str(record['_id'])
    record['updateTime']=record['updateTime'].strftime('%Y-%m-%d %H:%M:%S')
    return record

class exportHandler(tornado.web.RequestHandler):
    def get(self):
        start1=self.get_argument('start')
        end1=self.get_argument('end')
        start=datetime.strptime(start1,'%Y-%m-%d')
        end=datetime.strptime(end1,'%Y-%m-%d')+oneDay
        name=self.get_argument('name')
        query={'updateTime':{'$gt':start,'$lt':end}}
        if(name!='*'):
            query['name']=name
        reports=t.find(query)
        reports=map(lambda x:getRecord(x),reports)
        if(len(reports)==0):
	    self.write(u"数据为空")
            return
        df=pd.DataFrame(reports)
        
        columns={'description':u'其他补充',"updateTime":u'签到时间',"health":u'个人状况',"name":u'姓名',"place":u'所在地',"home":u'外出',"nocough":u'发热咳嗽','transport':u'交通状况'}
        keys=['_id','latlng','name', 'place', 'home', 'nocough','health', 'transport','description','updateTime']        
       
        df[columns['name']]=df['name']
        df[columns['place']]=df['place']
        
        df[columns['home']]=df['home'].apply(lambda x:u'在家无外出' if x else u'有外出')
        df[columns['nocough']]=df['nocough'].apply(lambda x:u'无' if x else u'有')
        df[columns['health']]=df['health'].apply(lambda x:u'身体健康无恙' if x else u'身体欠安')
        df[columns['transport']]=df['transport'].apply(lambda x:u'交通受阻' if x else u'交通正常')
        df[columns['description']]=df['description']
        df[columns['updateTime']]=df['updateTime']
        for k in keys:
            del df[k]
        directory='static/excels'
        if not os.path.exists(directory):
            os.mkdir(directory)
        df.to_excel(directory+'/'+start1+'-'+end1+'.xls',index=False)
        self.redirect('/static/excels/'+start1+'-'+end1+'.xls')

       
class searchHandler(tornado.web.RequestHandler):
    def get(self):
        start=self.get_argument('start')
	end=self.get_argument('end')
        start=datetime.strptime(start,'%Y-%m-%d')
        end=datetime.strptime(end,'%Y-%m-%d')+oneDay
        name=self.get_argument('name')
        query={'updateTime':{'$gt':start,'$lt':end}}
        if(name!='*'):
            query['name']=name
        reports=t.find(query)
        reports=map(lambda x:getRecord(x),reports)
        self.write({'result':reports})

class reportHandler(tornado.web.RequestHandler):
    def get(self):
        name=self.get_cookie('name')
        yesterday=datetime.now().replace(hour=0,minute=0,second=0,microsecond=0)
	reports=t.find({'updateTime':{'$gt':yesterday}})
        reports=map(lambda x:getRecord(x),reports)
        self.render('report.html',reports=json.dumps(reports),size=len(reports),name=name,company=company)

    def post(self):
        yesterday=datetime.now().replace(hour=0,minute=0,second=0,microsecond=0)

        name=self.get_argument('name')
        self.set_cookie("name",name)       
        place=self.get_argument('place')
        
        description=self.get_argument('description') 
        latlng=self.get_argument('latlng','0,0')
        home=True if self.get_argument('home')=="true" else False
        nocough=True if self.get_argument('nocough')=='true' else False
        health=True if self.get_argument('health')=='true' else False
        transport=True if self.get_argument('transport')=='true' else False
        updateTime=datetime.now()
        record={"name":name,'place':place,'description':description,'home':home,'nocough':nocough,'health':health,'transport':transport,'updateTime':updateTime,'latlng':latlng}
	print(record)
        t.delete_many({'updateTime':{'$gt':yesterday},'name':name})
        t.insert(record)
        record['_id']=str(record['_id'])
        record['updateTime']=record['updateTime'].strftime('%Y-%m-%d %H:%M:%S')

        self.write({'result':record})
        return 

 
app=tornado.web.Application(
	handlers=[(r'/',reportHandler),
       
		(r'/report',reportHandler),
                (r'/search',searchHandler),
                (r'/export',exportHandler),
		],static_path=os.path.join(os.curdir,'static'),
        template_path=os.path.join(os.curdir,'template'),debug=True
        )
if __name__=='__main__':
        
    tornado.options.parse_command_line()
    company=options.company
    db=options.db
    t=mongo.report[db]
    httpserver=tornado.httpserver.HTTPServer(app)
    httpserver.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()




    

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python开发物联网数据分析平台---数据看板

    MiaoGIS
  • Python开发物联网数据分析平台---web框架

    前端使用Bootstrap主题框架AdminLTE,后台使用python语言的tornado作为web框架。利用tornado的模板作为主要的动态页面生成方式,...

    MiaoGIS
  • 高质量编码--传感器数据同比

    下面介绍其前端代码,先看html页面,使用boostrap作为样式和布局,引入了bootstrap-daterangepicker插件作为日期范围选择面板,引入...

    MiaoGIS
  • Java单体应用 - 项目实战(后台) - 03.后台账户管理 - 02.账户列表展示

    原文地址:http://www.work100.net/training/monolithic-project-iot-cloud-admin-manager-...

    光束云
  • 前端MVC学习总结(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例

    这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap。 示例名称:天狗...

    张果
  • 前端MVC学习总结(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例

    这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap。 示例名称:天狗...

    张果
  • bootstrap switch控件

    需要使用Bootstrap switch,实现通过、拒绝功能并且在开关至拒绝时,显示textarea框输入原因。

    用户5760343
  • idea-ssm-crud项目实战(三)

    前面已经搭建好了ssm框架了,这一章节就写一下员工的crud了,都是一步步来操作,前台页面使用的Bootstrap来操作。如果idea中搭建ssm不会的可以去看...

    用户5224393
  • Python测试开发-创建模态框及保存数据

    模态框是指的在覆盖在父窗体上的子窗体。可用来做交互,我们经常会看到模态框用来登录、确定等等,到底是怎么实现这种弹出效果,bootstrap已经为我们提供了相...

    测试开发社区
  • v­bind以及class与style的绑定-vue笔记4

    在数据绑定中,最常见的两个需求就是元素的样式名称 class 和内联样式 style 的动 态绑定

    bamboo

扫码关注云+社区

领取腾讯云代金券