关于ruoyi框架整合ueditor富文本编辑器

文章目录

  • 一.关于Ueditor
    • 简介
    • 下载
  • 二.集成步骤
    • 1.下载并添加插件
    • 2.修改include页面
    • 3.修改要使用Ueditor的相关页面
      • 首先修改公告的add页面
      • 然后修改editor页面
    • 4.新增UeditorController
  • 三.测试效果

一.关于Ueditor

简介

Ueditor是一款由百度web前端研发部开发的所见即所得的开源富文本编辑器,具有轻量、可定制、用户体验优秀等特点。可以用于拓展ruoyi的富文本编辑工具

下载

我相信很多人打开Ueditor官网时是这样的
关于ruoyi框架整合ueditor富文本编辑器_第1张图片
虽然下边有教程,但是却不能嵌入ruoyi框架。若依官方有出教程http://doc.ruoyi.vip/ruoyi/document/cjjc.html#%E9%9B%86%E6%88%90ueditor%E5%AE%9E%E7%8E%B0%E5%AF%8C%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%E5%A2%9E%E5%BC%BA
不相信我的可以去看官网,当然Ueditor插件可以去官网下载,因为官网的已经搭建好了。

二.集成步骤

1.下载并添加插件

链接:https://pan.baidu.com/s/1jJL4lK4909XC4C77kMN-Fg
提取码:bkej
下载后解压,将ueditor_config中的ueditor-config.json取出到ueditor文件夹外(取出后可以删掉ueditor_config文件夹),然后将ueditor文件夹放到若依项目的admin-src-main-resources-static-ajax-lib中,此文件夹中大多都是插件,例如summernote(若依默认集成的富文本插件)
关于ruoyi框架整合ueditor富文本编辑器_第2张图片
最后将取出的ueditor-config.json放到resources文件下
关于ruoyi框架整合ueditor富文本编辑器_第3张图片

2.修改include页面

在admin-main-java-resources-templates目录下找的include.html文件
关于ruoyi框架整合ueditor富文本编辑器_第4张图片
在最后添加ueditor,引入插件


<div th:fragment="ueditor-js">
	<script th:src="@{/ajax/libs/ueditor/ueditor.config.js}">script>
	<script th:src="@{/ajax/libs/ueditor/ueditor.all.min.js}">script>
	<script th:src="@{/ajax/libs/ueditor/lang/zh-cn/zh-cn.js}">script>
div>

3.修改要使用Ueditor的相关页面

公告 页面为例我们会修改两个页面,一个是新增页面(add),还有一个编辑页面(editor)
要更换Ueditor富文本工具,我们需要将所有的summernote替换掉。由于我们下载的插件包功能都已经齐全,所以不用怕替换已经优化过的summernote。

首先修改公告的add页面

公告相关页面位置如下图
关于ruoyi框架整合ueditor富文本编辑器_第5张图片
打开add页面后,将公告内容处更换为:
注:更改其他非通知页面注意更改标签的id和name或者class,下边的js中也需要随着更改

DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
	<th:block th:include="include :: header('新增通知公告')" />
head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
	<form class="form-horizontal m" id="form-notice-add">
		<div class="form-group">
			<label class="col-sm-2 control-label is-required">公告标题:label>
			<div class="col-sm-10">
				<input id="noticeTitle" name="noticeTitle" class="form-control" type="text" required>
			div>
		div>
		<div class="form-group">
			<label class="col-sm-2 control-label">公告类型:label>
			<div class="col-sm-10">
				<select name="noticeType" class="form-control m-b" th:with="type=${@dict.getType('sys_notice_type')}">
					<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}">option>
				select>
			div>
		div>
		<div class="form-group">
			<label class="col-sm-2 control-label">公告内容:label>
			
			<div class="col-sm-10">
				<script id="editor" name="noticeContent" type="text/plain" style="height: 300px;">script>
			div>
		div>
		<div class="form-group">
			<label class="col-sm-2 control-label">公告状态:label>
			<div class="col-sm-10">
				<div class="radio-box" th:each="dict : ${@dict.getType('sys_notice_status')}">
					<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
					<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}">label>
				div>
			div>
		div>
	form>
