# 删除无用文件夹
删除routes、views、public 3个文件夹
# 修改app.js
```
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
//修改模板后缀为html
app.set('view engine', 'html');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', (req, res) => {
res.send('hello world!');
});
module.exports = app;
```
![](https://img.kancloud.cn/d1/48/d14825849bbe67c403077bc4a7036cd6_732x760.png)
# 查看浏览器
此时浏览器中只会输出hello world!
# 在应用根目录新建config.js保存将来的应用配置信息
```
var fs = require('fs');
var path = require('path');
module.exports = {
url: 'http://localhost:3000',
mysql: {
host: 'localhost',
user: 'root',
password: 'root',
database: 'myapp',
connectionLimit: 100,
timezone: '+08:00',
charset: 'utf8_general_ci',
},
}
```
# 安装mysql包
```
cnpm install mysql --save
```
**"mysql": "^2.18.1"**
![](https://img.kancloud.cn/99/c4/99c425cb9c6a80ca19b03cd491e05e83_511x210.png)
# 新建/libs/tools.js
```
var ejs = require('ejs');
var fs = require('fs');
var path = require('path');
//引用config.js
var config = require(__dirname + '/../config');
module.exports = {
//https://www.jb51.net/article/107406.htm
getUrlByParam: function (param) {
var url = "";
for (field in param) {
url += "&" + field + "=" + encodeURIComponent(param[field]);
};
return url == "" ? url : url.substring(1);
},
//分页函数
pagination: function (url, param, page, pagesize, total) {
page = parseInt(page);
let total_page = Math.ceil(total / pagesize);
let previous_disabled = "";
let next_disabled = "";
if (page <= 1) {
previous_disabled = "disabled";
}
if (page >= total_page) {
next_disabled = "disabled";
}
let previous_page = Math.max(page - 1, 1);
let next_page = Math.min(page + 1, total);
let first_page = 1;
let last_page = total_page;
let _p1 = param;
let p1 = this.getUrlByParam(Object.assign(_p1, { page: previous_page }));
let _p2 = param;
let p2 = this.getUrlByParam(Object.assign(_p2, { page: next_page }));
let _p3 = param;
let p3 = this.getUrlByParam(Object.assign(_p3, { page: first_page }));
let _p4 = param;
let p4 = this.getUrlByParam(Object.assign(_p4, { page: last_page }));
let url1 = '';
let url2 = '';
let url_first = '';
let url_last = '';
if (url.indexOf('?') > -1) {
url1 = url + '&' + p1;
url2 = url + '&' + p2;
url_first = url + '&' + p3;
url_last = url + '&' + p4;
} else {
url1 = url + '?' + p1;
url2 = url + '?' + p2;
url_first = url + '?' + p3;
url_last = url + '?' + p4;
}
if (previous_disabled == 'disabled') {
url_first = url1 = 'javascript:void(0);';
}
if (next_disabled == 'disabled') {
url_last = url2 = 'javascript:void(0);';
}
let html = `
<script>
function EnterPress(e){
var e = e || window.event;
if(e.keyCode == 13){
var page=Math.abs(parseInt(e.target.value));
if(!page) return;
if(page>${total_page}) return;
location.href='${url}${url.indexOf('?') > -1 ? '&' : '?'}page='+page;
}
}
</script>
<div class="paging_simple_numbers" style="width:500px;margin:0 auto;">
<ul class="pagination">
<li class="paginate_button page-item ${previous_disabled}">
<a href="${url_first}" class="page-link">首页</a>
</li>
<li class="paginate_button page-item previous ${previous_disabled}">
<a href="${url1}" class="page-link">上一页</a>
</li>
<li class="paginate_button page-item active">
<a href="javascript:void(0);" class="page-link">${page}/${total_page} [共${total}条]</a>
</li>
<li class="paginate_button page-item next ${next_disabled}">
<a href="${url2}" class="page-link">下一页</a>
</li>
<li class="paginate_button page-item ${next_disabled}">
<a href="${url_last}" class="page-link">尾页</a>
</li>
<li class="paginate_button page-item">
<input type="text" placeholder="页码" value="" size="2" style="margin-top:4px;" onkeyup="EnterPress()">
</li>
</ul>
</div>
`;
return html;
},
//现在的时间戳
////https://www.cnblogs.com/fozero/p/6959946.html
time: function () {
return parseInt(new Date().getTime() / 1000);
},
//2019-12-12 23:59:59 转 时间戳
strtotime: function (str) {
if (!str) return 0;
return parseInt(new Date(str).getTime() / 1000);
},
// 格式化日期,如月、日、时、分、秒保证为2位数
formatNumber: function (n) {
n = n.toString()
return n[1] ? n : '0' + n;
},
// 参数number为毫秒时间戳,format为需要转换成的日期格式
//data(value, 'Y-M-D h:m:s');
date: function (number = '', format = 'Y-M-D h:m:s') {
if (!number) {
number = this.time();
}
//增加 2020-04-16T11:29:10.000Z 类型的处理
let time = typeof (number) == 'object' ? number : new Date(number * 1000);
let newArr = [];
let formatArr = ['Y', 'M', 'D', 'h', 'm', 's'];
newArr.push(time.getFullYear());
newArr.push(this.formatNumber(time.getMonth() + 1));
newArr.push(this.formatNumber(time.getDate()));
newArr.push(this.formatNumber(time.getHours()));
newArr.push(this.formatNumber(time.getMinutes()));
newArr.push(this.formatNumber(time.getSeconds()));
for (let i in newArr) {
format = format.replace(formatArr[i], newArr[i])
}
return format;
},
//数组合并
array_merge: function (a, b) {
return a.concat(b);
},
//对象合并
object_merge: function (a, b) {
let o = {};
return Object.assign(o, a, b);
},
//字符串重复
//http://www.manongjc.com/article/17174.html
str_repeat: function (str, num) {
return num > 1 ? str.repeat(num) : str;
},
//判断是否在数组中
in_array: function (value, arr) {
return arr.indexOf(value) > -1;
},
//判断是否在对象中
in_object: function (key, obj) {
key += '';
return typeof (obj[key]) != 'undefined';
},
//判断数组或对象是否为空
//https://www.jianshu.com/p/cbdd58749489
empty: function (d) {
if (d.constructor === Array) {
return d.length > 0;
} else {
return Object.keys(d).length > 0;
}
},
//获取文件后缀
//https://www.cnblogs.com/FallIntoDarkness/p/9757334.html
extension: function (filename) {
let index = filename.lastIndexOf(".");
let suffix = filename.substr(index + 1);
return suffix;
},
//生成从minNum到maxNum的随机数
//https://www.cnblogs.com/wenxuehai/p/10285585.html
randomNum: function (minNum, maxNum) {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1, 10);
break;
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
//或者 Math.floor(Math.random()*( maxNum - minNum + 1 ) + minNum );
break;
default:
return 0;
break;
}
},
//消息提示函数
msg: function (code, msg = '', url = '') {
if (code) {
if (!msg) msg = '操作成功';
}
if (!code) {
if (!msg) msg = '操作失败';
}
var str = fs.readFileSync(this.viewPath + 'msg.html', 'utf-8');
return ejs.render(str, { code: code, msg: msg, url: url });
},
//model加载函数
model: function (name) {
var m = require(this.modelPath + name + '.js');
return new m();
},
//myapp根目录
rootPath: path.normalize(__dirname + '/../'),
//应用目录
appPath: path.normalize(__dirname + '/../application/'),
//model目录
modelPath: path.normalize(__dirname + '/../application/models/'),
//视图目录
viewPath: path.normalize(__dirname + '/../application/views/'),
//控制器目录
controllerPath: path.normalize(__dirname + '/../application/controllers/'),
//runtime目录
runtimePath: path.normalize(__dirname + '/../runtime/'),
//mysql表缓存目录
tableCachePath: path.normalize(__dirname + '/../runtime/table/'),
//上传文件目录
uploadsPath: path.normalize(__dirname + '/../public/uploads/'),
//网站公共目录
publicPath: path.normalize(__dirname + '/../public/'),
};
```
# 建立所有文件夹
```
mkdir application
mkdir application/models
mkdir application/views
mkdir application/controllers
mkdir runtime
mkdir runtime/table
mkdir public
mkdir public/uploads
```
![](https://img.kancloud.cn/15/02/15022636f30e660e40801605ffbeb152_358x329.png)
# 新建/application/views/msg.html
```
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>系统提醒</title>
</head>
<body>
<div style="background:#4984DF;align:center;width:500px;margin:0 auto;">
<h2><% if(code){ %>操作成功<% }else{ %>操作失败<% } %></h2>
<h3><%=msg%></h3>
<script>
<% if(code){ %>
<% if(url){%>
setTimeout(function(){
location.href='<%=url%>';
},1000);
<% }else{ %>
window.history.back();
<% } %>
<% } %>
<% if(!code){ %>
setTimeout(function(){
window.history.back();
},3000);
<% } %>
</script>
</div>
</body>
</html>
```
# 新建/application/views/404.html
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404</title>
</head>
<body>
404
</body>
</html>
```
- 课程介绍
- 开发环境搭建
- 安装express.js框架
- 为diy自己的web框架做准备(1)
- 为diy自己的web框架做准备(2)
- 为应用绑定域名
- 封装控制器基类base.js
- 封装数据库操作基类model.js
- curd操作-准备工作
- curd操作-文章列表
- curd操作-添加文章
- curd操作-编辑文章
- curd操作-删除文章
- model文件的使用
- 文件上传
- session实现登录
- 邮件发送
- 文件下载
- 执行子任务
- 图片缩放
- 图片裁剪
- 图片验证码
- Excel读取与写入
- 编写计划任务
- 工具函数使用实例
- websocket
- 集成ckeditor
- 微信公众号开发-1:内网穿透
- 微信公众号开发-2:自动回复
- 微信公众号开发-3:api接口调用
- 微信公众号开发-4:oauth登录
- 微信公众号开发-5:沙箱支付
- 微信公众号开发-6:真实支付
- 项目上线运行
- 项目代码下载