Node 实现一个MVC相册资源管理器

暂没有数据库,所以做的也是本地的资源管理器。

Node 实现一个MVC相册资源管理器_第1张图片

 

Node 实现一个MVC相册资源管理器_第2张图片

Node 实现一个MVC相册资源管理器_第3张图片

总体设计:

 

Node 实现一个MVC相册资源管理器_第4张图片

 

 

 app.js:

var express = require("express");

var app = express();
//控制器
var router = require("./controller");
//设置模版引擎
app.set("view engine","ejs");

//路由中间件
//静态页面
app.use(express.static("./public"));
app.use(express.static("./uploads")); //get/的时候,上层函数回调的时候传入req,res //首页 app.get("/",router.showIndex); app.get("/:albumName",router.showAlbum); app.get("/up",router.showUp); app.post("/up",router.doPost); //404 app.use(function (req,res) { res.render("err"); }); app.listen(3000);

用express静态出public和uploads文件夹,用来放资源文件,然后分别路由主页,相册文件夹,上传页面,上传表单处理。

 

然后在控制层的controller来控制前台和后台的交互

router.js:

var file = require("../models/file.js");
var formidable = require("formidable");
var path = require("path");
var fs = require("fs");
var sd = require("silly-datetime");
exports.showIndex = function (req,res,next) { //错误的,传统的思维,不是Node的思维。 // res.render("index",{ // //注意这里异步的,遇到阻塞,会直接呈递模版引擎,所以这种写法是错误的,小函数会没执行完,就呈递了 // "albums" : file.getAllAlbums() // }); //这就是Node.js的编程思维,就是所有的东西,都是异步的 //所以,内层函数,不是return回来东西,而是调用高层函数提供的 //回调函数。把数据当做回调函数的参数来使用。 file.getAllAlbums(function (err,allAlbums) { //这个function就是callback //err是字符串 if(err) { next(); return; } res.render("index",{ "albums" : allAlbums }); }) }; //相册页 exports.showAlbum = function (req,res,next) { //遍历相册中的所有图片 var albumName = req.params.albumName; //具体业务交给model file.getAllImagesByAlbumName(albumName,function (err,imagesArray) { if(err) { next(); return; } res.render("album",{ "albumname" : albumName, "images" : imagesArray }); }); }; exports.showUp = function (req,res) { //命令file模块(我们自己写的函数)调用getAllAlbums函数 //得到所有文件夹名字之后做的事情,写在回调函数里面 file.getAllAlbums(function (err,albums) { res.render("up",{ albums : albums }); }) } //上传表单 exports.doPost = function (req,res) { var form = new formidable.IncomingForm(); // "../"返回上一级 form.uploadDir = path.normalize(__dirname + "/../tempup/"); form.parse(req, function (err, fields, files,next) { console.log(fields); console.log(files); //改名 if(err) { next(); //这个中间件不受理这个请求了,往下走 return; }; //判断文件尺寸 var size = parseInt(files.tupian.size); if(size > 2000000) { res.send("图片尺寸应该小于2M"); //则删除这个文件 fs.unlink("files.tupian.path",function () { }); return; } var wenjianjia = fields.wenjianjia; var oldpath = files.tupian.path ; //还是加时间戳 var ttt = sd.format(new Date(), "YYYMMDDHHmmss"); var ran = parseInt(Math.random() * 89999 + 10000); var extname = path.extname(files.tupian.name); var newpath = path.normalize(__dirname + "/../uploads/" + wenjianjia + "/" + ttt + ran + extname); fs.rename(oldpath,newpath,function (err) { if(err) { res.send("改名失败"); return; } res.send("成功"); }); }); }

 

底层的真正处理的模型层的file.js,注意的是由于这里没用es6的先进写法,所以很多是异步语句,正常的return返回是不行的,需要递归迭代来获得所有数据,用callback回调处理

var fs = require("fs");

//这个函数的callback中含有两个参数,一个是err
//另一个是存放所有文件夹名字的array。
exports.getAllAlbums = function (callback) {
    fs.readdir("./uploads", function (err,files) {
        if(err) {
            callback("没有找到upload文件",null);
        }
        var allAlbums = []; (function iterator(i) { if (i == files.length) { //遍历结束  console.log(allAlbums); //执行完了之后,执行回调函数 callback(null,allAlbums); return; } fs.stat("./uploads/" + files[i], function (err, stats) { if(err) { callback("找不到文件" + files[i],null); } if (stats.isDirectory()) { allAlbums.push(files[i]); } iterator(i + 1); }); })(0); }); } //通过文件名,得到所有图片 exports.getAllImagesByAlbumName = function (albumName,callback) { fs.readdir("./uploads/" + albumName, function (err,files) { if(err) { callback("没有找到upload文件",null); return; } var allImages = []; (function iterator(i) { if (i == files.length) { //遍历结束  console.log(allImages); //执行完了之后,执行回调函数 callback(null,allImages); return; } fs.stat("./uploads/" + albumName + "/" + files[i], function (err, stats) { if(err) { callback("找不到文件" + files[i],null); return; } if (stats.isFile()) { allImages.push(files[i]); } iterator(i + 1); }); })(0); }); }

 剩下的就是view视图层的前端样式了,用的ejs模板和bootstrap样式:

主页index.js:




    
    
    
    littleAlbum

    

    
    
    





<% for(var i = 0; i < albums.length; i++){ %>
...

<%= albums[i] %>

<% } %>

相册页album.ejs:




    
    
    
    littleAlbum

    

    
    
    







<% for(var i = 0; i < images.length; i++){ %>
<% } %>

up.ejs:




    
    
    
    小小相册

    

    
    
    





尺寸小于2M

Example block-level help text here.

err.ejs:




    
    
    
    littleAlbum

    

    
    
    





注意上传模块用的formidable,获得的files,fields对象参数,是和表单标签样式name属性对应的。

转载于:https://www.cnblogs.com/zhangmingzhao/p/7868421.html

你可能感兴趣的:(Node 实现一个MVC相册资源管理器)