1. 程式人生 > >富文字編輯器UEditor提交時獲取所有上傳的檔案

富文字編輯器UEditor提交時獲取所有上傳的檔案

記錄一下最近使用Ueditor富文字編輯器時遇到的問題

使用者在編輯富文字內容時,比如上傳了10張圖片儲存,下一次編輯時去掉了其中3張圖片,那麼資料庫中當前文件與文件上傳的檔案的對應關係應該如何更新呢?

我採用的做法是,每次重新獲取富文字中的檔案,然後清除文件與檔案的關係後,按當前文件中獲取來的檔案列表重新新增關係

不採用正則表示式這種效率低的方式

在上傳檔案時將檔案內容做md5運算生成唯一key,然後將需要記錄的檔案內容都儲存到資料庫中的表中

我採用md5運算方法邏輯是,如果檔案大於2MB就取檔案頭1MB和後1MB,做md5運算生成檔案唯一標識,小於2MB就直接md5

不要問我為什麼用頭1MB和後1MB運算生成的MD5值作做唯一標識,用就完了

需要修改ueditor.all.js原始碼,在回顯與儲存文件時給相應標籤增加兩個屬性

1、t_crc="7d90bcfc87c1e8a918b38f35a6186f53",檔案唯一標識ID,檔案內容MD5值

2、t_tag="cxUeditorUploadFile",在標籤中打入標記,之後儲存時使用原生js方式獲取帶有標記的所有標籤,這樣就獲取到了檔案唯一標識crc欄位

如上傳的圖最終儲存為 :

<!-- 圖片 -->
<img src="/preview/20190429/20190429182137525982_98488150.jpg" title="191322z2g2mmnoloqzcqnq.jpg" _src="/preview/20190429/20190429182137525982_98488150.jpg" alt="191322z2g2mmnoloqzcqnq.jpg" t_crc="7d90bcfc87c1e8a918b38f35a6186f53" t_tag="cxUeditorUploadImage">

需要注意的是,UEditor中的標籤屬性有名單驗證,需要修改ueditor.config.js中的白名單whitList,增加t_crc,t_tag,否則UEditor會過濾掉我們自定義的屬性

因為不清楚如何自定義controller的返回欄位,看了官網也沒找到如何能自定義返回欄位,沒有辦法只能將其中一個欄位改為json字串,然修改ueditor原始碼解析改字串,是不是很low,我也不想這樣寫實在是沒辦法

{
  "original": "xy.png",
  "state": "SUCCESS",
  "title": "xy.png",
  "url": "{\"crc\":\"fe760006af17c5bfe2d68ad17f5fe8f6\",\"url\":\"/preview/20190430/20190430105610120347_98488150.png\"}"
}

注意原始碼中的ueditor.all.js原始碼中7966行的filterInputRule方法,執行editor.setContent方法和執行'inserthtml'命令後,會執行該過濾函式,我們直接加入return;否則我們自己加的標籤他會過濾掉

 /**
         * 執行註冊的過濾規則
         * @method  filterInputRule
         * @param { UE.uNode } root 要過濾的uNode節點
         * @remind 執行editor.setContent方法和執行'inserthtml'命令後,會執行該過濾函式
         * @example
         * ```javascript
         * editor.filterInputRule(editor.body);
         * ```
         * @see UE.Editor:addInputRule
         */
        filterInputRule: function (root) {
            // kdy修改
            return ;
            for (var i = 0, ci; ci = this.inputRules[i++];) {
                ci.call(this, root)
            }
        },

ueditor.all.js原始碼中9969行的過濾器defaultfilter也直接加入return;

UE.plugins['defaultfilter'] = function () {
    return; // kdy修改
    ......省略
}

ueditor.all.js原始碼中17648行,修改video標籤加入我們自定義屬性t_crc,t_tag

/**
     * 建立插入視訊字元竄
     * @param url 視訊地址
     * @param width 視訊寬度
     * @param height 視訊高度
     * @param align 視訊對齊
     * @param toEmbed 是否以flash代替顯示
     * @param addParagraph  是否需要新增P 標籤
     * // kdy修改
     */
    function creatInsertStr(url,width,height,id,align,classname,type,node){
        let urlJSON = undefined;
        try {
            urlJSON = JSON.parse(url);
        } catch (error) {
            if (node != undefined) {
                urlJSON = { "url": node.getAttr("_url"), "crc": node.getAttr("t_crc") };
            }
        }
        
        let crc = urlJSON.crc;
        if(node != undefined){
            crc = node.getAttr("t_crc");
        }
        url = urlJSON.url;
        url = utils.unhtmlForUrl(url);
        align = utils.unhtml(align);
        classname = utils.unhtml(classname);

        width = parseInt(width, 10) || 0;
        height = parseInt(height, 10) || 0;
        //修改了這裡
        var str;
        switch (type){
            case 'image':
                str = '<img t_tag="cxUeditorUploadFile" t_crc="'+crc+'" ' + (id ? 'id="' + id+'"' : '') + ' width="'+ width +'" height="' + height + '" _url="'+url+'" class="' + classname.replace(/\bvideo-js\b/, '') + '"'  +
                    ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;'+(align ? 'float:' + align + ';': '')+'" />'
                break;
            case 'embed':
                str = '<embed type="application/x-shockwave-flash" class="' + classname + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
                    ' src="' +  utils.html(url) + '" width="' + width  + '" height="' + height  + '"'  + (align ? ' style="float:' + align + '"': '') +
                    ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';
                break;
            case 'video':
                var ext = url.substr(url.lastIndexOf('.') + 1);
                if(ext == 'ogv') ext = 'ogg';
                str = '<video  t_tag="cxUeditorUploadFile" t_crc="'+crc+'"  ' + (id ? ' id="' + id + '"' : '') + ' class="' + classname + ' video-js" ' + (align ? ' style="float:' + align + '"': '') +
                    ' controls preload="none" width="' + width + '" height="' + height + '" src="' + url + '" data-setup="{}">' +
                    '<source src="' + url + '" type="video/' + ext + '" /></video>';
                break;
        }
        return str;
    }

