zoukankan      html  css  js  c++  java
  • Tinymce 编辑器添加自定义图片管理插件

    在使用Tinymce的过程中需要用到图片上传功能,而提供的上传插件在上传文件后是给了一个连接地址,就想用户需要什么图片,不能用最直观的方式表现出来么!

    虽然官网上也有一个文件管理的插件moxiemanager,可奈何他是收费的!https://www.tiny.cloud/docs/plugins/moxiemanager/

    然后就打算自己弄一个,其实实现效果起来很简单,就只是做了一个类型相册管理的功能,然后在点击图片的时候,将图片的地址信息插入到编辑器里就行了,由于后台用的是layui

    的框架,所以界面也就用了layui来实现,这里我只弄了上传,删除功能,也可自己添加检索等功能,实现效果如下

    1 、添加插件

    我们需要在tinymce的 Plugins  目录下新建一个filemanager文件夹,并添加一个名为plugin.min.js ,其中editor传参后再图片管理页面通过

    var editor = top.tinymce.activeEditor.windowManager.getParams().editor; 获取编辑器对象,进行图片插入操作

    tinymce.PluginManager.add("filemanager", function (editor, url) {
        editor.addButton("filemanager", {
            title: "图片管理",
            icon: 'image',
            onclick: function () {
                editor.windowManager.open({
                    title: "图片管理",
                    url:  "/Administrator/Filemanager/Editor",
                     window.innerWidth * 0.9,
                    height: window.innerHeight * 0.8
                }, {
                        editor: editor // pointer to access editor from cshtml
                })
            }
        })
    });
    

      

    2. 相册功能实现

    文件夹管理实体类

    public class FileManagerDirectoryEntity : BaseEntity
        {
            /// <summary>
            /// 父级Id
            /// </summary>
            public int ParentId { get; set; }
    
            /// <summary>
            /// 文件夹名称
            /// </summary>
            public string Name { get; set; }
    
            /// <summary>
            /// 路径
            /// </summary>
            public string FullPath { get; set; }
    
            /// <summary>
            /// 子文件数量
            /// </summary>
            public int ChildrenCount { get; set; }
        }
    

      

    文件管理实体类

    public class FileManagerDirectoryEntity : BaseEntity
        {
            /// <summary>
            /// 父级Id
            /// </summary>
            public int ParentId { get; set; }
    
            /// <summary>
            /// 文件夹名称
            /// </summary>
            public string Name { get; set; }
    
            /// <summary>
            /// 路径
            /// </summary>
            public string FullPath { get; set; }
    
            /// <summary>
            /// 子文件数量
            /// </summary>
            public int ChildrenCount { get; set; }
        }
    

      

    相册功能具体实现controller

    public class FileManagerController : Controller
        {
    
            #region Core
            private readonly IRepository<FileManagerDirectoryEntity> _fileManagerDirectoryRepository;
            private readonly IRepository<FileManagerFilesEntity> _fileManagerFilesRepository;
            private const string smallImage = "_small";
    
            public FileManagerController(
                 IRepository<FileManagerDirectoryEntity> fileManagerDirectoryRepository,
                 IRepository<FileManagerFilesEntity> fileManagerFilesRepository
                )
            {
                this._fileManagerDirectoryRepository = fileManagerDirectoryRepository;
                this._fileManagerFilesRepository = fileManagerFilesRepository;
            }
    
            #endregion
    
    
            /// <summary>
            /// 编辑器插件
            /// 获取文件数据
            /// </summary>
            /// <param name="dirId"></param>
            /// <returns></returns>
            public ActionResult Editor(int dirId = 0) {
    
                List<FileManagerFileModel> modelList = new List<FileManagerFileModel>();
                
                //加载该文件夹下的文件夹
                var dirList = _fileManagerDirectoryRepository.Table
                    .Where(x=>x.ParentId==dirId)
                    .OrderByDescending(x=>x.CreateTime)
                    .ToList();
                foreach(var item in dirList)
                {
    
                    FileManagerFileModel model = new FileManagerFileModel();
                    model.Id = item.Id;
                    model.Name = item.Name;
                    model.FullPath = item.FullPath;
                    model.FileType = 2;
                    model.ChildrenCount = item.ChildrenCount;
                    modelList.Add(model);
                }
    
                //加载该文件夹下的图片文件
                var fileList = _fileManagerFilesRepository.Table
                    .Where(x => x.DirectoryId == dirId)
                    .OrderByDescending(x => x.CreateTime)
                    .ToList();
                foreach (var item in fileList)
                {
    
                    FileManagerFileModel model = new FileManagerFileModel();
                    model.Id = item.Id;
                    model.Name = item.Name;
                    model.FullPath = item.FullPath;
                    model.SmallFullPath = item.FullPath + smallImage + item.FileExt;
                    model.FileType = 1;
                    modelList.Add(model);
                }
    
                return View(modelList);
            }
    
            /// <summary>
            /// 创建文件夹
            /// </summary>
            /// <param name="dirId"></param>
            /// <returns></returns>
            public ActionResult _AddDirectory(int dirId) {
                return View();
            }
    
            /// <summary>
            /// 文件夹信息保存
            /// </summary>
            /// <param name="dirId"></param>
            /// <param name="dirName"></param>
            /// <returns></returns>
            public ActionResult _AddDirectorySave(int dirId , string dirName) {
                var parentDirEntity = _fileManagerDirectoryRepository.GetById(dirId);
                if (!string.IsNullOrEmpty(dirName))
                {
                    var parentDirPath = parentDirEntity == null ? "/Content/FileManager/" : parentDirEntity.FullPath;
                    if(parentDirEntity != null)
                    {
                        parentDirEntity.ChildrenCount++;
                    }
    
                    FileManagerDirectoryEntity entity = new FileManagerDirectoryEntity();
                    entity.ParentId = dirId;
                    entity.Name = dirName;
                    entity.FullPath = string.Format("{0}/{1}/", parentDirPath, Guid.NewGuid());
                    if (!Directory.Exists(Server.MapPath(entity.FullPath)))
                    {
                        Directory.CreateDirectory(Server.MapPath(entity.FullPath));
                    }
    
                    _fileManagerDirectoryRepository.Insert(entity);
                    _fileManagerDirectoryRepository.SaveChanges();
                }
                return RedirectToAction("Editor",new { dirId = dirId});
            }
    
            /// <summary>
            /// 上传图片
            /// </summary>
            /// <param name="dirId"></param>
            /// <returns></returns>
            public JsonResult UploadImage(int dirId)
            {
                //路径地址
                string fileUrl = "";
                var parentDirEntity = _fileManagerDirectoryRepository.GetById(dirId);
                var parentDirPath = parentDirEntity == null ? "/Content/FileManager/" : parentDirEntity.FullPath;
    
                HttpFileCollectionBase postfile = HttpContext.Request.Files;
                if (postfile == null)
                {
                    return Json(new { code = 1, msg = "文件不能为空" });
                }
    
                var file = postfile[0];
                string extName = Path.GetExtension(file.FileName);
    
                using (System.Drawing.Image image = System.Drawing.Image.FromStream(file.InputStream))
                {
    
                    string fileName = Guid.NewGuid().ToString() + extName;
                    string smallImgName = string.Format("{0}{1}{2}", fileName, smallImage, extName);
    
                    string route = Server.MapPath(parentDirPath);
                    fileUrl = Path.Combine(parentDirPath, fileName);
                    string savePath = Path.Combine(route, fileName);
                    //缩略图路径
                    string smallImgPath = Path.Combine(route, smallImgName);
    
                    //生成缩略图
                    try
                    {
                        ImageResizer.Fit(image, 160, 160, ImageResizeMode.Crop, ImageResizeScale.Down).Save(smallImgPath);
                    }
                    catch (Exception)
                    {
                        return Json(new { flag = false, msg = "生成缩略图出错!" });
                    }
    
                    file.SaveAs(savePath);
                }
    
                #region 添加数据到素材表
                FileManagerFilesEntity entity = new FileManagerFilesEntity();
                entity.FileExt = extName;
                entity.FullPath = fileUrl;
                entity.Name = Path.GetFileNameWithoutExtension(file.FileName);
                entity.DirectoryId = dirId;
                entity.Size = file.ContentLength;
    
                _fileManagerFilesRepository.Insert(entity);
                _fileManagerFilesRepository.SaveChanges();
                #endregion
    
    
                if (parentDirEntity != null)
                {
                    parentDirEntity.ChildrenCount++;
                }
                _fileManagerDirectoryRepository.SaveChanges();
    
                return Json(new { code = 0 });
            }
    
    
    
            public class DeleteFilesParams
            {
                public int Id { get; set; }
    
                public int Type { get; set; }
            }
    
            /// <summary>
            /// 删除选中文件夹及图片
            /// </summary>
            /// <returns></returns>
            public JsonResult CheckedFilesDelete(List<DeleteFilesParams> checkeds)
            {
                var directoryList = _fileManagerDirectoryRepository.Table.ToList();
                var fileList = _fileManagerFilesRepository.Table.ToList();
    
    
                foreach(var item in checkeds)
                {
                    //删除图片
                    if (item.Type == 1)
                    {
                        var fileEntity = fileList.FirstOrDefault(x => x.Id == item.Id);
                        string path = Server.MapPath(fileEntity.FullPath);
                        if (System.IO.File.Exists(path))
                        {
                            System.IO.File.Delete(path);
                        }
    
    
                        var parentDir = directoryList.Find(x => x.Id == fileEntity.DirectoryId);
                        if (parentDir != null)
                        {
                            parentDir.ChildrenCount--;
                        }
    
                        _fileManagerFilesRepository.Delete(fileEntity);
                    }
                    else
                    {
                        var dirEntity = directoryList.FirstOrDefault(x => x.Id == item.Id);
                        DeleteChildDirFiles(dirEntity.Id, directoryList, fileList);
                        string path = Server.MapPath(dirEntity.FullPath);
                        if (Directory.Exists(path))
                        {
                            Directory.Delete(path, true);
                        }
    
    
                        var parentDir = directoryList.Find(x => x.Id == dirEntity.ParentId);
                        if (parentDir != null)
                        {
                            parentDir.ChildrenCount--;
                        }
    
                        _fileManagerDirectoryRepository.Delete(dirEntity);
                    }
                }
                _fileManagerFilesRepository.SaveChanges();
                _fileManagerDirectoryRepository.SaveChanges();
    
                return Json(new { code = 0 });
            }
    
            public void DeleteChildDirFiles(int pid,List<FileManagerDirectoryEntity> dirList, List<FileManagerFilesEntity> files) {
                var dirEntityList = dirList.Where(x => x.ParentId == pid);
                var fileEntityList = files.Where(x => x.DirectoryId == pid);
                foreach (var item in dirEntityList)
                {
                    DeleteChildDirFiles(item.Id, dirList, files);
                    _fileManagerDirectoryRepository.Delete(item);
                }
    
                foreach (var item in fileEntityList)
                {
                    _fileManagerFilesRepository.Delete(item);
                }
                _fileManagerDirectoryRepository.SaveChanges();
                _fileManagerFilesRepository.SaveChanges();
    
            }
        }
    

    文件管理页面 Editor.chtml

     

    @using Web.Areas.Administrator.Models
    @model List<FileManagerFileModel>
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>文件管理</title>
        <link href="/Assets/iconfont/iconfont.css" rel="stylesheet" />
        <link href="/Scripts/layui/css/layui.css" rel="stylesheet" />
        <style>
            body { background: #f6f6f6; }
            .toolbar { padding: 10px; background: #fff; }
            .toolbar i.iconfont{margin-right:10px;}
            .file-list{margin:20px;}
            .file-list li { float: left; background:#fff; margin-bottom:20px; margin-right:20px; }
            .file-list li .img-wapper { 160px;  }
            .file-list li .img-wapper img{100%; height:160px;}
            .file-list li .file-name { padding: 0 10px;  100%; overflow:hidden; line-height: 30px; height:30px; color: #666; font-size: 12px; background: #fafafa; }
            .file-list li .file-name .layui-form-checkbox{140px !important; overflow:hidden !important; }
            .file-list li:hover { box-shadow: 0 0 10px rgba(0,0,0,.1); }
            .file-list li:hover .file-name { background: #f5f5f5;}
        </style>
    </head>
    <body>
        <div class="toolbar">
            <a class="layui-btn layui-btn-small" href="javascript:;" data-toggle="modal" data-title="新建文件夹" data-url="@Url.Action("_AddDirectory",new { dirId = Request["dirId"] == null ? 0 : int.Parse(Request["dirId"])})">
                <i class="iconfont icon-directory"></i>
                新建文件夹
            </a>
            <button id="upload-img-btn" type="button" class="layui-btn"><i class="iconfont icon-photo"></i>上传图片</button>
            <button id="delete-img-btn" type="button" class="layui-btn layui-btn-danger"><i class="iconfont icon-photo"></i>删除图片</button>
        </div>
        <div class="layui-form">
            <ul class="file-list">
                @if (!string.IsNullOrWhiteSpace(Request["dirId"]))
                {
                    <li class="file-item">
                        <div class="img-wapper">
                            <a href="javascript:history.back(-1);">
                                <img src="/Assets/images/default/admin_directory_back.png" alt="返回上级" title="返回上级" />
                            </a>
                        </div>
                        <div class="file-name">
                            ...
                        </div>
                    </li>
                }
                @if (Model.Any())
                {
                    foreach (var item in Model)
                    {
                        <li class="file-item">
                            @if (item.FileType == 1)
                            {
                                <div class="img-wapper">
                                    <a href="javascript:;" class="file-img" data-url="@item.FullPath" data-title="@item.Name">
                                        <img src="@item.SmallFullPath" title="@item.Name" />
                                    </a>
                                </div>
                                <div class="file-name">
                                    <input type="checkbox" name="file-id" lay-skin="primary" title="@item.Name" data-id="@item.Id" data-type="1">
                                </div>
                            }
                            else
                            {
                                <div class="img-wapper">
                                    <a href="@Url.Action("Editor",new { dirId=item.Id})">
                                        @if (item.ChildrenCount > 0)
                                        {
                                            <img src="/Assets/images/default/admin_directory_files.png" title="@item.Name" />
                                        }
                                        else
                                        {
                                            <img src="/Assets/images/default/admin_directory.png" title="@item.Name" />
                                        }
                                    </a>
                                </div>
                                <div class="file-name">
                                    <input type="checkbox" name="file-id" lay-skin="primary" title="@item.Name" data-id="@item.Id" data-type="2">
                                </div>
                            }
                        </li>
                    }
                }
            </ul>
        </div>
        <input id="dirId" value="@Request["dirId"]" hidden>
        <script src="~/Scripts/jquery-3.2.1.min.js"></script>
        <script src="/Scripts/layui/layui.js"></script>
        <script>
            //获取tinymce编辑器
            var editor = top.tinymce.activeEditor.windowManager.getParams().editor;
    
            layui.use(['upload'], function () {
                var upload = layui.upload;
                var dirId = $("#dirId").val() == "" ? 0 : $("#dirId").val();
                upload.render({ //允许上传的文件后缀
                    elem: '#upload-img-btn'
                    , url: 'UploadImage?dirId=' + dirId
                    , accept: 'file' //普通文件
                    , multiple: true
                    , size: 1024 * 2 //限制文件大小,单位 KB
                    , exts: 'jpg|jpeg|png|gif' //只允许上传压缩文件
                    , done: function (res) {
                        if (res.code == 0) {
                            window.location.reload();
                        }
                    }
                });
    
                //删除图片
                $("#delete-img-btn").click(function () {
                    var checkeds = [];
                    $("input[name='file-id']:checkbox").each(function () {
                        if (true == $(this).is(':checked')) {
                            checkeds.push({
                                id: $(this).data('id'),
                                type: $(this).data('type')
                            });
                        }
                    });
                    if (checkeds.length == 0) {
                        layer.alert('请先选择需要删除的文件!');
                    }
                    else {
                        layer.confirm('删除后将无法恢复,请确认是否要删除所选文件?', {
                            btn: ['确定删除', '我在想想'] //按钮
                        }, function () {
                            $.ajax({
                                type: 'post',
                                url: 'CheckedFilesDelete',
                                data: { checkeds : checkeds },
                                success: function (result) {
                                    if (result.code == 0) {
                                        window.location.reload();
                                    }
                                    else {
                                        showMsg(result.msg);
                                    }
                                }
                            })
                        }, function () {
                        });
                    }
                })
            })
    
            //添加图片至编辑器
            $(".file-img").click(function () {
                var url = $(this).data("url"),
                    title = $(this).data("title");
    
                //添加确认
                layer.confirm('是否需要添加此图片?', {
                    btn: ['确认添加', '我在想想'] //按钮
                }, function () {
                    editor.execCommand('mceInsertContent', false, '<img alt="' + title + '" src="' + url + '"/>');
                    editor.windowManager.close();
                }, function () {});
            })
            
        </script>
        <script>
            //layui基本代码
            $(function () {
                layui.use(['element', 'form', "layer"], function () {
                    var element = layui.element;
    
                    //表单渲染
                    var form = layui.form;
                    form.on('submit(formDemo)', function (data) {
                        layer.msg(JSON.stringify(data.field));
                        return false;
                    });
                    form.render();
    
                    //异步加载modal
                    $(document).on("click", '[data-toggle="modal"]', function (e) {
                        var $this = $(this),
                            url = $(this).data('url'),
                            title = $(this).data("title")
                        if (url) {
                            $.ajax({
                                url: url,
                                data: { rnd: Math.random() },
                                //dataType: 'html',
                                success: function (data) {
                                    //示范一个公告层
                                    layer.open({
                                        type: 1
                                        , title: title //不显示标题栏
                                        , shade: 0.8
                                        , shadeClose: true
                                        , fixed: false
                                        , area: ["900px"]
                                        , offset: '40px'
                                        , id: 'ajax-modal-wapper' //设定一个id,防止重复弹出
                                        , move: false //禁止拖拽
                                        , content: data
                                    });
                                },
                                error: function (XMLHttpRequest, textStatus, errorThrown) {
                                    alert('加载出错。' + textStatus + '. ' + XMLHttpRequest.status);
                                },
                                complete: function () {
                                }
                            });
                        }
                    });
                });
            })
        </script>
    </body>
    </html>
    

      

    新增文件夹页面 _AddDirectory.chtml

    @{
        Layout = null;
    }
    
    <div class="modal-content" style="padding-top:20px;">
        <form class="layui-form" action="_AddDirectorySave" method="post" enctype="multipart/form-data">
            <input name="dirId" value="@Request["dirId"]" hidden>
            <div class="layui-form-item">
                <label class="layui-form-label" for="dirName">文件夹名称</label>
                <div class="layui-input-block">
                    <input class="layui-input" id="dirName" lay-verify="required" name="dirName" placeholder="请输入文件夹名称" type="text" value="">
                </div>
            </div>
            <div class="layui-form-item">
                <div class="layui-input-block">
                    <button class="layui-btn" lay-submit lay-filter="account-form" type="submit">保存信息</button>
                </div>
            </div>
        </form>
    </div>
    

      

    3. 将选中图片插入编辑器

    在图片列表的页面中,我们只需要在点击图片的事件中调用Tinymce编辑器的插入方法即可,以下为插入图片的代码

    <script>
            //获取tinymce编辑器
            var editor = top.tinymce.activeEditor.windowManager.getParams().editor;
    
            layui.use(['upload'], function () {
                var upload = layui.upload;
                var dirId = $("#dirId").val() == "" ? 0 : $("#dirId").val();
                upload.render({ //允许上传的文件后缀
                    elem: '#upload-img-btn'
                    , url: 'UploadImage?dirId=' + dirId
                    , accept: 'file' //普通文件
                    , multiple: true
                    , size: 1024 * 2 //限制文件大小,单位 KB
                    , exts: 'jpg|jpeg|png|gif' //只允许上传压缩文件
                    , done: function (res) {
                        if (res.code == 0) {
                            window.location.reload();
                        }
                    }
                });
    
                //删除图片
                $("#delete-img-btn").click(function () {
                    var checkeds = [];
                    $("input[name='file-id']:checkbox").each(function () {
                        if (true == $(this).is(':checked')) {
                            checkeds.push({
                                id: $(this).data('id'),
                                type: $(this).data('type')
                            });
                        }
                    });
                    if (checkeds.length == 0) {
                        layer.alert('请先选择需要删除的文件!');
                    }
                    else {
                        layer.confirm('删除后将无法恢复,请确认是否要删除所选文件?', {
                            btn: ['确定删除', '我在想想'] //按钮
                        }, function () {
                            $.ajax({
                                type: 'post',
                                url: 'CheckedFilesDelete',
                                data: { checkeds : checkeds },
                                success: function (result) {
                                    if (result.code == 0) {
                                        window.location.reload();
                                    }
                                    else {
                                        showMsg(result.msg);
                                    }
                                }
                            })
                        }, function () {
                        });
                    }
                })
            })
    
            //添加图片至编辑器
            $(".file-img").click(function () {
                var url = $(this).data("url"),
                    title = $(this).data("title");
    
                //添加确认
                layer.confirm('是否需要添加此图片?', {
                    btn: ['确认添加', '我在想想'] //按钮
                }, function () {
                    editor.execCommand('mceInsertContent', false, '<img alt="' + title + '" src="' + url + '"/>');
                    editor.windowManager.close();
                }, function () {});
            })
            
        </script>
     
    

     Ps: 还有很多的不足之处,希望能一起成长, 我的博客地址 jiojun.com 

  • 相关阅读:
    域渗透:ptk(pass the key)
    QQ拼音输入法6.0 DLL劫持实现提权
    进程关系
    进程控制
    进程环境
    系统数据文件和信息
    文件和目录
    标准I/O
    文件描述符标志/文件表项
    SSL安全原理
  • 原文地址:https://www.cnblogs.com/HJbk/p/9728357.html
Copyright © 2011-2022 走看看