sails mvc 服务器 和 echarts 报表系统。

sails的安装,见官方原文:http://sailsjs.org

本文附件:http://www.oschina.net/code/snippet_867090_43467

开始:

1.sails 输入命令 sails new <appName> 则新建一个新的web项目。

2. 切换到指定目录,输入命令 sails lift 启动,默认程序监听1337 端口,可以通过 参数 --port 端口 指定自定义端口。

3.浏览器访问localhost://1337 就可以看到首页了,很方便。

4.第一个controller,sails generate api <foo> [action1:type1, action2:type2]

在api/controllers 目录下生成了一个FooController ,并且这个controller有两个action.

5.配置路由,在config/routes.js 中配置路由。

module.exports = {
  'get /signup': { view: 'conversion/signup' },  'post /signup': 'AuthController.processSignup',
  'get /login': { view: 'portal/login' },  'post /login': 'AuthController.processLogin',  '/logout': 'AuthController.logout',  'get /me': 'UserController.profile'}

新添加一个路由:'get /foo':'FooController.action1'

7.访问localhost:1337/foo 可以看到一个返回的一个json。

8.数据库连接,系统默认带一个orm. 但是因为我的业务部需要model.所以暂时不用,我需要从数据库中拿到数据,处理后返回client。所以我用 node-mysql 可以通过npm安装。使用见手册 node mysql

9.在 api/services下面建立DbService, 负责数据曾操作。

var mysql = require('mysql');
var log4js = require('log4js');

var pool = mysql.createPool(sails.config.connections.mySql);
log4js.configure(sails.config.log);
var logger = log4js.getLogger('logInfo');


/*******************************/
module.exports = {
    getData: function(sql, cb) {
        if (sql) {
            pool.getConnection(function(err, conn) {
                conn.query(sql, function(err, sqlData) {
                    if (err == null) {
                        var colNames = [];
                        for (col in sqlData[0]) {
                            colNames.push(col);
                        }

                        var len = sqlData.length;
                        var temp = {};
                        for (i = 0; i < len; i++) {
                            for (j = 0; j < colNames.length; j++) {
                                if (!temp[colNames[j]]) {
                                    temp[colNames[j]] = [];
                                }
                                temp[colNames[j]].push(sqlData[i][colNames[j]])
                            }
                        }
                        cb(temp);
                    }

                });
                conn.release();
            })
        } else {
            cb(null);
        }
    }

}

传入sql 语句和callback 方法,查询后,调用callback。

10. controller 代码:

/**
 * HomeController
 *
 * @description :: Server-side logic for managing homes
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */
var log4js = require('log4js');
var fs = require('fs');
log4js.configure(sails.config.log);
var logger = log4js.getLogger('logInfo');

module.exports = {
    /**
     * `HomeController.action1()`
     */
    action1: function(req, res) {
        if (!req.query.tag) {
            return res.json({
                err: "请指定tag."
            });
        }
        var opt = ReportService.getOpt(req.query.tag);
        var setData = opt.dataParse || ReportService.setData;
        //do some thing for opt
        async.parallel([
                function(callback) {
                    DbService.getData(opt.sql, function(data) {
                        callback(null, data);
                    });
                },
                function(callback) {
                    DbService.getData(opt.note, function(data) {
                        callback(null, data);
                    });
                }
            ],
            // optional callback
            function(err, results) {
                if (err) {
                    logger.err(err);
                    return;
                }
                if (results[0]) {
                    try {
                        setData(opt, results[0]);
                    } catch (error) {
                        console.log(error);
                    }
                }
                results[1] = results[1] ? results[1] : {
                    "note": [""]
                };
                ReportService.setNote(opt, results[1]);

                return res.json(opt);
            });


    },


    /**
     * `HomeController.report()`
     */
    report: function(req, res) {
        var name = req.param('name');
        var path = './reportConfig/' + name + ".js";
        fs.exists(path, function(exists) {
            if (exists) {
                var data = JSON.parse(fs.readFileSync(path, 'utf-8'));
                data.Reports = _.sortBy(data.Reports, 'order');
                res.view('report', data);
            } else {
                res.status(404);
                res.view('404', {
                    error: '哎呀!报表 ' + name + ' 没找到呀!'
                });
            }
        })



        //return res;
    },


    /**
     * `HomeController.action3()`
     */
    action3: function(req, res) {
        return res.json({
            todo: 'action3() is not implemented yet!'
        });
    }
};

根据参数,读取报表配置,从报表配置中读取sql,然后查询数据库,将结果根据配置的方法,塞入对象,将对象传递给前台,echarts 读入对象,生成图像。后台完成。

