项目三(集团官网)——总结(2) 递归创建子目录

目录路径:

在实际项目中,一般都会有上传图片的需求,而在我们的项目文件中,使用thinkjs命令创建项目时,则会自动创建 www/static 目录,该目录下专门用来存放 JS、CSS、图片等静态资源。而在实现上传的图片保存在自己的项目中时,我们并不是一开始就在www底下创建一个固定的目录来存放已经上传的图片,而是通过thinkjs自动来根据需求来创建目录路径。

                                                                                                              

  

       比如,在我们的项目中,存放简历的文件夹暂时先就叫做“jobFiles”,类似于:这个,jobFiles文件夹就是只有当图片上传的时候才会自动在存放在静态文件www/static目录下创建,而对于工作来说,这样子创建的文件夹就比较灵活,因为如果没有请求文件上传的方法时,也就不会产生这个文件夹,更加方便。而对于自动创建文件夹的方法,thinkjs官网也给了自己的方法:

think.mkdir(p, mode)
p {String} 要创建的目录 
mode {Number} 要创建的目录权限,默认为 0777 
递归的创建目录,如果目录已经存在,那么修改目录的权限。
// 假设 /home/welefen/a/b/ 不存在
think.mkdir("/home/welefen/a/b");
think.mkdir("home/welefne/a/b/c/d/e"); // 递归创建子目录

而要实现上图中在www/static/jobFiles/自动取时间/该文件这样的效果的话,就必须自己来写工具类方法:

/**
 * 获取未压缩图片路径___本地文件路径
 * @param jpg 图片类型
 * @returns {string}
 */
imgUtil.getLocalImageUrl = function (jpg) {
    let newDate = new Date();
    let obj={timePath:timeutil.dateFormat(newDate.getTime() / 1000, '/yyyy/MM/dd/') ,fileName: newDate.getTime() + '.' + jpg};
    return obj;
};

/**
 * @fmt 格式化字符串
 * @Date 为需要格式化的日期
 * 示例:format(new Date(),'yyyy-MM-dd hh:mm:ss');
 * 返回值为字符串
 */
tUtil.dateFormat = function(pdate, fmt) {
    let date = new Date(Number(pdate) * 1000);
    if (date == "Invalid Date") {
        date = new Date(pdate);
    }
    if (null == date || undefined == date) return '';
    var o = {
        "M+": date.getMonth() + 1, //月份
        "d+": date.getDate(), //
        "h+": date.getHours(), //小时
        "m+": date.getMinutes(), //
        "s+": date.getSeconds(), //
        "S": date.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
};

③上传文件、图片的方法

/**
     * 上传图片
     * @returns {*}
     */
    async uploadAction() {
        let file = think.extend({}, this.file('file'));
        let originalFilename = file.originalFilename;
        let fPath = file.path;
        let suffix = fPath.substr(fPath.lastIndexOf(".") + 1);//取后缀
        if (suffix == "jpg" || suffix == "png" || suffix == "jpeg" || suffix == "doc" || suffix == "docx" || suffix == "pdf") {
            let size = file.size / 1024;//文件大小转化为kb
            if (size < 300) {
                let fileObj = imgutil.getLocalImageUrl(suffix);
                var uploadPath = "static/jobFiles" + fileObj.timePath + fileObj.fileName;    
                think.mkdir("static/jobFiles" + fileObj.timePath);// 递归创建子目录
                if (think.isFile(fPath)) {//检测是否是文件,如果在不存在则返回 false
                    fs.renameSync(fPath, uploadPath);//fs.renameSync(oldPath, newPath)
                    return this.success({showName: originalFilename, path: '/jobFiles' + fileObj.timePath + fileObj.fileName });
                } else {
                    return this.fail("上传文件失败,请重新上传!");
                }
            } else {
                return this.fail("文件过大,请上传小于300kb的文件!");
            }
        } else {
            return this.fail("仅支持上传jpg,png,jpeg,doc,pdf格式文件!");
        }
    }

      在这里,特别注意的一个问题,也就是让自己找了很久的bug,就是上面写的upload方法中的定义的

var uploadPath = "static/jobFiles" + fileObj.timePath + fileObj.fileName;

    之前就是因为自己写成了/static/jobFiles,这样在上传的方法中,连自己也不知道上传的文件被放在哪个文件夹里,最后在大神同事的指点下,才恍然大悟:thinkjs在递归创建目录时,如果自己将路径写成"/static/jobFiles..."的话,它就会去这个js文件中往上找/static/jobFiles,但是在这个js文件夹之上又找不到所谓的jobFiles文件夹,因此最终也就不知道上传的文件跑哪里了,但是如果将路径写成相对路径"static/jobFiles..."的话,它就会直接去静态文件"www"底下去找"static/jobFiles...",若没有此文件夹的话,就会按我们所想的去创建一个目录。

    还有一点:上面的方法中,还有一句:  fs.renameSync(fPath, uploadPath);//fs.renameSync(oldPath, newPath)

这个也是值得一提的知识点:(nodejs中的fs.renameSync)

方法说明:同步版的rename;

语法:

fs.renameSync(oldPath, newPath)

但是:由于该方法属于fs模块,使用前需要引入fs模块(var fs= require(“fs”) )

接收参数:(两个)oldPath——原路径       newPath——新路径

var fs = require('fs');
fs.renameSync('125.txt','126.txt');

              

也就是在实现上传功能后,必须使用fs.renameSync(oldPath,newPath)的方法把原文件名改成“时间戳.后缀”的形式,这样子才算完成整个文件长传功能。

PS:我们项目中的文件上传都是使用jquery-file-upload组件。

原文地址:https://www.cnblogs.com/zhengyeye/p/6000839.html