在使用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

Tinymce 编辑器添加自定义图片管理插件的更多相关文章

  1. 推荐ajaxfilemanager for tiny_mce 比较完善的tiny_mce编辑器的图片上传及图片管理插件PHP版 支持中文

    tiny_mce编辑器,我觉得挺简洁.好用的,但就是图片上传的插件是收费的,而且网上找了半天也没有找到开源好用的上传插件. 不过功夫不负有心人,终于还就被我找到一款相当满意的插件. 这个插件的名字叫a ...

  2. TinyMCE编辑器图片上传扩展(base64方式),asp.net mvc5

    编辑器上传图片一般都是先上传到服务器中,若是用户取消或忘记提交表单就产生一张废图在空间里面,时间一长就产生大量占用空间的无用图片,现在就试试提交前先用base64,提交后,在后台处理编辑器内容中的&l ...

  3. 在线HTML文档编辑器使用入门之图片上传与图片管理的实现

    在线HTML文档编辑器使用入门之图片上传与图片管理的实现: 官方网址: http://kindeditor.net/demo.php 开发步骤: 1.开发中只需要导入选中的文件(通常在 webapp ...

  4. WordPress TinyMCE 编辑器增强技巧大全

    说到WordPress自带的TinyMCE 编辑器,有些国人总是不太满意.针对这个情况,倡萌已经介绍了一些增强或替代的方法: WordPress编辑器增强插件:TinyMCE Advanced Wor ...

  5. tinymce 编辑器 上传图片

    tinymce编辑器进行本地图片上传 首先下载tinymce.js之后 在form中添加一个<textarea>元素 给其一个id和name 然后就可以初始化编辑器了 tinymce.in ...

  6. 在Tinymce编辑器里,集成数学公式

    在以前,需要在Web页面显示数学公式,常用的都是先制作成图片,然后插入到页面里.这使得后期对数学公式的修改变的麻烦,同时也不利于搜索引擎搜索. 本文将介绍如何在TinyMce编辑器里集成数学公式.先看 ...

  7. 分享22款响应式的 jQuery 图片滑块插件

    响应式(Responsive)设计的目标是要让产品界面能够响应用户的行为,根据不同终端设备自动调整尺寸,带给用户良好的使用体验.这篇文章收集了22款优秀的响应式 jQuery 幻灯片插件,它们能够帮助 ...

  8. ImageLightbox.js – 响应式的图片 Lightbox 插件

    ImageLightbox.js 是一款很简洁的用于显示图片灯箱效果(Lightbox)的插件,没有字幕,导航按钮或默认背景.如果默认功能不够用的话,你可以很容易地自定义 JavaScript 函数扩 ...

  9. CKEditor在线编辑器增加一个自定义插件

    CKEditor是一个非常优秀的在线编辑器,它的前身就是FCKEditor,CKEditor据官方说是重写了内核的,但功能和性能比FCKEditor更为强大和优越.记得07年的时候第一次接触FCKEd ...

随机推荐

  1. 字符串模式匹配算法1 - BF和KMP算法

    在字符串S中定位/查找某个子字符串P的操作,通常称为字符串的模式匹配,其中P称为模式串.模式匹配有多种算法,这里先总结一下BF算法和KMP算法. 注意:本文在讨论字符位置/指针/下标时,全部使用C语法 ...

  2. STM32-RTC实时时钟-毫秒计时实现

    OS:Windows 64 Development kit:MDK5.14 IDE:UV4 MCU:STM32F103C8T6 1.RTC时钟简介 STM32 的实时时钟(RTC)是一个独立的定时器, ...

  3. shell-007:数据库备份,本地保留7天,远程机器保留一个月

    ## #!/bin/bash d1=`date +%w` # 以周几有变量 d2=`date +%d` # 以每月第几天为变量 local_bakdir=/bak/mysql # 本地备份目录 rem ...

  4. npm install 报错:ERR! code EINTEGRITY 解决方案

    npm升级后,npm install 报错了,报错信息:ERR! code EINTEGRITY到处百度搜索解决方案,终于找到了!“npm cache verify”这条命令帮助了不少人 npm ca ...

  5. python实现数据库增删改查

    column_dic = {"id": 0, "name": 1, "age": 2, "phone": 3, &quo ...

  6. [转] Linux History(历史)命令用法 15 例

    [From]https://linuxtoy.org/archives/history-command-usage-examples.html 如果你经常使用 Linux 命令行,那么使用 histo ...

  7. SqlServer索引、优化、约束、连接

    索引的创建和删除 create index in_name on person(name) --创建索引 drop index person.in_name --删除索引 create index i ...

  8. gradle 打包 jar (一波三折)

    第一次尝试,打包成功,运行失败 build.gradle 打包 jar { baseName 'testJar' from { //添加依懒到打包文件 //configurations.compile ...

  9. Webapps初步_认识HTTP例子程序读取

    package servlet_01; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io. ...

  10. 15.Iterator和for...of循环

    1.Iterator(遍历器)的概念 JavaScript原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6又添加了Map和Set.这样就有了四种数据集合,用户还可以 ...