11.前端,sails 自己带了一个html引擎,可以通过js 来写html 很爽。这是一个例子,根据配置,生成html页面,返回给前端。

<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="ECharts">
    <meta name="author" content="yanggaofei@cyou-inc.com">
    <title>ECharts · Example</title>

    <link rel="shortcut icon" href="../asset/ico/favicon.png">
    <link href="/css/bootstrap.css" rel="stylesheet">
    <link href="/css/echartsHome.css" rel="stylesheet">
    <link href="/css/bar.css" rel="stylesheet">
    <link href="/css/animate.css" rel="stylesheet">
    <script src="/js/esl/esl.js"></script>
    <style type="text/css">
    @media(min-width: 1300px){
        .container {
        width: 1300px;
        }
    }

    .home{
        text-align: center;
        margin-top: 200px;
        font-size: 50px;
    }

    .home h1{
        color: #f35626;
        background-image: -webkit-linear-gradient(92deg,#f35626,#feab3a);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        font-size: 50px;
    }

    .chart1{
        height: 400px;
    }

    .chart4{
        height: 300px;
    }



    </style>
</head>

<body>
    <!--报表的宽度变量-->
    <% var chart_1 = 'col-md-10' %>
    <% var chart_4 = 'col-md-5' %>
    <!---->

    <!-- Fixed navbar -->
    <!--<div class="navbar navbar-default navbar-fixed-top" role="navigation" id="head"></div>-->
    <div class="container featurette">
        <div class="row page">
        <h2>
            <a name="-"></a>
            <span>-</span>
        <span>第<%= SeriesNum %>期</span>
        </h2>
        <div class="col-md-10 home bounceInLeft animated"  >
               <h1><span>EMT</span> 经济报表第<%= SeriesNum %>期</h1>
               <h4><%= Date %>&nbsp;&nbsp;&nbsp;<%= Author %></h4>
         </div>
        </div>
        <% Reports.forEach(function(r){ %>
        <div class="row page">
        <h2>
            <a name="<%= r.order %>" tag="<%= r.tag %>" count=<%= r.count%> ></a>
            <span><%= r.order %></span>
        <span><%= r.title %></span>
        </h2>
            <div id="graphic" >
                <% for(i=1;i<=r.count;i++){ %>
                <div class="<%= r.count==1?chart_1:chart_4 %>">
                    <div id="<%= 'main_'+r.tag + '_' + i %>" class="<%= 'chart'+r.count %>"></div>
                    <div id="<%= 'main_note_' + r.tag + '_' + i %>"></div>
                </div>
                <% } %>
            </div>
        </div>
        <% }) %>

    </div>

    <div id="scroll"></div>

    <footer id="footer"></footer>
    
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript" src="/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="/js/jquery.easing.min.js"></script>
    <script type="text/javascript" src="/js/scrollBar.js"></script>
    <script type="text/javascript">
    require.config({
        paths:{ 
             echarts:'/js/echarts-map'
        }
    });

    function showChart(tag){
        if(tag == 'undefined'){
            return;
        }
        var count = $('a[tag="'+tag+'"]').attr('count');
        count = count||1;
        
        tags=[];
        for(i=1;i<=count;i++){
            tags.push(tag +'_'+ i);
        }
       
        require(
            [
                'echarts'
            ],
            function (ec) {
                $(tags).each(function(i,_tag){
                var chart = $('#main_' + _tag).get(0);
                var note = $('#main_note_' + _tag);

                var myChart = ec.init(chart);
                myChart.showLoading({text:'正在加载数据'});
                $.getJSON('/home/action1?tag='+_tag,function(opt){
                    myChart.setOption(opt);
                    myChart.hideLoading();
                    note.html(opt.note.note[0]).minAnimate('fadeInLeft');
                });
            });
        })
    }

    //init
    $('#scroll').scrollBar(showChart);
    $('.page').height(window.screen.availHeight)
    $(function(){
        $('body').animate({scrollTop: 0}, 'normal', 'easeInOutQuad');  
    })

    </script>
</body>
</html>

可以看到 <%%> ejs的语法,将要解析的语句用<%> 扩起来,系统将解析这些语句。语法是javascript的语法。使用的时候,传入json对象。比如在controller里。res.view('report', data); 返回report.ejs 并且用data进行解析。

12. 页面截图:

151843_5bwS_867090.jpg

151843_cw8k_867090.jpg

151843_Kb5R_867090.jpg


转载于:https://my.oschina.net/u/867090/blog/339267

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值