长风破浪会有时
直挂云帆济沧海

nodejs配置ueditor

当前端的ueditor.config.js访问的地址是ueditor/ue等时候.后端路由接收。进ue方法

import ueditor from "../service/ueditor/index";

import BaseController from "../../core/BaseController";

class Ueditor extends BaseController{
    async ue(){
        this.body = await ueditor('public',this.ctx);
    }
}

module.exports = Ueditor;

2.ueditor界面配置上传等内容

import * as fs from 'fs';

import * as http from 'http';

import * as https from 'https';

import * as path from 'path';

import upload,{base64Image,fileFormat,getSuffix } from './../upload';

import * as multer from 'koa-multer';

//获取ueditor配置文件
import config from './../config';
//获取全局配置文件
import nconfig from '../../../config';
//同步遍历文件
export const eachFileSync = (dir,findOneFile)=>{
    const stats = fs.statSync(dir);
    if(stats.isDirectory()){
        fs.readdirSync(dir).forEach(file=>{
            eachFileSync(path.join(dir,file),findOneFile);
        })
    }else{
        findOneFile(dir,stats);
    }
}
//处理上传保存路径
export const setFullPath = (dest) =>{
    const date = new Date();
    const map = {
        t: date.getTime(), // 时间戳
        y: date.getFullYear(), // 年
        m: date.getMonth() + 1, // 月
        d: date.getDate(), // 日
        h: date.getHours(), // 时
        i: date.getMinutes(), // 分
        s: date.getSeconds(), // 秒
    }
     return dest.replace(/\{([ymdhis])\1*\}|\{time\}|\{rand:(\d+)\}/g, function(all:any, $1:any, $2:any) {
        if ($1 !== void 0) {
            const v = String(map[$1]);
            const l = all.length;
            if ($1 != 'y') {
                return l > 3 && Number(v) <= 9 ? '0' + v : v;
            }
            return v.substr(6 - l);
        }

        if (all === '{time}') return String(map.t);

        return String(Math.random()).substr(2, Number($2) || 6);
    });
}
//抓取网络图片
const catchImage = (url:string) =>{
    const request =  /^https:\/\//.test(url) ? https.request : http.request;
    let image = url.match(/^(:?https?\:)?\/\/[^#?]+/)[0]
    let originalname = image.substr(image.lastIndexOf('\/') + 1)
    let contentType = ''
    let base64Data = ''
    return new Promise((resolve, reject) => {
        const req = request(url, (res) => {
            contentType = res.headers['content-type']
            res.setEncoding('base64')
            res.on('data', (chunk) => {
                base64Data += chunk
            })
            res.on('end', () => resolve({contentType, base64Data, originalname}))
        })

        req.on('error', (err) => resolve({error: true}))
        req.end()
    })
}

//ueditor上传方法
const ueditor = async (dir:any,ctx,next) =>{
    let ueOpts : any = [];
    if(typeof dir === 'object'){
        ueOpts = Array.isArray(dir) ? dir : ueOpts.push('public');
    }else{
        ueOpts.push(dir || 'public')
    }
    const publicDir = path.resolve(ueOpts[0]);
    const conf = Object.assign({},config,ueOpts[1] || {});
    const uploadType = {
        [conf.imageActionName]: 'image',
        [conf.scrawlActionName]: 'scrawl',
        [conf.catcherActionName]: 'catcher',
        [conf.videoActionName]: 'video',
        [conf.fileActionName]: 'file',
    }
    const listType = {
        [conf.imageManagerActionName]: 'image',
        [conf.fileManagerActionName]: 'file',
    };
    let result = {};
    let {action,start = 0,callback} = ctx.query;
    start = parseInt(start);
    //上传文件
    if(Object.keys(uploadType).includes(action)){
        const actionName = uploadType[action];
        let pathFormat = setFullPath(conf[actionName + 'PathFormat']).split("/");
        let filename = pathFormat.pop();
        try{
            switch(action){
                //涂鸦类型图片
                case conf.scrawlActionName :
                    let base64Data = ctx.request.body[conf[actionName + 'FieldName']];
                    let base64Length = base64Data.length;
                    if(base64Length - (base64Length /8) * 2 > conf[actionName + 'MaxSize']){
                        throw new Error('picture too big')
                    }
                    ctx.req.file = base64Image(base64Data,publicDir,{
                        destination : path.join(publicDir,...pathFormat)
                    })
                    result = Object.assign({state: 'SUCCESS',code:0}, fileFormat(ctx.req.file))
                    break;
                //抓取远程图片 
                case  conf.catcherActionName:
                    const sources = ctx.request.body[conf[actionName + 'FieldName']]
                    let list = []
                    let images = []
                    sources.forEach((url) => {
                        images.push(catchImage(url).then((image:any) => {
                            if(image.error){
                                list.push({state: 'ERROR',code:0, source: url})
                            }else{
                                let base64Data = image.base64Data;
                                let base64Length = base64Data.length;
                                if(base64Length - (base64Length / 8) * 2 > conf[actionName + 'MaxSize']){
                                    list.push({state: 'Picture too big',code:0, source: url})
                                }else{
                                    // 重新获取filename
                                    filename = setFullPath(conf[actionName + 'PathFormat']).split('/').pop()
                                    if(filename === '{filename}'){
                                        filename = image.originalname.replace(/\.\w+$/, '')
                                    }
                                    if(/^image\/(\w+)$/.test(image.contentType)){
                                        base64Data = 'data:'+ image.contentType +';base64,' + base64Data
                                    }
                                    console.log(base64Data);
                                    list.push(Object.assign({state: 'SUCCESS', source: url}, fileFormat(
                                        base64Image(base64Data, publicDir, {
                                            destination: path.join(publicDir, ...pathFormat),
                                            filename
                                        })
                                    ), {original: image.originalname}))
                                }
                            }
                            return image
                        }))
                    })
                    await Promise.all(images)
                    result = {state: 'SUCCESS',code:0, list}
                    break;
                default : 
                    await upload(publicDir, {
                        storage : multer.diskStorage({
                            destination: path.join(publicDir, ...pathFormat),
                            filename (req, file, cb) {
                                //保存原名称
                                if(filename === '{filename}'){
                                    filename = file.originalname
                                }else{
                                    filename += getSuffix(file.originalname)
                                }
                                // const fileFormat = (file["originalname"].split("."));
                                // const fileFormat = file.originalname.substr(filename.lastIndexOf('.')).toLowerCase()
                                // cb(null,Date.now() + "." + fileFormat);
                                cb(null, filename)
                            }
                        })
                        ,
                        limits: {
                            fileSize: conf[actionName + 'MaxSize']
                        },
                        allowfiles: conf[actionName + 'AllowFiles']}).single(conf[actionName + 'FieldName'])(ctx, next)
                    
                    result = Object.assign({state: 'SUCCESS'}, fileFormat(ctx.req.file));
                    break;
            }
        }catch(err){
            console.log(err);
            result = {state: err.message}
        }
    }else if(Object.keys(listType).includes(action)){
        const actionName = listType[action]
        let files = []
        eachFileSync(path.join(publicDir, conf[actionName + 'ManagerListPath']), (file, stat) => {
            if(conf[actionName + 'ManagerAllowFiles'].includes(getSuffix(file))){

                const url = nconfig.nowUrl + file.replace(publicDir, '').replace(/\\/g, '\/')
                const mtime = stat.mtimeMs
                files.push({url, mtime})
            }
        })
        result = {
            list: files.slice(start, start + conf[actionName + 'ManagerListSize']),
            start: start,
            total: files.length,
            code : 0,
            state: 'SUCCESS'
        }
    }else if(action === 'config'){
        result = conf;
    }else{
        result = {state:'FAIL',code:400}
    }
    return await callback ? [callback] + '(' + JSON.stringify(result) + ')' : JSON.stringify(result);
}
export default ueditor;

3.upload设置上传文件路径等

/**
 * 单文件上传:upload().single(fieldname)
 * 多文件上传:upload().array(fieldname[, maxCount])
 * 多表单上传:upload().fields([{name: 'avatar', maxCount: 1}, {name: 'gallery', maxCount: 1}])
 */
import * as fs from 'fs';
import * as path from 'path';
import * as multer from 'koa-multer';
//默认静态目录
let publicDir = '';
//同步创建文件目录
export const mkdirsSync = (dirname:string) =>{
    if(fs.existsSync(dirname)){
        return true;
    }else{
        if(mkdirsSync(path.dirname(dirname))){
            fs.mkdirSync(dirname);
            return true;
        }
    }
}
//获取文件后缀
export const getSuffix = (filename:string) => {
    return filename.substr(filename.lastIndexOf('.')).toLowerCase();
}
//存储方式
export const diskStorage = multer.diskStorage({
    destination(req,file,cb){
        let dir = "";
        let type = "file";
        file.mimetype.replace(/image|video/g, (v) => {
            return type = v
        })
        dir = path.join(publicDir, 'upload', type)
        mkdirsSync(dir)
        cb(null, dir)
    },
    filename(req,file,cb){
        cb(null, Date.now() + (Math.random().toString().substr(2,6)) + getSuffix(file.originalname))
    }
})
//处理上传后返回的数据格式
export const fileFormat = (data) =>{
    console.log(data);
    let { originalname :original , filename: title, path: url, size } = data;
    const type = getSuffix(title)
    url = url.replace(publicDir, '').replace(/\\/g, '\/')

    return { original, title, type, url, size }
}
//保存base64类型图片
export const base64Image = (base64Data,dir,options) =>{
        if(typeof dir === 'object'){
            options = dir
            dir = ''
        }
        publicDir = path.resolve(dir || 'public')
        let dest = ''
        let ext = '.png'
        let { destination, filename } = Object.assign({
            destination: path.join(publicDir, 'upload', 'image'),
            filename: Date.now() + (Math.random().toString().substr(2,6))
        }, options || {})

        base64Data = base64Data.replace(/^data:image\/(\w+);base64,/, (all, e) => {
            ext = e === 'jpeg' ? '.jpg' : '.' + e
            return ''
        })
        filename += ext
        dest = path.join(destination, filename)

        mkdirsSync(destination)
        fs.writeFileSync(dest, base64Data, 'base64')
        const stat = fs.statSync(dest)
        return { originalname: '', filename, path: dest, size: stat.size }
}
//上传文件
const upload = (dir,options) =>{
    if(typeof dir === 'object'){
        options = dir;
        dir = "";
    }
    publicDir = path.resolve(dir || 'public')
    const allowfiles = options.allowfiles || '*'    // 文件类型,['.jpg', '.png']
    const fileFilter = (req, file, cb) => {
        if(allowfiles === '*' || allowfiles.includes(getSuffix(file.originalname))){
            cb(null, true)
        }else{
            cb(new Error('Unsupported file type'), false)
        }
    }
    return multer(Object.assign({
        storage: diskStorage,
        fileFilter,
        limits: {
            files: 20,                    // 单次上传文件最大数量
            fileSize: 2 * 1024 * 1024,    // 文件最大长度 (字节单位)
        },
    }, options))
}
export default upload;
赞(2)
未经允许不得转载:阿锋哥前端开发经验分享 » nodejs配置ueditor
分享到: 更多 (0)

几百块就能做营销型企业网站?

查看详情