• 【前端】Vue2全家桶案例《看漫画》之番外篇、express上传漫画(可选)


    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/vue_vux_app_extra_1.html

    项目github地址:https://github.com/shamoyuu/vue-vux-iconan

    这一篇属于后台内容,前端小伙伴可以选择阅读。

    接口后面都会公开,不会后台的小伙伴可以直接调用。

    首先图片存储。图片我会上传到百度的BOS里,是一个支持外链的存储空间,还提供了很多非常方便的功能,后面用到的时候会详细说。

    然后数据库用mysql。上传完图片后会把图片的信息都保存起来,方便我们后面调用。

    图片处理,会用到gm,因为有些漫画是左右两张放在一张图片上的,我们需要裁切成2份后再上传。

     

    首先我们建表,总共3个表,分别是漫画表(opus)、章节表(chapter)和图片表(picture)

    漫画表(opus)

    章节表(chapter)

    图片表(picture)

    然后我们来写一个router吧,它里面有3个接口,分别是添加漫画,重命名文件夹和批处理temp下文件夹。

    这个文件是运行在express里的,可以看我以前介绍的在百度BAE搭建node后台的教程:http://www.cnblogs.com/shamoyuu/p/node_bae.html

    var express = require("express");
    var request = require('request');
    var fs = require('fs');
    var router = express.Router();
    var _ = require("lodash");
    var Opus = require("../models/index").Opus;
    var Chapter = require("../models/index").Chapter;
    var Picture = require("../models/index").Picture;
    var gm = require("gm");
    
    var BosClient = require("bce-sdk-js").BosClient;
    
    const config = {
        endpoint: "https://bj.bcebos.com",   //传入Bucket所在区域域名
        credentials: {
            ak: "AccessKey",         //您的AccessKey
            sk: "SecretAccessKey"    //您的SecretAccessKey
        }
    };
    
    
    var client = new BosClient(config);
    
    /**
     * 啥都没有
     */
    router.get("/", function (req, res, next) {
        res.send({
            message: "成功",
            stateCode: 0
        });
    });
    
    /**
     * 添加一个漫画
     */
    router.get("/add", function (req, res, next) {
        
        Opus.create({
            name: "七龙珠",
            summary: "很久很久以前,地球上散落着七颗神奇的龙珠,传说只要聚齐它们,神龙就会出现,并可以为人实现一个愿望。为了寻找龙珠,布尔玛和孙悟空踏上了奇妙的寻珠之旅……",
            author: "鸟山明",
            cover: "http://iconan.bj.bcebos.com/2%2Fcover.jpg",
            type: 0,
            popularity: 0,
            score: 100,
            createtime: new Date(),
            updatetime: new Date()
        }).then(function () {
            console.info("插入数据完成");
        });
        
        res.send({
            message: "成功",
            stateCode: 0
        });
    });
    
    /**
     * 重命名temp文件夹下除ok外所有文件夹
     */
    router.get("/rename", function (req, res, next) {
        
        fs.readdir("temp", function (err, files) {
            for (var key in files) {
                var dirname = files[key];
                if (dirname != "ok") {
                    fs.renameSync("temp/" + dirname, "temp/第" + dirname.match(/龍珠完全版Vol_(d+)/)[1] + "卷");
                }
            }
        });
        
        res.send({
            message: "成功",
            stateCode: 0
        });
    });
    
    /**
     * 开始处理temp下所有文件夹
     */
    router.get("/start", function (req, res, next) {
        
        //需要手动修改为当前漫画id
        var opusid = 2;
        var chapterid = 1;
        
        var chapterPosition = 0;
        
        fs.readdir("temp", function (err, files) {
            
            console.info(files);
            
            var dirFoo = [];
            
            
            for (var key in files) {
                var chaptername = files[key];
                if (chaptername != "ok") {
                    
                    dirFoo.push(function () {
                        return new Promise(function (resolve, reject) {
                            console.info("开始处理章节", chaptername);
                            
                            Chapter.create({
                                opusid: opusid,
                                name: chaptername,
                                type: 0,
                                position: chapterPosition++,
                                createtime: new Date(),
                                updatetime: new Date()
                            }).then(function (model) {
                                console.info("插入数据完成", model.dataValues);
                                
                                chapterid = model.dataValues.id;
                                
                                fs.readdir("temp/" + chaptername, function (err, files) {
                                    var pathUrl = "temp/ok/";
                                    
                                    var num = 0;
                                    
                                    var fooArr = [];
                                    
                                    fooArr.push(function () {
                                        return new Promise(function (resolve, reject) {
                                            fs.readdir("temp/ok", function (err, files) {
                                                for (var key in files) {
                                                    fs.unlinkSync("temp/ok/" + files[key]);
                                                }
                                                resolve();
                                            });
                                        })
                                    });
                                    
                                    for (var key in files) {
                                        var fileName = files[key];
                                        console.info(fileName);
                                        
                                        fooArr.push(function () {
                                            return new Promise(function (resolve, reject) {
                                                var img = gm("temp/" + chaptername + "/" + fileName);
                                                //获取图片尺寸
                                                img.size(function (err, size) {
                                                    //如果图片是横向长方形,那么就从中间裁切成2张单独的图片
                                                    if (size.width / size.height > 1) {
                                                        img.crop(Math.floor(size.width / 2), size.height, Math.floor(size.width / 2), 0)
                                                            .write(pathUrl + "p" + fill(num++, 4) + ".jpg", function (err) {
                                                                err && console.info(err);
                                                                //第二张图片在第一张裁切完再进行
                                                                img.crop(Math.floor(size.width / 2), size.height, 0, 0)
                                                                    .write(pathUrl + "p" + fill(num++, 4) + ".jpg", function (err) {
                                                                        err && console.info(err);
                                                                        resolve();
                                                                    });
                                                            });
                                                    }
                                                    else {
                                                        img.write(pathUrl + "p" + fill(num++, 4) + ".jpg", function (err) {
                                                            err && console.info(err);
                                                            resolve();
                                                        });
                                                    }
                                                });
                                            })
                                        })
                                    }
                                    
                                    //顺序同步执行fooArr里的方法
                                    reduce(fooArr).then(function () {
                                        console.info("裁切完成,开始上传");
                                        
                                        //清空方法数组
                                        fooArr.length = 0;
                                        
                                        var picturePosition = 0;
                                        
                                        //完成后上传
                                        fs.readdir("temp/ok", function (err, files) {
                                            for (var key in files) {
                                                var fileName = files[key];
                                                if (/^pd+.jpg$/.test(fileName)) {
                                                    console.info(fileName);
                                                    
                                                    fooArr.push(function () {
                                                        return new Promise(function (resolve, reject) {
                                                            console.info("开始上传");
                                                            //获取图片尺寸
                                                            gm(pathUrl + fileName).size(function (err, size) {
                                                                var upFileName = opusid + "/" + chapterid + "/" + Date.now() + ".jpg";
                                                                console.info(upFileName);
                                                                //以文件形式上传
                                                                client.putObjectFromFile("iconan", upFileName, pathUrl + fileName)
                                                                    .then(function () {
                                                                        Picture.create({
                                                                            chapterid: chapterid,
                                                                            url: "http://iconan.bj.bcebos.com/" + upFileName,
                                                                             size.width,
                                                                            height: size.height,
                                                                            type: 0,
                                                                            position: picturePosition++,
                                                                            createtime: new Date(),
                                                                            updatetime: new Date()
                                                                        }).then(function () {
                                                                            console.info("插入数据完成");
                                                                            resolve();
                                                                        });
                                                                    })
                                                                    .catch(function () {
                                                                        console.info("上传失败", arguments);
                                                                        reject();
                                                                    });
                                                            });
                                                        })
                                                    });
                                                }
                                            }
                                            
                                            reduce(fooArr).then(function () {
                                                console.info("上传完成");
                                                resolve();
                                            });
                                        });
                                    })
                                });
                            });
                        })
                    });
                }
            }
            
            reduce(dirFoo).then(function () {
                console.info("最终完成");
            })
        });
        
        
        res.send({
            message: "正在操作中,请在控制台查看进度",
            stateCode: 0
        });
    });
    
    /**
     * 将数字补位
     * @param num 需要补位的数字
     * @param n 需要多少位
     * @returns {string}
     */
    function fill(num, n) {
        return (Array(n).join(0) + num).slice(-n);
    }
    
    /**
     * 让一个promise的数组顺序执行
     */
    function reduce(arr) {
        var sequence = Promise.resolve();
        
        arr.forEach(function (item) {
            sequence = sequence.then(item)
        });
        
        return sequence
    }
    
    
    module.exports = router;

    然后把下载好的漫画,以章节为目录复制到temp文件夹下,例如下面的《七龙珠》

    先调用rename接口,然后调用start接口,就会看到后台在不断处理和上传图片,坐等几小时后,就会按章节分不同文件夹上传的服务器,然后把外链地址保存到数据库的picture表中。

     

    昨晚上传了5小时,就上传完了《柯南》和《七龙珠》,总共10G多的图片,速度还是很不错的。

  • 相关阅读:
    菜鸟学存储:网络存储IP SAN与IB SAN
    读xml高手
    预先加载图片
    xred520
    最简单准确的硬盘整数分区设置操作方法
    Google 每天处理约 20000TB 的数据
    IE 8 无法正常使用网站后台编辑器问题
    常用的JS技术1
    adodb stream 使用说明
    [Tools] JDGUI(Java Decompiler)
  • 原文地址:https://www.cnblogs.com/shamoyuu/p/vue_vux_app_extra_1.html
Copyright © 2020-2023  润新知