SpringBoot集成UEditor实现文本编辑功能

  • 简介
  • 创建实体
  • DAO层
  • Controller层业务实现
  • 页面弹出框设置
  • 页面布局设置
  • js页面设置
  • 设置只显示六条记录 点击事件的查看功能
  • pom.xml配置


简介

UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,而且UEditor功能全面、涵盖流行富文本编辑器特色功能,独创多种全新编辑操作模式。涵盖了各种浏览器之间的差异,提供良好的富文本编辑体验开源,基于MIT协议,支持商业和非商业用户的免费使用和任意修改。允许自由使用和修改代码。(UEditor:https://ueditor.baidu.com/website/index.html)

创建实体

package cn.gson.crm.model.domain;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

/**
 * BizNotice entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "biz_notice")
@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler","operations","roles","menus"})
public class BizNotice implements java.io.Serializable {

	// Fields

	private static final long serialVersionUID = -8466379237715997671L;
	private String id;
	private String title;
	private String content;
	private String publisherId;
	private Boolean state;
	private Timestamp publisherTime;
	private Timestamp createTime;
	private String remark;    //备注

	// Constructors

	/** default constructor */
	public BizNotice() {
	}

	/** minimal constructor */
	public BizNotice(String id) {
		this.id = id;
	}

	/** full constructor */
	public BizNotice(String id, String title, String content,
			String publisherId, Boolean state, Timestamp publisherTime,
			Timestamp createTime, String remark) {
		this.id = id;
		this.title = title;
		this.content = content;
		this.publisherId = publisherId;
		this.state = state;
		this.publisherTime = publisherTime;
		this.createTime = createTime;
		this.remark = remark;
			}

	// Property accessors
	@Id
	@Column(name = "id", unique = true, nullable = false, length = 40)
	public String getId() {
		return this.id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@Column(name = "title")
	public String getTitle() {
		return this.title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	@Column(name = "content", length = 65535)
	public String getContent() {
		return this.content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	@Column(name = "publisher_id", length = 40)
	public String getPublisherId() {
		return this.publisherId;
	}

	public void setPublisherId(String publisherId) {
		this.publisherId = publisherId;
	}

	@Column(name = "state")
	public Boolean getState() {
		return this.state;
	}

	public void setState(Boolean state) {
		this.state = state;
	}

	@Column(name = "publisher_time", length = 19)
	public Timestamp getPublisherTime() {
		return this.publisherTime;
	}

	public void setPublisherTime(Timestamp publisherTime) {
		this.publisherTime = publisherTime;
	}

	@Column(name = "create_time", length = 19)
	public Timestamp getCreateTime() {
		return this.createTime;
	}

	public void setCreateTime(Timestamp createTime) {
		this.createTime = createTime;
	}

	@Column(name = "remark")
	public String getRemark() {
		return this.remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}
}

DAO层

@Repository
public interface BizNoticeDao extends PagingAndSortingRepository<BizNotice, Long>, JpaSpecificationExecutor<BizNotice> {

	public BizNotice findById(String id);
	public List<BizNotice> findTop6ByStateOrderByPublisherTimeDesc(boolean b);
	
}

Controller层业务实现

package cn.gson.crm.controller.system;

/**
 * 描述:通知公告栏信息Controller
 * 
 * @author fyh
 * @date 2018-11-20
 */

@Controller
@RequestMapping("/system/biznotice")
public class BizNoticeController {

	Logger logger = Logger.getLogger(BizNoticeController.class);

	@Autowired
	BizNoticeDao bizNoticeDao;

	@Autowired
	CfgAreaMemberDao cfgAreaMemberDao;

	@Autowired
	CfgWorkAreaDao cfgWorkAreaDao;

	/**
	 * 超级管理员id
	 */
	@Value("${crm.system.super-user-id}")
	Long superUserId;

	@RequestMapping
	public void index() {
	}

	@RequestMapping("/list")
	@ResponseBody
	public DataGrid<BizNotice> list(Integer page, Integer rows, String title, String content, String publisherId,
			String state, String publisherTime, String createTime, String remark) {
		PageRequest pr = new PageRequest(page - 1, rows);

		// 使用了自定义的复杂查询,这就比原生的Specification的语法使用流畅多了
		Page<BizNotice> pageData = bizNoticeDao.findAll(new MySpecification<BizNotice>()
				.and(Cnd.eq("title", title), Cnd.like("content", content), Cnd.like("publisherId", publisherId), // 发布人
						Cnd.eq("state", state), Cnd.like("publisherTime", publisherTime),
						Cnd.eq("createTime", createTime), Cnd.like("remark", remark))
				.desc("createTime"), pr);

		return new DataGrid<BizNotice>(pageData);
	}

	@RequestMapping("/listForm")
	@ResponseBody
	public List<BizNotice> listForm() {
		// jpa规范仅限查询前五条状态为已发布,并且以发布时间倒叙
		List<BizNotice> stateList = bizNoticeDao.findTop6ByStateOrderByPublisherTimeDesc(true);
		return stateList;
	}

	@RequestMapping("/viewNoticeform")
	public void viewNoticeform(String id, Model model, HttpSession session) {
		if (id != null) {
			ObjectMapper mapper = new ObjectMapper();
			BizNotice bizNotice = bizNoticeDao.findById(id);
			try {
				model.addAttribute("bizNotice", mapper.writeValueAsString(bizNotice));
			} catch (JsonProcessingException e) {
				logger.error("json转换错误", e);
			}
		}
	}

	@RequestMapping("/form")
	public void form(String id, Model model) {
		if (id != null) {
			ObjectMapper mapper = new ObjectMapper();
			BizNotice bizNotice = bizNoticeDao.findById(id);
			try {
				model.addAttribute("bizNotice", mapper.writeValueAsString(bizNotice));
			} catch (JsonProcessingException e) {
				logger.error("json转换错误", e);
			}
		}
	}

	@MyLog(value = "删除通知公告信息") // 这里添加了AOP的自定义注解
	@RequestMapping("/delete")
	@Transactional
	@ResponseBody
	public AjaxResult delete(String id, String name) {
		try {
			bizNoticeDao.delete(bizNoticeDao.findById(id));
		} catch (Exception e) {
			return new AjaxResult(false).setMessage(e.getMessage());
		}
		return new AjaxResult();
	}

	@RequestMapping({ "/save", "/update" })
	@Transactional
	@ResponseBody
	public AjaxResult save(@Valid BizNotice bizNotice, String editorValue, HttpSession session, BindingResult br) {
		// 创建这条数据的id
		if (bizNotice != null && StringUtils.isEmpty(bizNotice.getId())) {
			bizNotice.setId(UUIDUtil.creatUUID());
		}
		// 后台自动获取创建人
		Member member = (Member) session.getAttribute(Constants.SESSION_MEMBER_KEY);
		bizNotice.setPublisherId(member.getRealName());
		List<CfgAreaMember> memberList = cfgAreaMemberDao.findByMemberId(member.getId());
		if (memberList == null || memberList.size() == 0) {
			if (member.getId() != superUserId) {
				return new AjaxResult(false, "您不属于任何工区,请联系管理员!");
			}
		}
		if (member.getId() != superUserId) {
			String areaid = memberList.get(0).getAreaId();
			String bdid = cfgWorkAreaDao.findById(areaid).getCfgBidspart().getId();
			bizNotice.setBidspartId(bdid);
		} else {
			bizNotice.setBidspartId("");
		}
		bizNotice.setCreateTime(DateUtil.getTimestampDate());
		bizNotice.setState(false);
		bizNotice.setContent(editorValue);
		try {
			bizNoticeDao.save(bizNotice);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return new AjaxResult();
	}

	@MyLog(value = "发布通知公告信息") // 这里添加了AOP的自定义注解
	@RequestMapping("/noticeSubmit")
	@ResponseBody
	public AjaxResult noticeSubmit(@Valid String id, String name) {
		BizNotice notice = bizNoticeDao.findById(id);
		notice.setState(true);
		notice.setPublisherTime(DateUtil.getTimestampDate());
		bizNoticeDao.save(notice);
		return new AjaxResult();

	}

}

页面弹出框设置

<form class="app-form" id="biznotice-form">
  	<input type="hidden" name="id">
  	<div class="field" padding="5px" >
  	<input class="easyui-textbox" name="title" style="width:100%" data-options="label:'标题:'">
  	</div>
    <div class="field" padding="5px" margin="5px">
    	<script id="content" type="text/plain"  style="width:100%;height:320px;"></script>
    </div>
    <div class="field">
	<input class="easyui-textbox" name="remark" style="width:100%" data-options="label:'备注:'">
	</div>
</form>

<script>
	//ue = new baidu.editor.ui.Editor();
    //ue.render("content",{ zIndex: 10000});
	<#if bizNotice??>
	    $(function () {
	      //var ue = UE.getEditor('content', { toolbars:[[]], zIndex: 10000}).render('content');
	      UE.delEditor('content');
    	  var ue = UE.getEditor('content', { zIndex: 10000});
	      setTimeout(function () {
	        var obj = ${bizNotice};
	        ue.ready(function() {
	   			 ue.setContent(obj.content);
			});
	        $("#biznotice-form").form("load", obj);
	      }, 200);
	    });	
	</#if>
	
	<#if !bizNotice??>
		$(function () {
			UE.delEditor('content');
    	    var ue = UE.getEditor('content', {zIndex: 10000});
		});
	</#if>
</script>

页面布局设置

<div class="easyui-layout" fit="true">
  <div data-options="region:'north',border:false" style="height: 80px;padding: 10px;overflow: hidden;" title="通知公告栏信息">
    <form id="biznotice_search_from" class="searcher-form">
      <input name="publisherId" class="easyui-textbox field" label="发布人:" labelWidth="70">
      <a class="easyui-linkbutton searcher" data-options="iconCls:'fa fa-search'">检索</a>
      <a class="easyui-linkbutton reset" data-options="iconCls:'fa fa-repeat'">重置</a>
    </form>
  </div>
  <div data-options="region:'center',border:false" style="border-top: 1px solid #D3D3D3">
    <table id="biznotice_dg"></table>
  </div>
</div>

js页面设置

define(function () {
  return function () {
    var dg = $("#biznotice_dg");
    var searchFrom = $("#biznotice_search_from");
    var form;
    
    // 使用edatagrid,需要而外导入edatagrid扩展
    dg.datagrid({
      url: '/system/biznotice/list',
      emptyMsg: "未查询到数据",
      idField: "id",
      fit: true,
      rownumbers: true,
      fitColumns: true,
      border: false,
      pagination: true,
      singleSelect: true,
      pageSize: 30,
      columns: [[
	  {
        field: 'title',
        title: '标题',
        width: 30
      },
      {
          field: 'publisherId',
          title: '发布人',
          width: 40
        },
	  {
        field: 'content',
        title: '内容',
        width: 150
      },
	  {
        field: 'publisherTime',
        title: '发布时间',
        width: 60
      },
	  {
        field: 'remark',
        title: '备注',
        width: 40
      },
      {
    	  field: 'state',
          title: '状态',
          width: 30,
          formatter: function (value, row, index) {
        	  if(row.state == false){
        		  return "未发布";
        	  }else{
        		  return "已发布";
        	  }
          }
    	  
      },
	  {
          field: 'test',
          title: '操作',
          width: 70,
          align: 'center',
          formatter: function (value, row, index) {
        	  if(row.state == false){
        		  return authToolBar({
            		 "notice-edit": '<a data-id="' + row.id + '" class="ctr ctr-edit">编辑</a>',
                     "notice-delete": '<a data-id="' + row.id + '" class="ctr ctr-delete">删除</a>',
                     "notice-submit": '<a data-id="' + row.id + '" data-name="' + row.title + '" class="ctr ctr-status">发布</a>'
            		}).join("");
        	  }else{
        		  return authToolBar({ 
                      "notice-delete": '<a data-id="' + row.id + '" data-name="' + row.title + '" class="ctr ctr-delete">删除</a>'
        		  }).join("");
        		  }
        	  }
          }
      ]],
	  toolbar: authToolBar({
	        "notice-create": {
				iconCls : 'fa fa-plus-square',
				text : "创建",
				handler : function() {
					createForm();
				}
		     },
		     "notice-editword": {
				text : "打开文档",
				handler : function() {
					POBrowser.openWindowModeless("system/biznotice/word", "width=1050px;height=900px;");
				}
			 },
			 "biznotice-editexcel":{
				 text : "打开excel",
					handler : function() {
						POBrowser.openWindowModeless("system/biznotice/excel", "width=1050px;height=900px;");
				}
			 }
	  })
    });
    /**
     * 操作按钮绑定事件
     */
    dg.datagrid("getPanel").on('click', "a.ctr-edit", function () {// 编辑按钮事件
      createForm.call(this, this.dataset.id)
    }).on('click', "a.ctr-delete", function () {// 删除按钮事件
      var id = this.dataset.id;
      var name = this.dataset.name;
      $.messager.confirm("删除提醒", "确认删除此记录?", function (r) {
        if (r) {
          $.get("/system/biznotice/delete", {id: id, name: name}, function () {
            // 数据操作成功后,对列表数据,进行刷新
            dg.datagrid("reload");
          });
        }
      });
    }).on('click', "a.ctr-status", function () {// 提交公告
        var id = this.dataset.id;
        var name = this.dataset.name;
        $.messager.confirm("提醒", "确认提交此公告?", function (r) {
          if (r) {
            $.get("/system/biznotice/noticeSubmit", {id: id, name: name}, function () {
            	// 数据操作成功后,对列表数据,进行刷新
	        	dg.datagrid("reload");
            });
          }
        });
      });

    /**
     * 搜索区域事件
     */
    searchFrom.on('click', 'a.searcher', function () {//检索
      dg.datagrid('load', searchFrom.formToJson());
    }).on('click', 'a.reset', function () {//重置
      searchFrom.form('reset');
      dg.datagrid('load', {});
    });


    /**
     * 创建表单窗口
     *
     * @returns
     */
    function createForm(id) {
      var dialog = $("<div/>", {class: 'noflow'}).dialog({
        title: (id ? "编辑" : "创建"),
        iconCls: 'fa ' + (id ? "fa-edit" : "fa-plus-square"),
        height: id ? 700 : 700,
        width: 900,
        href: '/system/biznotice/form',
        queryParams: {
          id: id
        },
        modal: true,
        onClose: function () {
          $(this).dialog("destroy");
        },
        onLoad: function () {
          //窗口表单加载成功时执行
          form = $("#biznotice-form");
        },
        buttons: [{
          iconCls: 'fa fa-save',
          text: '保存',
          handler: function () {
            if (form.form('validate')) {
              $.post("/system/biznotice/save", form.serialize(), function (res) {
                dg.datagrid('reload');
                dialog.dialog('close');
              })
            }
          }
        }]
      });
    }
  }
});

设置只显示六条记录 点击事件的查看功能

<div title="通知公告" collapsible="true" style="height:340px;padding:5px;">
	     	<table id="bizNotice"></table>
</div>

		//通知公告栏
		$('#bizNotice').datagrid({
	      url: '/system/biznotice/listForm',
	      emptyMsg: "未查询到数据",
	      idField: "id",
	      fit: true,
	      rownumbers: false,
	      fitColumns: true,
	      border: false,
	      showHeader:false,
	      singleSelect: true,
	      columns: [[
		      {
		        field: 'title',
		        title: '标题',
		        width: 100,
	      	    formatter: function(value, row, index){
	      	    	if(value.length >25){
	      	    	 val = value.substr(0,25)+'  '+'...';
	      	    	}else{
	      	    	  val = value;
	      	    	}
					 if(index < 3){
						return '<i class="fa fa-bullhorn" aria-hidden="true"></i>' + '	' + val + '  ' + '<img src="../../images/new.gif"/>';
					}else{
						return '<i class="fa fa-bullhorn" aria-hidden="true"></i>' + '	' + val;
					}
			    }
		      },
			  {
		        field: 'publisherTime',
		        title: '发布时间',
		        width: 25,
		        align : 'right',
		        formatter: function(value, row, index){
					return value.substr(0, 11);
			    }
		      }
      	  ]],
      	  onLoadSuccess: function (data) {
	            var panel = $(this).datagrid('getPanel');
	            var tr = panel.find('div.datagrid-body tr');
	            tr.each(function () {
	                var td = $(this).children('td');
	                td.css({
	                    "border-width": "0"
	                });
	            });
	        },
	        onClickRow: function(index, row){
	        	var id = row.id;
	        	viewForm(id);
	        },
	        rowStyler: function(index, row){
				if(index < 3){
				   return 'color:#37A2DA;';
				}
			}
	    });

	//新闻公告超链接页面
    function viewForm(id) {
      	var dialog = $("<div/>", {class: 'noflow'}).dialog({
        title: "关于公告",
        iconCls: 'fa ' + (id ? "fa-edit" : "fa-plus-square"),
        height: 700,
        width: 700,
        href: '/system/biznotice/viewNoticeform',
        queryParams: {
          id: id,
        },
        modal: true,
        onClose: function () {
          $(this).dialog("destroy");
        },
        onLoad: function () {
        },
        buttons: [{
          iconCls: 'fa fa-close',
          text: '关闭',
          handler: function () {
        	  dialog.dialog('close');
          }
        }]
      });
    
    };

pom.xml配置

<dependency>
		    <groupId>cn.songxinqiang</groupId>
		    <artifactId>com.baidu.ueditor</artifactId>
		    <version>RELEASE</version>
</dependency>