アリeggフレームワークに基づいてブログを構築(6)--文章を閲覧、発表する


関連記事
アリeggフレームワークに基づくブログ構築(1)——開発準備アリeggフレームワークに基づくブログ構築(2)——Hello Worldアリeggフレームワークに基づくブログ構築(3)——登録と登録アリeggフレームワークに基づくブログ構築(4)——権限制御アリeggフレームワークに基づくブログ構築(5)——トップナビゲーションバーアリeggフレームワークに基づくブログ構築(6)——閲覧、発表文章はアリeggフレームワークに基づいてブログを構築する(7)--文章を編集する
git
https://github.com/ZzzSimon/e...好きならいいね!
本文
文章を閲覧、発表するのは簡単に言えばarticleテーブルの読み取り/書き込み操作です.
Articleテーブル設計
フィールドの説明
名前
説明する
id
プライマリキーid
title
記事タイトル
url
記事アクセスpath
detail
文章の内容
author
作者、対応username
invisible
秘密にするかどうか、秘密にするかどうかは文章のリストに表示されません
create_time
文章の最初の発表時間
update_time
文章の最後の修正時間
sqlスクリプト
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
  `id` varchar(20) NOT NULL,
  `title` varchar(255) NOT NULL,
  `url` varchar(255) NOT NULL,
  `detail` varchar(4096) NOT NULL,
  `author` varchar(255) NOT NULL,
  `invisible` int(1) NOT NULL DEFAULT '0',
  `create_time` datetime NOT NULL,
  `update_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ページデザイン
記事を参照
文章を発表する
きのうせっけい
記事を参照
  • 記事タイトルをクリックして記事の詳細を表示
  • 文章を発表する
  • 記事タイトル
  • を入力
  • 秘密保持の有無を選択し、秘密保持は文章リスト
  • に表示されない.
  • 記事を保存
  • markdown
  • をサポート
    markdownサポート
    フロントエンドmdエディタでは、Editor.mdを選択しました.
    公式ドキュメント:http://pandao.github.io/edito...
    フロントエンドコード
    記事を参照
    list.tpl記事リストapp/view/article/list.tplファイルを作成します.
    {% extends "parent.tpl" %}
    
    {% block head %}
        
    {% endblock %}
    
    
    {% block content %}
    
      {% for item in list %}
    • {{ item.title }}
      {{item.author}} {{helper.formatTime(item.update_time)}}
    • {% endfor %}
    {% endblock %}

    detail.tpl記事の詳細app/view/article/detail.tplファイルを作成します.
    {% extends "parent.tpl" %}
    
    {% block head %}
    {{article.title}}
    
    
    
    
    
    
    
    
    
    {% endblock %}
    
    
    {% block content %}
    
    
    
    
    {% endblock %} {%block script%} $(function () { const markdown = $('#detail').text(); var testEditormdView = editormd.markdownToHTML("test-editormd-view", { markdown: markdown,//+ "\r
    " + $("#append-test").text(), //htmlDecode : true, // HTML , , htmlDecode: "style,script,iframe", // you can filter tags decode //toc : false, tocm: true, // Using [TOCM] //tocContainer : "#custom-toc-container", // ToC //gfm : false, //tocDropdown : true, // markdownSourceCode : true, // Markdown , Textarea emoji: true, taskList: true, tex: true, // flowChart: true, // sequenceDiagram: true, // }); });
    {% endblock %}

    ここで注意しなければならないのは1点です:mdの内容はまずテンプレートを通じて、1つの隠れたdivの中でレンダリングされます.その後、editormdでダイナミックにレンダリングされます.
    文章を発表する
    article.tpl発表記事app/view/article/article.tplファイルを作成します.
    {% extends "parent.tpl" %}
    
    {% block head %}
    Markdown Editor
    
    
    {% endblock %}
    
    {% block content %}
    
    
    {% endblock %} {% block script %} let testEditor = editormd("test-editormd", { width: "100%", height: 740, path: '/public/editormd/lib/', // theme: "dark", // previewTheme: "dark", // editorTheme: "pastel-on-dark", // markdown: md, codeFold: true, //syncScrolling : false, saveHTMLToTextarea: true, // HTML Textarea searchReplace: true, //watch : false, // htmlDecode: "style,script,iframe|on*", // HTML , , //toolbar : false, // //previewCodeHighlight : false, // HTML , emoji: true, taskList: true, tocm: true, // Using [TOCM] tex: true, // TeX , flowChart: true, // , sequenceDiagram: true, // / , , //dialogLockScreen : false, // , , true //dialogShowMask : false, // , , true //dialogDraggable : false, // , , true //dialogMaskOpacity : 0.4, // , , 0.1 //dialogMaskBgColor : "#000", // , , #fff imageUpload: true, imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"], imageUploadURL: "/edit/uploadPic?_csrf={{ ctx.csrf | safe }}", /* : { success : 0 | 1, //0 ;1 message : " ", url : " " // }*/ onload: function () { console.log('onload', this); //this.fullscreen(); //this.unwatch(); //this.watch().fullscreen(); //this.setMarkdown("#PHP"); //this.width("100%"); //this.height(480); //this.resize("100%", 640); } }); $('#save').bind('click', function () { data = { article: { title: $('#title').val(), detail: testEditor.getMarkdown(), invisible: $('#invisible').prop('checked') ? 1:0 } }; $.post('/edit/save?_csrf={{ ctx.csrf | safe }}', data, function (resp) { if (resp.flag === '1') { window.location.href = resp.url; } }) }) {% endblock %}

    ここで注意しなければならないのは、ajaxのデフォルトはリダイレクトされていないので、保存に成功すると、文章のアクセスurlを返し、コールバック関数でリダイレクトする必要があります.
    バックエンドコード
    ArticleController app/controller/article.jsファイルを作成します.
    const Controller = require('egg').Controller;
    
    class ArticleController extends Controller {
        async list() {
            const ctx = this.ctx;
            const articleList = await ctx.service.article.list();
            await ctx.render('article/list.tpl', { list: articleList });
        }
    
        async detail(){
            const ctx = this.ctx;
            const queryRes = await ctx.service.article.detail(ctx.params.id);
            ctx.logger.info(queryRes);
            await ctx.render('article/detail.tpl', { article: queryRes[0] });
        }
    }
    
    module.exports = ArticleController;

    EditController app\controller\edit.jsファイルを作成します.
    const Controller = require('egg').Controller;
    const fs = require('mz/fs');
    
    
    class EditController extends Controller{
        async editHtm(){
            await this.ctx.render('article/edit.tpl');
        }
        async save(){
            const ctx = this.ctx;
            const article = ctx.request.body.article;
            article.id = ctx.helper.uuid();
            article.url = '/article/'+article.id+'.htm';
            article.author = ctx.session.user.username;
            const nowTime = new Date();
            article.create_time = nowTime;
            article.update_time = nowTime;
            const result = await ctx.service.article.save(article);
            if (result) {
                ctx.body = {flag:'1',msg:'    ',url:article.url}
            }else {
                ctx.body = {flag:'0',msg:'    '}
            }
        }
    
        async uploadPic(){
            const { ctx } = this;
            const file = ctx.request.files[0];
            let filenameNew = ctx.helper.uuid() +'.'+  file.filename.split('.').pop();
            let filepathNew = this.config.baseDir+'\\app\\public\\mdPic\\'+filenameNew;
            //            
            await fs.rename(file.filepath, filepathNew);
            // editormd      
            ctx.body = {
                success : 1, //0      ;1      
                message : "    ",
                url     : filepathNew.split(this.config.baseDir+'\\app')[1] //        
            }
        }
    }
    
    module.exports = EditController;

    ここで注意しなければならないのは1点です.
  • uoloadPicメソッドは、主にmdエディタの画像アップロードに使用されます.

  • ArticleService app/service/article.jsファイルを作成します.
    const Service = require('egg').Service;
    
    class ArticleService extends Service {
        async list() {
            const sql = "SELECT url,title,author,update_time FROM article WHERE invisible = 0";
            const list =await this.app.mysql.query(sql);
            return list;
        }
    
        async detail(id = 1){
            const sql = "SELECT title,detail,author,update_time FROM article WHERE id = ?";
            return await this.app.mysql.query(sql,[id])
        }
    
        async save(article = {}){
            const res = await this.app.mysql.insert('article',article);
            return res.affectedRows === 1;
        }
    
    
    }
    
    module.exports = ArticleService;

    router.js app/router.jsに内容を追加します.
    router.get('/edit.htm',controller.edit.editHtm);
    router.get('/article/:id.htm',controller.article.detail);
    router.get('/articleList.htm', controller.article.list);
    
    router.post('/edit/save',controller.edit.save);
    router.post('/edit/uploadPic',controller.edit.uploadPic);

    の最後の部分
    読み終わって役に立つと思ったら、作者に好きなものをあげてください.ありがとう!