div>
<th:block th:include="include :: footer" />

<th:block th:include="include :: ueditor-js" />
<script type="text/javascript">
	var prefix = ctx + "system/notice";
	//初始化编辑器
	var ue = UE.getEditor('editor');
	//此方法必须在外面,否则会导致下方submitHandler方法中的text定位不到
	function getContentTxt() {
		return UE.getEditor('editor').getContentTxt();
	}

	$("#form-notice-add").validate({
		focusCleanup: true
	});
	//替换掉原有的submitHandler方法
	function submitHandler() {
		if ($.validate.form()) {
			var text = getContentTxt();
			if (text == '' || text.length == 0) {
				$.modal.alertWarning("请输入公告内容!");
				return;
			}
			$.operate.save(prefix + "/add", $('#form-notice-add').serialize());
		}
	}
script>
body>
html>

然后修改editor页面

editor页面修改类似于add,但是也有不同

DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
    <th:block th:include="include :: header('修改通知公告')" />
head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
    <form class="form-horizontal m" id="form-notice-edit" th:object="${notice}">
        <input id="noticeId" name="noticeId" th:field="*{noticeId}"  type="hidden">
        <div class="form-group">
            <label class="col-sm-2 control-label is-required">公告标题:label>
            <div class="col-sm-10">
                <input id="noticeTitle" name="noticeTitle" th:field="*{noticeTitle}" class="form-control" type="text" required>
            div>
        div>
        <div class="form-group">
            <label class="col-sm-2 control-label">公告类型:label>
            <div class="col-sm-10">
                <select name="noticeType" class="form-control m-b" th:with="type=${@dict.getType('sys_notice_type')}">
                    <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{noticeType}">option>
                select>
            div>
        div>
        <div class="form-group">
        
            <label class="col-sm-2 control-label">公告内容:label>
            <div class="col-sm-10">
                <script id="editor" name="noticeContent" type="text/plain" style="height: 300px;">script>
                <textarea id="noticeContent" style="display: none;">[[*{noticeContent}]]textarea>
            div>
        div>
        <div class="form-group">
            <label class="col-sm-2 control-label">公告状态:label>
            <div class="col-sm-10">
                <div class="radio-box" th:each="dict : ${@dict.getType('sys_notice_status')}">
                    <input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:field="*{status}">
                    <label th:for="${dict.dictCode}" th:text="${dict.dictLabel}">label>
                div>
            div>
        div>
    form>
div>
<th:block th:include="include :: footer" />

<th:block th:include="include :: ueditor-js" />
<script type="text/javascript">
    var prefix = ctx + "system/notice";
    //替换summernote相关的函数
    $(function () {
        var text = $("#noticeContent").text();
        var ue = UE.getEditor('editor');
        ue.ready(function () {
            ue.setContent(text);
        });
    })

    function getContentTxt() {
        return UE.getEditor('editor').getContentTxt();
    }

    $("#form-notice-edit").validate({
        focusCleanup: true
    });
	//这个同样要替换
    function submitHandler() {
        if ($.validate.form()) {
            var text = getContentTxt();
            if (text == '' || text.length == 0) {
                $.modal.alertWarning("请输入通知内容!");
                return;
            }
            $.operate.save(prefix + "/edit", $('#form-notice-edit').serialize());
        }
    }
script>
body>
html>

如果页面其他的方法跟summernote无关则不需要处理,如果有相关的话根据实际情况进行处理,一般功能尽量不要耦合,不然很难去更换summernote.

4.新增UeditorController

在admin-main-java-controller-common文件夹下新增一个UeditorController,内容如下:

package com.ruoyi.web.controller.common;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.utils.file.FileUploadUtils;

/**
 * Ueditor 请求处理
 *
 * @author ruoyi
 */
@SuppressWarnings("serial")
@Controller
@RequestMapping("/ajax/libs/ueditor")
public class UeditorController extends BaseController
{
    private final String METHOD_HEAD = "ueditor";
    private final String IMGE_PATH = "/ueditor/images/";
    private final String VIDEO_PATH = "/ueditor/videos/";
    private final String FILE_PATH = "/ueditor/files/";