ueditor.all.js原始碼中17780行,視訊上傳後的回撥函式加入t_crc 和 t_tag

me.commands["insertvideo"] = {
        execCommand: function (cmd, videoObjs, type){
            videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs];
            var html = [],id = 'tmpVedio', cl;
            for(var i=0,vi,len = videoObjs.length;i<len;i++){
                vi = videoObjs[i];
                cl = (type == 'upload' ? 'edui-upload-video video-js vjs-default-skin':'edui-faked-video');
                html.push(creatInsertStr( vi.url, vi.width || 420,  vi.height || 280, id + i, null, cl, 'image'));
            }
            me.execCommand("inserthtml",html.join(""),true);
            var rng = this.selection.getRange();
            for(var i= 0,len=videoObjs.length;i<len;i++){
                var img = this.document.getElementById('tmpVedio'+i);
                domUtils.removeAttributes(img,'id');
                rng.selectNode(img).select();
                me.execCommand('imagefloat',videoObjs[i].align)
            }
        },
        queryCommandState : function(){
            var img = me.selection.getRange().getClosedNode(),
                flag = img && (img.className == "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1);
            return flag ? 1 : 0;
        }
    };

ueditor.all.js原始碼中24536行,修改image標籤圖片上傳成功後的回撥函式,這個方法會在富文字編輯框中加入我們上傳的圖片,同樣加入t_crc 和 t_tag

function callback(){
	try{
		var link, json, loader,
			body = (iframe.contentDocument || iframe.contentWindow.document).body,
			result = body.innerText || body.textContent || '';
		json = (new Function("return " + result))();
		// 修改這裡
		let urlJSON = JSON.parse(json.url);
		let t_url = urlJSON.url;
		let t_crc = urlJSON.crc;
		json.url = t_url;
		link = me.options.imageUrlPrefix + json.url;
		
		if(json.state == 'SUCCESS' && json.url) {
			loader = me.document.getElementById(loadingId);
			loader.setAttribute('src', link);
			loader.setAttribute('_src', link);
			loader.setAttribute('title', json.title || '');
			loader.setAttribute('alt', json.original || '');
			loader.setAttribute('style','max-width:650px');
			loader.setAttribute('t_crc', t_crc || '');
			loader.setAttribute('t_tag','cxUeditorUploadFile');
			loader.removeAttribute('id');
			domUtils.removeClasses(loader, 'loadingclass');
		} else {
			showErrorLoader && showErrorLoader(json.state);
		}
	}catch(er){
		showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError'));
	}
	form.reset();
	domUtils.un(iframe, 'load', callback);
}

ueditor.all.js原始碼中24812行,上傳附件後的回撥函式,同樣加入t_crc 和 t_tag

return {
        commands:{
            'insertfile': {
                execCommand: function (command, filelist){
                    filelist = utils.isArray(filelist) ? filelist : [filelist];

                    var i, item, icon, title,
                        html = '',
                        URL = me.getOpt('UEDITOR_HOME_URL'),
                        iconDir = URL + (URL.substr(URL.length - 1) == '/' ? '':'/') + 'dialogs/attachment/fileTypeImages/';
                    for (i = 0; i < filelist.length; i++) {
                        item = filelist[i];
                        // 修改這裡
                        let urlJSON = JSON.parse(item.url);
                        let t_url = urlJSON.url;
                        let t_crc = urlJSON.crc;
                        item.url = t_url;
                        icon = iconDir + getFileIcon(item.url);
                        title = item.title || item.url.substr(item.url.lastIndexOf('/') + 1);
                        html += '<p style="line-height: 16px;">' +
                            '<img style="vertical-align: middle; margin-right: 2px;" src="'+ icon + '" _src="' + icon + '" />' +
                            '<a t_crc="'+ t_crc +'" t_tag="cxUeditorUploadFile" style="font-size:12px; color:#0066cc;" href="' + item.url +'" title="' + title + '">' + title + '</a>' +
                            '</p>';
                    }
                    me.execCommand('insertHtml', html);
                    // me.fireEvent('afterUpfile', filelist);
                }
            }
        }
    }

完成

連結:https://pan.baidu.com/s/1JZ0qbz7Fu0EL1H5quA98Jg 
提取碼: