在使用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",
- width: 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 { width:160px; }
- .file-list li .img-wapper img{width:100%; height:160px;}
- .file-list li .file-name { padding: 0 10px; width: 100%; overflow:hidden; line-height: 30px; height:30px; color: #666; font-size: 12px; background: #fafafa; }
- .file-list li .file-name .layui-form-checkbox{width: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