    @Autowired
    private ServerConfig serverConfig;

    /**
     * ueditor
     */
    @ResponseBody
    @RequestMapping(value = "/ueditor/controller")
    public Object ueditor(HttpServletRequest request, @RequestParam(value = "action", required = true) String action,
                          MultipartFile upfile) throws Exception
    {
        List<Object> param = new ArrayList<Object>()
        {
            {
                add(action);
                add(upfile);
            }
        };
        Method method = this.getClass().getMethod(METHOD_HEAD + action, List.class, String.class);
        return method.invoke(this.getClass().newInstance(), param, serverConfig.getUrl());
    }

    /**
     * 读取配置文件
     */
    public JSONObject ueditorconfig(List<Object> param, String fileSuffixUrl) throws Exception
    {
        ClassPathResource classPathResource = new ClassPathResource("ueditor-config.json");
        String jsonString = new BufferedReader(new InputStreamReader(classPathResource.getInputStream())).lines().parallel().collect(Collectors.joining(System.lineSeparator()));
        JSONObject json = JSON.parseObject(jsonString, JSONObject.class);
        return json;
    }

    /**
     * 上传图片
     */
    public JSONObject ueditoruploadimage(List<Object> param, String fileSuffixUrl) throws Exception
    {
        JSONObject json = new JSONObject();
        json.put("state", "SUCCESS");
        json.put("url", ueditorcore(param, IMGE_PATH, false, fileSuffixUrl));
        return json;
    }

    /**
     * 上传视频
     */
    public JSONObject ueditoruploadvideo(List<Object> param, String fileSuffixUrl) throws Exception
    {
        JSONObject json = new JSONObject();
        json.put("state", "SUCCESS");
        json.put("url", ueditorcore(param, VIDEO_PATH, false, fileSuffixUrl));
        return json;
    }

    /**
     * 上传附件
     */
    public JSONObject ueditoruploadfile(List<Object> param, String fileSuffixUrl) throws Exception
    {
        JSONObject json = new JSONObject();
        json.put("state", "SUCCESS");
        json.put("url", ueditorcore(param, FILE_PATH, true, fileSuffixUrl));
        return json;
    }

    public String ueditorcore(List<Object> param, String path, boolean isFileName, String fileSuffixUrl)
            throws Exception
    {
        MultipartFile upfile = (MultipartFile) param.get(1);
        // 上传文件路径
        String filePath = RuoYiConfig.getUploadPath();
        String fileName = FileUploadUtils.upload(filePath, upfile);
        String url = fileSuffixUrl + fileName;
        return url;
    }
}

添加后根据自己不同的项目包名将引入包删除后重新引入.
这里多说一句,RequestMapping指引的路径要跟ueditor.config.js中的一致,ueditor.config.js在我们放入的ajax-lib-ueditor中,当然其已经自动获取url了

如果有修改也需要修改此文件。
再提一句,我曾维护一个项目的upload被重写了,重写后的upload返回的值不是String类型
关于ruoyi框架整合ueditor富文本编辑器_第6张图片
那么我们通过toString转为字符串是行不通的,会导致我们的图片没法回显,并且路径也不对,这时我们需要自己重写一个upload类,然后自定义一个根据文件路径上传

//根据文件路径上传,返回值为String
 public static final String upload1(String baseDir, MultipartFile file) throws IOException
    {
        try
        {
            return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        }
        catch (Exception e)
        {
            throw new IOException(e.getMessage(), e);
        }
    }
//返回值为String
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
            throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
            InvalidExtensionException
    {
        int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
        if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
        {
            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
        }

        assertAllowed(file, allowedExtension);

        String fileName = extractFilename(file);

        File desc = getAbsoluteFile(baseDir, fileName);
        file.transferTo(desc);
        return getPathFileName(baseDir, fileName);
    }

当然,这upload类所在的路径是(common模块)common-src-main-java-common-utils-file-FileUploadUtils.java文件中

三.测试效果

关于ruoyi框架整合ueditor富文本编辑器_第7张图片
测试成功

你可能感兴趣的:(java,编辑器,前端,spring,boot,template,method)