Egg中使用 wysiwyg-editor 編輯器

1. 在HTML文件中引入需要的文件。

<!-- 引入開源的圖標庫文件 -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />

<!-- 引入編輯器的CSS文件 -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/froala-editor/2.5.1/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" /> 
<link href="https://cdnjs.cloudflare.com/ajax/libs/froala-editor/2.5.1/css/froala_style.min.css" rel="stylesheet" type="text/css" />


<!-- 依賴於JQuery,必須要引入-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

<!-- 引入編輯器的JS文件 -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/froala-editor/2.5.1//js/froala_editor.pkgd.min.js"></script>

<!-- 引入中文語言包對編輯器進行漢化,語言包從以下網址下載-->
<!-- https://www.froala.com/wysiwyg-editor/languages-->
<script type="text/javascript" src="/public/admin/editor/froala_editor_2.8.5/js/languages/zh_cn.js"></script>

2. 在HTML文件中定義一個文本域,指定編輯器要插入的位置。

<textarea name="content" id="content" cols="100" rows="8" style="margin-top:20px"></textarea>

3. 在HTML文件中初始化編輯器。

<script>
    // 初始化編輯器
    $(function () {
        $('#content').froalaEditor({
            // 設置編輯器的高度
            height: 300,
            // 設置所用的語言
            language: 'zh_cn',
            // 配置上傳圖片的路由
            imageUploadURL:'/admin/goods/goodsUploadImage',
            // 配置根據屏幕不同大小顯示不同的工具條
            // 如果不需要區分顯示,需要全部設置成一樣的
            toolbarButtons: [
                'fullscreen', 'bold', 'italic', 'underline', 'strikeThrough', 'subscript', 'superscript', 
                '|', 
                'fontFamily', 'fontSize', 'color', 'inlineStyle', 'paragraphStyle', 
                '|', 
                'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 
                '-', 
                'insertLink', 'insertImage', 'insertVideo', 'embedly', 'insertFile', 'insertTable', 
                '|', 
                'emoticons', 'specialCharacters', 'insertHR', 'selectAll', 'clearFormatting', 
                '|', 
                'print', 'spellChecker', 'help', 'html', 
                '|', 
                'undo', 'redo'
            ],
            toolbarButtonsSM: [
                'fullscreen', 'bold', 'italic', 'underline', 'strikeThrough', 'subscript', 'superscript', 
                '|', 
                'fontFamily', 'fontSize', 'color', 'inlineStyle', 'paragraphStyle', 
                '|', 
                'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 
                '-', 
                'insertLink', 'insertImage', 'insertVideo', 'embedly', 'insertFile', 'insertTable', 
                '|', 
                'emoticons', 'specialCharacters', 'insertHR', 'selectAll', 'clearFormatting', 
                '|', 
                'print', 'spellChecker', 'help', 'html', 
                '|', 
                'undo', 'redo'
            ],
            toolbarButtonsMD: [
                'fullscreen', 'bold', 'italic', 'underline', 'strikeThrough', 'subscript', 'superscript', 
                '|', 
                'fontFamily', 'fontSize', 'color', 'inlineStyle', 'paragraphStyle', 
                '|', 
                'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 
                '-', 
                'insertLink', 'insertImage', 'insertVideo', 'embedly', 'insertFile', 'insertTable', 
                '|', 
                'emoticons', 'specialCharacters', 'insertHR', 'selectAll', 'clearFormatting', 
                '|', 
                'print', 'spellChecker', 'help', 'html', 
                '|', 
                'undo', 'redo'
            ]
        })
    }); 
</script>

4. 配置初始化編輯器中上傳圖片的路由。

// router.js
'use strict';
module.exports = app => {
    const { router, controller } = app;
    router.post('/admin/goods/goodsUploadImage',controller.admin.goods.goodsUploadImage);

};

5. 爲編輯器上傳圖片的路由編寫控制器。

// app/controller/admin/goods.js

'use strict';

const Fs = require('fs');
// cnpm i mz-modules --save
// 此模塊解決上傳卡死
const Pump = require('mz-modules/pump');
const Controller = require('egg').Controller;

