当前位置:   article > 正文

SpringBoot整合editor.md实现markdown语法的编辑器

SpringBoot整合editor.md实现markdown语法的编辑器

2、SpringBoot整合editor.md实现markdown语法的编辑器

内容编辑页面

edit.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" th:src="@{/js/jquery-3.5.1.min.js}"></script>
    <link rel="stylesheet" th:href="@{/editormd/css/editormd.css}"/>
    <script rel="script" th:src="@{/editormd/js/editormd.min.js}"></script>
</head>
<body>

<div>
    <input type="text" name="title" id="title" th:value="${editor.getTitle()}">
    <input type="hidden" name="id" id="id" th:value="${editor.getId()}">
</div>
<div class="editormd" id="test-editormd">
    <textarea class="editormd-markdown-textarea" name="test-editormd-markdown-doc" id="content" th:text="${editor.getContent()}"></textarea>
    <!-- 第二个隐藏文本域,用来构造生成的HTML代码,方便表单POST提交,这里的name可以任意取,后台接受时以这个name键为准 -->
    <textarea class="editormd-html-textarea" name="editormd-html-textarea" id="htmlContent" th:text="${editor.getHtmlContent()}"></textarea>
</div>

<div>
    <button onclick="saveHtml()">保存</button>
</div>


<script type="text/javascript">
    var testEditor;

    $(function () {
        testEditor = editormd("test-editormd", {
            width: "70%",
            height: 640,
            syncScrolling: "single",
            path: "/editormd/lib/",
            //这个配置在simple.html中并没有,但是为了能够提交表单,使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中,方便post提交表单。
            saveHTMLToTextarea: true, //这个配置,方便post提交表单
            tocm: true, // Using [TOCM]
            tex: true,// 开启科学公式TeX语言支持,默认关闭

            flowChart: true,//开启流程图支持,默认关闭

            /**上传图片相关配置如下*/
            imageUpload : true,
            imageFormats : ["jpg", "jpeg", "gif", "png"],
            imageUploadURL : "/blog/imgUpload",//注意你后端的上传图片服务地址
            /*上传图片成功后可以做一些自己的处理*/

            //加载完成
            onload: function () {
                // alert("上传成功!");
                //console.log('onload', this);
                //this.fullscreen();
                //this.unwatch();
                // this.watch().fullscreen();
                // this.width("100%");
                // this.height(480);
                // this.resize("100%", 640);
            },
        });
    });


    function saveHtml() {
        var  id = $("#id").val();
        var  title = $("#title").val();
        var content = $("#content").val();
        var htmlContent = $("#htmlContent").val();


        $.ajax({
            url: "/blog/save/" + id,
            type: "post",
            data: {
                title: title,
                content:content,
                htmlContent:htmlContent
            },
            success:function () {
                alert("发布成功");
            },
            error:function () {
                alert("发布失败");
            }
        });
    }

</script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

内容展示页面

preview.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>博客展示</title>
    <link rel="stylesheet" th:href="@{/editormd/css/editormd.css}"/>
    <link rel="stylesheet" th:href="@{/editormd/css/editormd.preview.min.css}" />
    <link rel="stylesheet" th:href="@{/editormd/css/editormd.css}"/>

</head>
<body>
<div id="test-editormd">
      <textarea style="display:none;" placeholder="markdown语言" th:text="${editor.getContent()}">#Editor.md</textarea>
</div>

<script type="text/javascript" th:src="@{/js/jquery-3.5.1.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/lib/marked.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/lib/raphael.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/lib/flowchart.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/lib/jquery.flowchart.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/lib/sequence-diagram.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/lib/underscore.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/lib/prettify.min.js}"></script>
<script type="text/javascript" th:src="@{/editormd/js/editormd.min.js}"></script>
<script type="text/javascript">
    var testEditor;

    $(function () {
        // testEditor = editormd.markdownToHTML("content",{
        //     width: "100%",
        //     height: 600,
        //     path: "/editormd/lib/", //依赖lib文件夹路径
        //     preview: true,
        //     watch: true,
        //     editor: false
        // });
        testEditor = editormd.markdownToHTML("test-editormd", {
            htmlDecode      : "style,script,iframe",
            emoji           : true,
            taskList        : true,
            tex             : true,  // 默认不解析
            flowChart       : true,  // 默认不解析
            sequenceDiagram : true  // 默认不解析
        });

    })
</script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

博客的Controller

package com.qykhhr.societywebsite.controller;

import cn.hutool.core.util.IdUtil;
import com.qykhhr.societywebsite.entity.Editor;
import com.qykhhr.societywebsite.entity.FileInfo;
import com.qykhhr.societywebsite.entity.User;
import com.qykhhr.societywebsite.service.Impl.BlogServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * @author 雨林
 */
@Slf4j
@Controller
@RequestMapping("/blog")
public class BlogController {

    @Autowired
    BlogServiceImpl blogService;

    /**
     * 配置文件中配置文件保存的路径
     */
    @Value("${img.location}")
    private String folder;


    /**
     * 去博客(文章)的首页(列表)
     * @return
     */
    @GetMapping("/toBlogIndex")
    public String toBlogIndex() {
        return "blog/index";
    }

    /**
     * 修改已经编辑过的文章
     * 先通过传入的文章id得到Editor对象,然后用Model将editor对象带入edit页面中
     * 在edit页面使用el表达式显示已经写过的文章内容,以及标题等
     * @param id
     * @param request
     * @param model
     * @return
     */
    @GetMapping("/toUpdateBlog/{id}")
    public String toBlogEdit(@PathVariable("id")String id, HttpServletRequest request,Model model) {
        //从sessio域中获取对象
        User user = (User) request.getSession().getAttribute("user");
        System.out.println("id = " + id);
        //先找到这个文章,然后放到model中
        Editor  editor = blogService.queryEditor(id);
        if(editor != null){
            model.addAttribute("editor",editor);
            return "blog/edit";
        }else{
            return "error/4xx";
        }
    }

    /**
     * 去编辑页面,只是编辑
     * 从session域中获取登录的User,然后通过hutool生成id,然后结合uid生成一个唯一文章的id
     * 再设置editor的基本信息,设置内容、标题都为空,是为了避免在edit页面被el表达式调用为null
     * @param request
     * @param model
     * @return
     */
    @GetMapping("/toEdit")
    public String toBlogEditPage(HttpServletRequest request,Model model) {

        Editor editor = new Editor();
        //生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42
        String simpleUUID = IdUtil.simpleUUID();

        //设置博客的基本信息
        //设置文章id
        editor.setId(simpleUUID);

        //避免被el在null调用
        editor.setTitle("");
        editor.setCreate_datetime(new Date());
        editor.setContent("");
        editor.setHtmlContent("");
        model.addAttribute("editor",editor);

        return "blog/edit";
    }

    /**
     * 保存/更新 文章,edit页面的数据被自动封装为Editor对象
     * @param editor
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @PostMapping("/save/{id}")
    public String saveBlog(@PathVariable("id")String id, Editor editor, HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User) request.getSession().getAttribute("user");
        //设置文章的uid
        editor.setUid(user.getUid());

        System.out.println("editor = " + editor);
        System.out.println("edit.getId" + editor.getId());
        System.out.println("edit.getUid" + editor.getUid());
        System.out.println("article.getTitle()" + editor.getTitle());
        System.out.println("article.getContent() = " + editor.getContent());

        Editor editorById = blogService.queryEditor(id);

        System.out.println("saveBlog editorById = " + editorById);

        //必须要在去博客页面就有唯一id,不能在保存这里生成唯一文章id,要不然就会一直保存

        //如果数据库中已经有该id,给就是更新文章
        if(editorById != null){
            blogService.updateBlog(editor);
        }else {
            blogService.saveBlog(editor);
        }
        return "blog/success";
    }


    /**
     * 预览,传入文章id,在数据库中查到markdown格式的内容信息并封装成Editor对象,通过Model带入到preview页面并被解析
     * @param id
     * @param
     * @return
     */
    @GetMapping("/preview/{id}")
    public String preview(@PathVariable(value = "id") String id,Model model,HttpServletRequest request) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        Editor editor = blogService.queryEditor(id);
        if(user.getUid().equals(editor.getUid())){
            System.out.println("editor = " + editor);
            model.addAttribute("editor", editor);
            return "blog/preview";
        }else {
            return "error/4xx";
        }

    }


    /**
     * 图片的上传
     *
     * @param request
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/imgUpload")
    @ResponseBody
    public FileInfo imageUpload(HttpServletRequest request, @RequestParam(value = "editormd-image-file", required = false) MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            //获取文件名
            String filename = file.getOriginalFilename();

            String[] split = filename.split("\\.");
            //只接受jpg、png、gif、jpeg文件
            if("jpg".equalsIgnoreCase(split[1]) || "png".equalsIgnoreCase(split[1]) || "gif".equalsIgnoreCase(split[1]) || "jpeg".equalsIgnoreCase(split[1])){
                String simpleUUID = IdUtil.simpleUUID();
                String photoName = simpleUUID + "." + split[1];

                file.transferTo(new File(folder + photoName));


                //http://localhost:8080 //获取协议号
                String basePath = request.getScheme()
                        + "://"
                        + request.getServerName()//获取IP地址
                        + ":"
                        + request.getServerPort()//获取端口号
                        + request.getContextPath();//获取工程路径


                return new FileInfo(1, "上传成功", basePath + "/upload/" + photoName);
            }
        }
        return null;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/616071
推荐阅读
相关标签
  

闽ICP备14008679号