继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

beego开发轻博客——第五讲 文章录入

慕姐8265434
关注TA
已关注
手记 1147
粉丝 221
获赞 1064

前台页面

1. 我们采用“ wangeditor”作为 富文本编辑器 编辑器

wangEditor 是一款 轻量级 web 富文本编辑器。配置方便,使用简单。支持 IE10+ 浏览器。

2 新增 views->note_new.html 文件,核心代码如下
<body class="lay-blog">
        ...
    <form class="layui-form layui-form-pane" action="">        <div class="layui-form-item">
            <label class="layui-form-label">标题</label>
            <div class="layui-input-block">
                <input type="text" name="title" required=""
                        value=""
                        lay-verify="required" placeholder="请输入标题"
                        autocomplete="off" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item layui-form-text">
            <label class="layui-form-label">内容</label>
            <div class="layui-input-block">
                <div id="edit"></div>
            </div>
        </div>
        <div class="layui-form-item">
            <button class="layui-btn" lay-submit=""
                    lay-filter="save">提交            </button>
        </div>
    </form>
       ...



页面效果如下:

webp

image.png

3. wangEditor使用

我们只需要引入wangEditor.min.js 文件,调用window.wangEditor("元素id").create() 就可 初始化富文本页面 。我继续修改views->note_new.html 文件。

<body>...<form>... <div id="edit"><div> ...</form>...
{{template "comm/footer.html" .}}<script type="text/javascript" src="/static/lib/wangEditor/wangEditor.min.js"></script><script>
    layui.use([...], function () {
        ...        // 初始化 wangEditor
        var E = window.wangEditor;        var editor = new E('#edit');      // 图片不采用上传模式,直接保存到数据库
        editor.customConfig.uploadImgShowBase64 = true;
        editor.customConfig.pasteFilterStyle = false;
        editor.customConfig.zIndex = 1;
        editor.create();
    });</script>

定义数据库表

新增models->note.go 定义文章表,代码如下
type Note struct {
    gorm.Model
    Key     string `gorm:"unique_index;not null;"` //文章唯一标示
    UserID  int // 用户id
    User    User  //用户
    Title   string //文章标题
    Summary string `gorm:"type:text"` //概要
    Content string `gorm:"type:text"` //文章内容
    Visit   int    `gorm:"default:0"` //浏览次数
    Praise  int    `gorm:"default:0"` // 点赞次数}

新增文章的页面显示

1.  我们需要为文章新增页面添加路由路径,以此我们新增一个新的NoteController控制器。新增 controllers->note.go文件添加如下代码
type NoteController struct {
    BaseController
}// @router /new [get]func (ctx *NoteController) NewPage() {
    ctx.Data["key"] = uuid.NewUUID().String()
    ctx.TplName = "note_new.html"}

上面代码中有个ctx.Data["key"] = uuid.NewUUID().String()。试想如果用户打开新增文章页面后,维护好数据,当点击保存按钮时候,不小心多点几次,难道系统就会多新增几个重复的文章记录?因此,我们添加了ctx.Data["key"] = uuid.NewUUID().String() 使每打开新增文章页面都会有一个唯一的key 在当前页面上。当点击保存时,会将页面key传回到后台,这样后台可以更具key开判断用户是新增还是修改!刚才说的情况用户多次点击,第一次是新增,之后都是修改。

2. 与文章调整相关的功能,必须是登陆的用户,且登陆的用户的必须是管理员。我们修改 NoteController控制器,添加NestPrepare方法。每次发送的请求,当路由到NoteController控制器相应的方法时,都会去调用NestPrepare方法,用来添加判断用户必须登陆且为管理员。修改controllers->note.go,代码如下
func (ctx *NoteController) NestPrepare() {
    ctx.MustLogin()//用户必须登陆,没有登陆就返回错误
    if ctx.User.Role != 0 {//不是管理员,之前返回错误
        ctx.Abort500(syserrors.NewError("您没有权限修改文章", nil))
    }
}
3. 我们采用的beego的注解路由,我需要将NoteController控制器 注入beego的Include上。修改routers->router.go文件,修改如下:
func init() {
    ...
    beego.AddNamespace(
        beego.NewNamespace(            "note",
            beego.NSInclude(&controllers.NoteController{}),
        ),
    )
}

到此,新增文章的路由路径为:note/new

4. 添加新增文章的操作入口->修改用户管理页面(views->user.html) 添加按钮,点击跳转到文章新增页面。修改views->user.html文件,修改代码如下:
...
{{if .IsLogin}}
    ...
  {{if eq .User.Role 0}}    <h4 class="item-title">
        <p>
            <a href="/note/new"><i class="layui-icon layui-icon-add-1">&#xe654;</i><span>新增文章</span></a>
        </p>
    </h4>{{end}}
...

新增文章的页面保存功能

1. 我们新约定 文章新增的路由路径为:/note/save/:key
2. 添加页面逻辑,当保存时,我们将页面用户维护的文章数据用ajax发送post请求到后台服务,服务对于的路径为/note/save/:key,我们需要修改views->note_new.html文件,添加如下代码
...<script>
    layui.use(['form', 'jquery', 'layer', 'sysn'], function () {
        ...
      form.on('submit(save)', function (fromdata) {
        sysn.post("/note/save/{{.key}}", fdata)
            .success(function (data) {
               layer.msg("保存成功!");               if (data.action) {
                    setTimeout(function () {                         window.location.href = data.action;
                    }, 300)
               }
            }).run();
      }
}</script>...
3. 调整数据库

3.1 我们之前定义的文章的数据库中表结构中key是不能重复的,是作为文章的唯一标示。因此我们新增的时候都需要先判断 key是否存在,如果存在就更新不存在就新增。我们修改models->note.go 添加按key查询文章的方法。

func QueryNoteByKeyAndUserId(key string, userid int) (note Note, err error) {    return note, db.Model(&Note{}).Where("key = ? and user_id = ?", key, userid).Take(&note).Error
}

3.2 需要将文章的数据保存到数据库,因此我们要新增方法,用来保存文章数据。代码如下:

func SaveNote(n *Note) error {    return db.Save(n).Error
}
4. 调整控制器NoteController

4.1 将来我们需要将文章在首页列出来,我们不能将文章的所有的内容都显示在首页,因此我们需要截取文章前600个字作为文章的摘要保存到数据库。这里我们用到golang的第三方库github.com/PuerkitoBio/goquery,用来解析文章的html文档。修改controllers->note.go 添加截取文章摘要的方法,代码如下。

// 截取content摘要//content >文章 > html文档func getSummary(content string) (string, error) {   // bytes.Buffer,非常常用。
    var buf bytes.Buffer
    buf.Write([]byte(content))    // 用goquery来解析content
    doc, err := goquery.NewDocumentFromReader(&buf)    if err != nil {        return "", err
    }    // Text() 得到body元素下的文本内容(去掉html元素)
    str := doc.Find("body").Text()    // 截取字符串
    if len(str) > 600 {
        str = str[0:600] + "..."
    }    return str, nil
}

4.1 新增保存文章的方法 ,修改controllers->note.go ,代码如下

// @router /save/:key [post]func (ctx *NoteController) Save() {    //得到页面的传过来 key 
    key := ctx.Ctx.Input.Param(":key")    // 判空,为空就返回错误。
    title := ctx.GetMustString("title", "标题不能为空!")
    content := ctx.GetMustString("content", "内容不能为空!")    //获取文章摘要
    summary, _ := getSummary(content)    // 根据key查询文章
    note, err := ctx.Dao.QueryNoteByKeyAndUserId(key, int(ctx.User.ID))
    var n models.Note    if err != nil {        //存在错误,但是当错误不是查不到数据的错误,那就返回错误
        if err != gorm.ErrRecordNotFound {
            ctx.Abort500(syserrors.NewError("保存失败!", err))
        }       // 查不到数据,那就做新增文章操作
        n = models.Note{
            Key:     key,
            Summary: summary,
            Title:   title,
            Files:   files,
            Content: content,
            UserID:  int(ctx.User.ID),
        }
    } else {        //查询不报错,这存在文章,那就做更新文章操作
        n = note
        n.Title = title
        n.Content = content
        n.Summary = summary
        n.Files = files
        n.UpdatedAt = time.Now()
    }    //保存文章 SaveNote 是根据id来判断是更新还是新增,id存在就更新,不存在就新增。
   //上面更新操作是,从数据库查出来的文章记录,修改数据,所以是存在id的。
    if err := ctx.Dao.SaveNote(&n); err != nil {
        ctx.Abort500(syserrors.NewError("保存失败!", err))
    }
    ctx.JSONOk("成功")
}



作者:qq归位
链接:https://www.jianshu.com/p/fb0a69412c3d


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP