使用"轻"语言搭建简易网站

网站搭建通常由多人相互配合完成;在整个开发过程中,需要涉及/数据库/后台管理/前端开发等等;基于简单的语言完成整个网站的构建,可以有助于了解网络的构成.在没有足够精力前提下,对其他领域知识’一知半解’也是很有用的,至少可以保证在接口对接等等情况时,可以有目的性的查找问题.

数据库—-sqlite

sqlite数据库算是所有数据库中,最小最轻量的了,基本字段只有五种:

  1. integer——整型
  2. real——浮点型
  3. text——字符串类型
  4. blob——字节流,将输入内容不改变进行存储
  5. null——空字段

在数据处理时,使用简单的字段类型,可以很方便的进行一些数据转换,从整体来看,sqlite有JS的某些特质;同时sqlite也是安卓端默认的数据库,因此对于移动开发人员会比较熟悉一些;

sqlite支持性比较好,在linux和window端均可以进行安装,具体内容可以参照 菜鸟教程-SQLITE,sqlite语法非常简单,使用起来很方便,对于小型系统而言,非常的适合。

后台—-Nodejs

nodejs自其2009出生以来,受到的广泛的关注,对于前端人员来说,javaScript已经炉火纯青,nodejs与原有的js相比,增量比较的小;由于V8引擎的存在,js运行速度足以达到大部分业务的需要;
重要的是,ES6 标准的出台,在使得开发规范的同时,引入了很多面向对象的特性,原有的js由于功能和语法的需要,不得不使用大量的闭包;面对大量的var,简直头晕脑胀;ES6则新引入局部变量let,类class等,使得js开发门槛大大降低;
当前nodejs社区也是异常的火热,大量的模块module被上传到npm中,真正实现了“插件式”开发;在需要某项功能时,一个require就可以解决所有。
网上有现成的界面渲染框架,只要稍微懂得jsp原理,就可以使用,这里选择使用较为简单的express-ejs框架模版。
express-ejs使用
nodejs集成sqlite数据库

前端框架

前端页面对于一个非专业人员来说,想看懂不难,但想实现绚丽的效果,就不是简单能够做到的,因此对于前端界面,这里选择克隆基于 bootstrap 前端框架。
框架模版下载地址

组合开发

在选定语言模版后,就可以着手进行小型服务器搭建了;

1、环境

首先需要选择某个操作平台,window/linux等,这里环境限制,我使用了window开发环境;安装nodejs开发环境,安装express插件。安装node环境。使用npm安装sqlite模块:

2、工具

下载一款良好的开发工具,我一般习惯使用webstorm,因为与AndroidStudio风格很相似。

3、创建项目

1、打开webstorm

2、使用express插件新建项目,在红线处设置项目名
这里写图片描述

3、项目创建后,会自动生成多个文件和文件夹

  • /bin 一般存放可执行的js文件
  • /node_modules 存放node项目开发过程中需要require的模块
  • /public 存放一些静态的文件,如css,html,字体,图片等等
  • /routes 路由文件,在网络请求时,express拦截器可以将相应请求拦截给指定的文件去处理
  • /views 模版文件,用于生成html文件或文本内容,ejs文件,可以通过 <%= %> 等方式进行渲染。
  • .gitignore 在项目上传至github 等git仓库时,配置不予上传的内容。
  • .app.js 主要的文件,在这里可以配置express的拦截方法,配置静态文件的寻找路径,错误异常处理等等。
  • package.json 包配置文件,其中记录了项目名,版本,依赖等等内容,在项目根目录下运行npm install 命令,会将配置的依赖模块进行安装。
  • package-lock.json 其他的一些依赖配置,一般不主动配置
  • README.md makedown文件,用于进行项目说明

4、导入前端模版

将下载好的html,js,css,img等图片导入项目中,放入public 目录。将首界面文件更改为ejs文件放入到views目录,用于填充数据后返回给客户端进行显示。

这里写图片描述

5、初始化数据库,配置app.js,生成路由类

1、先新建config.js文件,用于配置项目的host,port,数据库名称

这里写图片描述

代码块:

exports.dbName='company.db';
exports.host='localhost';
exports.port=80;

2、新建database.js文件,用于加载数据库:这里配置了模版界面中需要显示的信息、数据库表

这里写图片描述

代码块:

//file:test.js
var sqlite3 = require('sqlite3');
var debug = require('debug');
var globalConfig=require('../config');

//新建并创建表
var db;

//操纵实例
var singleInstance = {};

singleInstance.pageConfig = {
  company: '**科技',
  about: '关于',
  services: '服务',
  products: '产品',
  joinUs: '人才招聘',
  blog: '博客',
  contact: '联系我们',
  page: '界面元素',
  regulations: '制度',
  motto: '想法与实现之间,尚有很大的差距',
  mottoAuthor: 'Mark Simmons,Nett Media',
  introduce: '这是我们',
  introduceTitle: '激情,昂扬,拼搏,进取',
  introduceContent: '这是一个集体,这是我的家,这里有技术大牛,有商务精英,有销售专家,更有尊敬的领导...',
  productsBelief: '我们是一个信誉良好的网络公司',
  moreBlog: '查看更多博客',
  address: '**街道,**区<br>郑州,河南',
  email: '***@***.com',
  phone: '180 **** ****',
  getContact: '如果对本公司有****,......,请与我们取得联系',
  submitUrl: '/postSubject'
};


singleInstance.getDB = function () {
  if (db) return db; else throw "数据库未创建,请先调用 initDB 方法";
};

/**
 * 验证用户账户
 *
 * @param account 帐号
 * @param password 密码
 * @param callback 回调函数,包含两个参数:err,data,若成功则err为null,若查询不到数据,则data为undefined,否则data为有效数据
 */
singleInstance.checkRootAccount = function (account, password, callback) {
  db.get("select * from " + TABLE_MEMBER + " where account=$account and password=$password", account, password, callback)
};

/**
 * 查询博客信息
 *
 * @param limit 限制获取多少条数据,小于0表示不处理
 * @param orderBy 以哪个字段排序
 * @param orderType 排序方式,默认>0为升序,<0为降序,0表示不处理
 * @param callback 回调,err,rows[多个数据为数组形式]
 */
singleInstance.queryTableBlog = function (limit, orderBy, orderType, callback) {
  var order = '';
  if (orderType) {
    order = " order by " + orderBy + " " + (orderType > 0 ? "ASC" : "DESC") + " ";
  }

  limit = limit < 0 ? "" : " limit " + limit + " ";
  db.all("select * from " + TABLE_BLOG + order + limit, callback);
};

/**
 * 向数据库中写入建议信息
 *
 * @param callback 回调,err,rows[多个数据为数组形式]
 * @param obj js对象,键和值对应数据库中字段
 */
singleInstance.insertTableSuggestions = function (obj, callback) {
  var keys = '';
  var values = '';
  for (var key in obj) {
    keys += "," + key;
    values += ",'" + obj[key] + "'";
  }
  if (Object.keys(obj)) {
    keys = keys.substring(1);
    values = values.substring(1);
  }
  var sql = "insert into " + TABLE_SUGGESTIONS + "(" + keys + ") values(" + values + ");";
  db.run(sql, callback);
};

/**
 * 获取职位对应的字符串形式
 */
singleInstance.getJOINType = function (id) {
  switch (id) {
    case 0:
      return '总经理';
    case 1:
      return '软件开发人员';
    case 2:
      return '硬件开发';
    case 3:
      return '前端开发';
    case 4:
      return '安卓开发';
  }
  return '普工';
};

/**
 * 获取职工类型
 */
singleInstance.getStaffDuty = function (duty) {
  switch (duty) {
    case 0:
      return '职员';
    case 100:
      return '项目组长';
    case 200:
      return '总监';
    case 300:
      return '经理';
    case 400:
      return '总经理';
    case 500:
      return '董事长';
  }
  return '临时工';
};


//数据库表
var TABLE_INFO = 'table_info';
var TABLE_STAFF = 'table_staff';
var TABLE_SERVICE = 'table_service';
var TABLE_PRODUCT = 'table_product';
var TABLE_BLOG = 'table_blog';
var TABLE_MEMBER = 'table_member';
var TABLE_JOIN = 'table_join';
var TABLE_REGULATIONS = 'table_regulations';
var TABLE_SUGGESTIONS = 'table_suggestions';

var defaultConfig = {
  dbName: '../database/'+globalConfig.dbName,
  tables: [
    //省略创建其他表

    //公司内部人员博客:博客编号,图片,员工id,笔名,标题,简介,博客地址
    {
      name: TABLE_BLOG,
      columns: ['id', 'icon', 'staff_id', 'pen_name', 'title', 'brief', 'address', 'weight', 'time'],
      types: ['integer primary key autoincrement', 'text', 'integer', 'text', 'text', 'text', 'text', 'integer', 'integer, FOREIGN KEY (staff_id) REFERENCES '+TABLE_STAFF+'(id)']
    }
  ]
};

exports.initDB = function (config) {
  if (!db) {
    if (!config) config = defaultConfig;
    db = new sqlite3.Database(config.dbName, function (err) {
      if (err) throw "数据库创建失败:\n" + err;

      //页面配置表
      var create_table = '';
      var item;
      for (var k = 0; k < config.tables.length; k++) {
        item = '(';
        for (var i = 0; i < config.tables[k].columns.length; i++) {
          item += config.tables[k].columns[i] + " " + config.tables[k].types[i];
          if (i == config.tables[k].columns.length - 1) {
            item += ')';
          } else {
            item += ','
          }
        }
        create_table += "create table if not exists " + config.tables[k].name + item + ";";
      }
      debug.log(create_table);
      db.exec(create_table, function (err) {
        if (err) throw "无法创建TABLE" + err;
      });
    });
  }
  return singleInstance;
};

3、配置app.js文件,设定路由拦截,静态文件选择路径,同时将ejs模版渲染需要的数据绑定到app.locals 上,声明周期为全局。

这里写图片描述

代码块:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var debug = require('debug');
var dbInstance = require('./src/database').initDB();
var ejs = require('ejs');
var fs=require('fs');

var welcome = require('./routes/welcome');
var users = require('./routes/users');
var reboot = require('./routes/reboot');

var app = express();

//定义log
var log = debug.log;
debug.log = function (msg) {
    log("=====BEGIN");
    log(msg);
    log('=====END\n');
};

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

/**
 * 更新app.locals数据
 */
function initAppLocals() {
  ///////////////////////////////////////////////////// 从数据库中获取最新记录
  /**
   * 设定界面元素显示信息
   */
  app.locals.pageConfig = dbInstance.pageConfig;

  /**
   * 博客消息
   */
  dbInstance.queryTableBlog(5, 'weight', -1, function (err, data) {
    app.locals.tableBlog = data;
    debug.log(data);
  });

  //省略其他表初始化过程

  /**
   * 内部方法,提供数据格式转换
   */
  app.locals.getStaffDuty=dbInstance.getStaffDuty;
  app.locals.getJOINType=dbInstance.getJOINType;
/////////////////////////////////////////////////////
}
initAppLocals();
exports.initAppLocals=initAppLocals;

//拦截器,再次拦截
app.use('/users', users);

//重新从数据库中加载数据
app.use('/reboot', reboot);

//提出建议内容
app.use(dbInstance.pageConfig.submitUrl,function (req,res,next) {
  var name=req.body['name'];
  var email=req.body['email'];
  var subject=req.body['subject'];
  var content=req.body['content'];
  var time=new Date().getTime();
  dbInstance.insertTableSuggestions({
    name:name,
    email:email,
    subject:subject,
    content:content,
    time:time
  },function (err) {
    if(!err){
      res.end('success');
    }else{
    res.end('error');
    }
  });
});

//如果是html中访问css,js等文件,则修改路径的规则
app.use('/public',function (req, res, next) {
  console.log(req.url);
  fs.readFile(path.join(__dirname,req.baseUrl,req.url), function (err, data) {
    if (err) {
      res.end();
    }
    res.end(data);
  });
});

//加载首页信息
app.use('/index',welcome);
app.use('/*', function (req, res, next) {
  res.redirect('/index');
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handler
app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;

4、模版渲染,将app.locals 对象上的数据渲染到ejs模版中,生成html内容,在客户端访问时返回给客户端。

这里写图片描述

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title><%= pageConfig.company %></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">
    <!-- css -->
    <link href="../public/css/bootstrap-responsive.css" rel="stylesheet">
    <link href="../public/css/style.css" rel="stylesheet">
    <!-- skin color -->
    <link href="../public/color/default.css" rel="stylesheet">
    <!--[if lt IE 7]>
    <link href="../public/css/font-awesome-ie7.css" type="text/css" rel="stylesheet">
    <![endif]-->
    <link rel="shortcut icon" href="../public/img/favicon.ico">

</head>
<body>

<!-- navbar头部 -->
<div class="navbar-wrapper">
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="navbar-inner">
            <div class="container">
                <!-- Responsive navbar -->
                <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"><span
                            class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
                </a>
                <%# 加载导航栏数据%>
                <h1 class="brand"><a tppabs="#" disabled="true"><%= pageConfig.company %></a></h1>
                <!-- navigation -->
                <nav class="pull-right nav-collapse collapse">
                    <ul id="menu-main" class="nav">
                        <li><a title="team" href="#about"><%= pageConfig.about %></a></li>
                        <li><a title="services" href="#services"><%= pageConfig.services %></a></li>
                        <!--<li class="hidden"><a title="products" href="#products"><%= pageConfig.products %></a></li>-->
                        <li><a title="joinUs" href="#joinUs"><%= pageConfig.joinUs %></a></li>
                        <li><a title="blog" href="#blog"><%= pageConfig.blog %></a></li>
                        <li><a title="regulations" href="#regulations"><%= pageConfig.regulations %></a></li>
                        <li><a title="contact" href="#contact"><%= pageConfig.contact %></a></li>
                        <li class="hidden"><a href="../public/page.html"><%= pageConfig.page %></a></li>
                    </ul>
                </nav>
            </div>
        </div>
    </div>
</div>

<!-- Header area -->
<div id="header-wrapper" class="header-slider">
    <header class="clearfix">
        <div class="logo">
            <img src="../public/img/logo-image.png" alt=""/>
        </div>
        <div class="container">
            <div class="row">
                <div class="span12">
                    <div id="main-flexslider" class="flexslider">
                        <ul class="slides">
                            <%# 首页欢迎内容,海报%>
                            <% for(var position in tableInfo) { %>
                            <li>
                                <p class="home-slide-content">
                                    <%= tableInfo[position].title %>
                                </p>
                            </li>
                            <% } %>
                        </ul>
                    </div>
                    <!-- end slider -->
                </div>
            </div>
        </div>
    </header>
</div>

<%# 座右铭%>
<!-- spacer section -->
<section class="spacer green">
    <div class="container">
        <div class="row">
            <div class="span6 alignright flyLeft">
                <blockquote class="large">
                    <%= pageConfig.motto %> <cite><%= pageConfig.mottoAuthor %></cite>
                </blockquote>
            </div>
            <div class="span6 aligncenter flyRight">
                <i class="icon-coffee icon-10x"></i>
            </div>
        </div>
    </div>
</section>
<!-- end spacer section -->

<!-- section: team -->
<%# 员工信息 %>
<section id="about" class="section">
    <div class="container">
        <h4><%= pageConfig.introduce %></h4>
        <div class="row">
            <div class="span4 offset1">
                <div>
                    <h2><%= pageConfig.introduceTitle %></h2>
                    <p><%= pageConfig.introduceContent %></p>
                </div>
            </div>
            <div class="span6">
                <div class="aligncenter">
                    <img src="../public/img/icons/creativity.png" alt=""/>
                </div>
            </div>
        </div>
        <div class="row">
            <% for(var item in tableStaff) { %>
            <div class="span2 <%= item == 0 ? 'offset1' : '' %> flyIn">
                <div class="people">
                    <img class="team-thumb img-circle" src="<%= tableStaff[item]['icon'] %>" alt=""/>
                    <h3><%= tableStaff[item]['name'] %></h3>
                    <p>
                        <%= getStaffDuty(tableStaff[item]['duty']) %>
                    </p>
                </div>
            </div>
            <% } %>
        </div>
    </div>
    <!-- /.container -->
</section>
<!-- end section: team -->

<!--省略其他数据加载部分-->

6、数据填充

在数据库中插入虚假的信息,填充网页内容。
这样服务端以及数据库就已经完成了,然后针对前端显示的效果进行微调,然后进入bin 目录执行命令:node www 启动服务,此时可以使用浏览器访问本地地址:http:/localhost/

=============================

整理整个项目放入github上,其中前端框架放在public 目录中。

GITHUB地址:https://github.com/lovingning/CompanyGateway

=============================

猜你喜欢

转载自blog.csdn.net/lovingning/article/details/78369211