class GoodsController extends Controller {
    // 編輯器圖片上傳
    async goodsUploadImage() {

        // autoFields: true 表示除了文件的其它字段
        let parts = this.ctx.multipart({ autoFields: true });
        let files = {}, stream;
        // 循環獲取數據流
        while ((stream = await parts()) != null) {
            if (!stream.filename) {
                // 多文件上傳時,只能break,不能return
                break;
            }
            // 文件表單的name
            let fieldname = stream.fieldname;

            // 獲取上傳文件路徑與入庫保存路徑
            let dir = await this.service.tools.getUploadFile(stream.filename);
            // 上傳路徑
            let target = dir.uploadDir;

            // 寫入上傳文件
            let writeStream = Fs.createWriteStream(target);
            await Pump(stream, writeStream);

            // 將多個上傳圖片統一拼接爲一個對象,便於訪問
            files = Object.assign(files, {
                [fieldname]: dir.saveDir
            })
        }
        // 返回數據格式要按編輯器約定的格式
        this.ctx.body={
            link:files.file
        }
    }

}
module.exports = GoodsController;

6. 控制器中調用服務中的getUploadFile方法。

// app/service/tools.js
'use strict';
const Path = require('path');
const Service = require('egg').Service;
 
 
// 引入格式化時間模塊
// cnpm i silly-datetime --save
const Sd = require('silly-datetime');
 
// 引入模塊智能生成上傳文件夾
// cnpm i mz-modules --save
const Mkdirp = require('mz-modules/mkdirp');
 
 
// 引入生成縮略圖的模塊
// cnpm install jimp --save
// https://github.com/oliver-moran/jimp/tree/master/packages/jimp
const Jimp = require('jimp');
 
 
class ToolService extends Service {
 
    // 獲取當前時間戳
    async getTime(){
        let now = new Date();
        return now.getTime();
    }
 
    // 處理要上傳的文件名
    async getUploadFile(filename){
        // 獲取當前日期
        let now = Sd.format(new Date(),'YYYYMMDD');
        // 創建文件目錄(將存放地址與日期進行拼接);
        let dir = Path.join(this.config.uploadDir,now);
        // 按dir去創建文件夾,如果沒有則生成,如果有則忽略
        await Mkdirp(dir);
 
        // 以時間戳命名文件
        let timestamp = await this.getTime();
 
        // 圖片的保存路徑(文件夾 + 時間戳 + 後輟名)
        let uploadDir = Path.join(dir,timestamp + Path.extname(filename));
 
        return{
            // 上傳的地址
            uploadDir:uploadDir,
            // 保存在數據庫的地址
            saveDir:uploadDir.slice(3).replace(/\\/g,'/')
        }
    }
 
 
    // 生成縮略圖方法
    async jimpImg(target){
        Jimp.read(target, (err, lenna) => {
            if (err) throw err;
            // 生成200乘以200大小,品質爲90,並重命名文件
            lenna.resize(200,200).quality(90).write(target+'_200x200'+Path.extname(target)); 
        })
 
    }
 
}
 
module.exports = ToolService;

7. 處理編輯器上傳圖片時,由於Egg安全驗證機制導致無法上傳的問題。

// config/config.default.js

'use strict';
module.exports = appInfo => {

    const config = exports = {};
    // use for cookie sign key, should change to your own and keep security
    config.keys = appInfo.name + '_1585450669767_9677';

    // 上傳文件存放的全局地置
    config.uploadDir = 'app/public/admin/upload';

    // 上傳文件的配置
    // https://github.com/eggjs/egg-multipart
    config.multipart = {
        // 允許上傳的圖片格式
        whitelist: ['.png', '.jpg', '.jpeg'],
        // 文件允許大小
        fileSize: '50mb',
        // 上傳字段的數量
        fields: '50'
    }

    // 處理編輯器上傳圖片的安全驗證機制
    exports.security = {
        csrf: {
            // 當URL爲/admin/goods/goodsUploadImage時,忽略csrf驗證
            ignore: ctx => { 
                if (ctx.request.url == '/admin/goods/goodsUploadImage') { 
                    return true; 
                } 
                return false; 
            },
        }
    }

    return config

};

參考文檔:

https://github.com/froala/wysiwyg-editor

https://www.froala.com/wysiwyg-editor/docs/options

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章