文章显示
1. 功能分析
文章的显示功能,首先我们需要添加路由,约定文章显示的路由路径为"/details/[文章的key]",再添加路由对应的控制器,我们需要根据key查找到文章的记录,返回给页面。
根据文字的key查询文章的数据库方法,我们之前在新增文章的时候已经添加。
2. 控制器逻辑调整2.1 修改controllers->index.go添加GetDetails,查询文章信息返回给页面,代码如下(请留意代码中的注解,都是逻辑说明)://@router /details/:key [get]func (this *IndexController) GetDetails() { //得到页面传过来的文章的key
key:= this.Ctx.Input.Param(":key") //到数据库中根据key查询文章
note,err:=models.QueryNoteByKey(key) if err!=nil{ //查询有问题,就提示页面文章不存在
this.Abort500(syserror.New("文章不存在",err))
} //将文章的信息放回给页面
this.Data["note"] = note this.TplName="details.html"}
3. 前台页面调整3.1 我们修改views->index.html 页面,修改跳转文章详情的链接,改成我们定义好的路由路径。修改代码如下...
{{.Title}}
发布于:{{date .UpdatedAt "Y-m-d H:i:s"}}
...3.1 我们修改views->index.html 页面,将文章摘要信息显示的部分抽取出来保存为模版,并且新增文件views->comm->note_summary_tpl.html。3.1.1 views->index.html 修改代码如下{{ range .notes}}
{{template "comm/note_summary_tpl.html" .}}
...
{{end}}
3.1.2 views->comm->note_summary_tpl.html修改代码如下
{{.Title}}
发布于:{{date .UpdatedAt "Y-m-d H:i:s"}}
{{.Summary}}
{{str2html .Content}}
...3.3 我们修改views->details.html 页面,嵌入views->comm->note_tpl.html模版页面,显示文章内容,修改代码如下...{{template "comm/note_tpl.html" .note }}
...文章的显示功能已经实现
文章修改
1. 功能分析
1、我们需要给文章修改功能添加操作入口,我们使用layui提供的fixbar作为操作按钮。
2、页面需要的数据:我们要判断用户是否登陆,用户是否有修改文章的权限,同时我们也有判断当前的用户id是否和当前文章所属用户的id相等,只有满足这些条件才能对文章进行修改和删除的操作。修改文章时我们需要带入文章的key。因此我们要拿到当前登陆的用户的信息,还要拿到当前文章详情页面的文章的所属用户的id和文章的key值。
3、页面要拿到当前登陆的用户的信息,我们要将用户信息保存到html页面中类型为json对象的user变量。为了得到user的json对象,我们需要定义“gorm定义表结构的结构体”的json输出的格式。
4、我们定义修改文章的路由路径为:/edit/[当前文章的key],然后路由对应的控制器方法的逻辑是:根据key和当前登陆的用户找到文章数据(这儿我们需要新增数据库方法),指定渲染模版note_new.html,修改note_new.html,使其能够显示文章具体信息。而note_new.html模版,在文章新增的时候,我们就已经支持文章修改的功能,我们只需修改文章保存的控制器方法,添加保存后返回的跳转页面路径,跳转到文章详情页面。
2. 数据库逻辑调整2.1 添加根据用户id和文章的key查询文章的方法,修改models->note.go文件,添加QueryNoteByKeyAndUserId方法,代码如下:func QueryNoteByKeyAndUserId(key string, userid int) (note Note, err error) { return note, db.Where("key = ? and user_id = ? ", key, userid).Take(¬e).Error
}2.2 目前定义数据库表结构的结构体都是继承gorm自带的model结构体,而gorm的model的结构体,没法重新定义json输出的格式,因此,我们重新定义model的结构体并定义json的格式。修改models->core.go文件,添加代码如下// `json:"name"` 这句是定义json输出的格式type Model struct {
ID uint `gorm:"primary_key" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `sql:"index" json:"deleted_at"`
}2.3 修改models->note.go,修改代码如下type Note struct {
Model//这儿的Model是我们上面定义的Model不是gorm.Model
...
}2.4 修改models->user.go,优化用户结构体的json输出的格式,修改代码如下type User struct {
Model //这儿的Model是我们上面定义的Model不是gorm.Model
Name string `gorm:"unique_index" json:"name"`
Email string `gorm:"unique_index" json:"email"`
Pwd string `json:"-"`//“-” 代表不输出,密码不能输出到页面。
Avatar string `json:"avatar"`
Role int `json:"role"`
}
3. 控制器逻辑调整3.1 添加编辑页面的路由/edit/:key,添加控制器逻辑:查询文章并显示文章修改页面。修改controllers->note.go文件,添加如下代码:// @router /edit/:key [get]func (this *NoteController) EditPage() { // 获取页面传过来key
key := this.Ctx.Input.Param(":key") //根据当前文章的key和登陆用户id查询出,文章信息。
note, err := models.QueryNoteByKeyAndUserId(key, int(this.User.ID)) if err != nil { //查询有问题,就提示文章不存在。
this.Abort500(syserror.New("文章不存在!", err))
} //将文章的信息以及key传到页面。
this.Data["note"] = note this.Data["key"] = key //"note_new.html" 是文章新增的页面,之前实现文章新增功能的时候
this.TplName = "note_new.html"}3.2 修改文章保存的控制器逻辑,让页面保存成功后跳转页面到文章详情页面。修改controllers->note.go中的Save方法。// @router /save/:key [post]func (this *NoteController) Save() {
... //原代码:this.JSONOkH("保存成功", H{})
this.JSONOk("保存成功", fmt.Sprintf("/details/%s", key))
}
4. 前台页面调整4.1 在文章详情页面中,我们将当前登陆的用户信息,文章的用户所属id,以及文章的key,保存到js变量中。修改views->details.html页面添加如下代码4.2 在文章详情页面添加修改和删除的操作按钮,我们采用layui提供的fixbar控件,同时我们根据当前登陆的用户和当前文章详情页的文章的所属用户来判断是否显示按钮,修改views->details.html页面添加如下代码
layui.use(['util','jquery'], function(){ var util = layui.util,$= layui.jquery; //用户必须登陆,
//登陆的用户的role必须为0,可以修改文章
//登陆的用户的id,必须等于当前文章详情页的文章所属用户的id
if(user&& user.id >0&&user.role===0&&user.id ===note.userid){
util.fixbar({ bar1: '',//编辑的图标
bar2:'' //删除的图标
,click: function(type){ console.log(type); if(type === 'bar1'){ //跳转到修改文章的页面
window.location.href="/note/edit/"+note.key
} if(type === 'bar2'){ //删除的逻辑,等待实现。
}
}
});
}
});4.3 文章修改的页面views-note_new.html页面,虽然之前实现了修改文章的功能。页面模版没有根据传过来的文章内容来填充文章的内容。我们修改views-note_new.html 修改代码如下...
...
value="{{.note.Title}}"
lay-verify="required" placeholder="请输入标题"
autocomplete="off" class="layui-input">
...
style="background: #fff;">
{{if .note}}{{str2html .note.Content}}{{end}}
...文章修改功能已经实现
文章删除
1. 功能分析
我们需要定义文章删除功能的路由定义:/del/[文章的key] 为post请求。我们要添加根据用户id和文章的key去删除文章的数据库方法。再添加路由对应的控制器逻辑,调用删除文章的数据库方法来删除文章。修改文章详情页面,当点击删除按钮的时候,后台发送post请求,成功提示删除成功,页面跳转到首页。失败就提示删除失败。
2. 数据库逻辑调整2.1 修改models-note.go文件,我们添加根据用户id和文章的key,删除文章的方法,代码如下func DeleteNoteByUserIdAndKey(key string, userid int) error { return db.Delete(&Note{}, "key = ? and user_id = ?", key, userid).Error
}
3. 控制器逻辑调整3.1 修改controllers-note.go文件,添加根据传过来的key和当前登陆的用户id 去调用删除文章的控制器方法,代码如下// @router /del/:key [post]func (this *NoteController) Del() { //获取页面传过来的key值
key := this.Ctx.Input.Param(":key") //调用数据库方法删除文章
if err := models.DeleteNoteByUserIdAndKey(key, int(this.User.ID)); err != nil { //删除失败,提示页面删除失败
this.Abort500(syserror.New("删除失败", err))
} //返回删除成功,并跳转到首页
this.JSONOk("删除成功", "/")
}
4. 前台页面调整4.1 修改views->details.html文件,添加向后台发送删除文章的请求的逻辑,添加代码如下layui.use(['util','jquery'], function(){
...
if(type === 'bar2'){
$.post("/note/del/"+note.key,function (data) { if (data.code === 0) {
layer.msg("删除成功"); if (data.action) {
setTimeout(function () { window.location.href = data.action;
}, 300);
}
} else {
layer.msg("删除失败:" + data.msg);
}
}, "json").error(function () {
layer.msg("网络异常")
});
}
...
});文章删除的功能已经实现。
这儿可以考虑优化一下删除文章的时候提示是否删除
贴个页面效果图
文章显示效果图
作者:qq归位
链接:https://www.jianshu.com/p/129c01509315