• 项目三(集团官网)——总结(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组件。

  • 相关阅读:
    Avoiding React setState() Pitfalls(译)
    rax学习(十):实现微信消息长列表(LongList)之列表扩展
    rax学习(九):实现微信消息长列表(LongList)之配置透出
    rax学习(八):实现微信消息长列表(LongList)之性能优化
    rax学习(七):实现微信消息长列表(LongList)之性能监控
    rax学习(六):实现微信消息长列表(LongList)之业务埋点
    jQuery获取父 兄 子 节点
    css相关
    两端对齐justify
    js页面刷新的几种方法
  • 原文地址:https://www.cnblogs.com/zhengyeye/p/6000839.html
Copyright © 2020-2023  润新知