前台页面
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> ...
页面效果如下:
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" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="/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"></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(¬e).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
共同学习,写下你的评论
评论加载中...
作者其他优质文章
