手摸手教你用beego实现留言本之四(实现留言本)

wujiangwei · · 1716 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

> 留言本实现流程: 1. 用户登录,填写留言 2. 展示留言列表 (分页查询和搜索) 3. 实现留言增删改查 ### 1. 增加留言表 ``` CREATE TABLE `leave_message` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL DEFAULT '0' COMMENT '来自用户表user的id', `content` text NOT NULL COMMENT '留言内容', `status` tinyint(2) NOT NULL DEFAULT '1' COMMENT '是否展示 0 否 1是', `create_at` datetime NOT NULL COMMENT '创建时间', `update_at` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`), KEY `uid` (`uid`) USING BTREE ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='留言表'; ``` ### 2. 增加路由 ```go beego.Router("/msg/", &controllers.MessageController{},"get:Index") beego.Router("/msg/list", &controllers.MessageController{},"get:List") beego.Router("/msg/addmsg", &controllers.MessageController{},"post:AddMsg") beego.Router("/msg/delmsg", &controllers.MessageController{},"post:DelMsg") ``` 第一个是视图模板文件,第二个是获取列表,一般查询用`get`,数据修改用 `post` ### 3. 增加控制器 ```go type MessageController struct { beego.Controller } func (c *MessageController) List() { msg := models.LeaveMessage{} limit,_ := c.GetInt("limit") page,_ := c.GetInt("page") content := c.Input().Get("content") response := ResponseJson{} response.Message = "ok" response.State = 0 if messages, err:= msg.GetList(limit,page,content) ; err != nil { response.Message = err.Error() response.State = 500 } else { response.Data = messages } c.Data["json"] = response c.ServeJSON() //c.TplName = "message.tpl" } func (c *MessageController) Index() { c.TplName = "message.tpl" } func (c *MessageController)AddMsg() { username := c.GetSession("Username") content := c.Input().Get("content") id, _ := c.GetInt("id",0) response := ResponseJson{} response.Message = "ok" response.State = 0 if content == "" { response.Message = "留言内容不能为空" response.State = 500 c.Data["json"] = response c.ServeJSON() return } if username == "" || username == nil { response.Message = "当前用户尚未登录,请先登录" response.State = 501 c.Data["json"] = response c.ServeJSON() return } msg := models.LeaveMessage{} msg.Content = content msg.Id = id if id,err := msg.SaveMessage(username.(string)); err != nil { response.Message = "保存失败,请稍后再试" response.State = 503 } else { response.Data = id } c.Data["json"] = response c.ServeJSON() return } func (c *MessageController)DelMsg() { username := c.GetSession("Username") id, _ := c.GetInt("id",0); response := ResponseJson{} response.Message = "ok" response.State = 0 msg := models.LeaveMessage{} msg.Id = id if username == "" || username == nil { response.Message = "当前用户尚未登录,请先登录" response.State = 501 c.Data["json"] = response c.ServeJSON() return } if err := msg.DelMsg(username.(string)); err != nil { response.Message = "删除失败,请稍后再试" response.State = 503 } c.Data["json"] = response c.ServeJSON() return } ``` > 需要说明一下的是: > 1. `c.Input().Get('content')` 返回的是字符串,如果需要接收`id`之类的整型可以使用 `c.GetInt('id',0)` 这个函数返回值有两个,参数也是两个 可以使用 `_` 占位符跳过第二个`err`的接收 > 2. 如果我们调用 `c.ServeJSON()` 想提前返回,一定要注意后面紧跟 `return`, 否则后面的代码可能会接着执行 ### 3. 模型 ```go package models import ( "errors" "github.com/astaxie/beego/orm" "log" "time" ) type LeaveMessage struct { Id int Uid int Content string Status int CreateAt time.Time `orm:"type(datetime)"` UpdateAt time.Time `orm:"type(datetime)"` } type MsgData struct { Id int Content string Name string CreateAt time.Time } type MessageList struct { Count int List []MsgData } func init() { orm.RegisterModel(new(LeaveMessage)) } /** 添加留言 */ func (msg *LeaveMessage) SaveMessage(username string) (int, error) { o := orm.NewOrm() user := User{Name: username} if err := user.GetUserId(); err != nil { return 0, err } msg.Uid = user.Id msg.Status = 1 msg.UpdateAt = time.Now() if msg.Id > 0 { //需要判断是否是自己的留言 注意 这里读到的可能会覆盖自己的 结构 重新开启一个 msgr := LeaveMessage{Id:msg.Id,Uid:msg.Uid} if err := o.Read(&msgr, "uid", "id"); err != nil { log.Printf("update user %v error,error info is %v ,is not yourself \n", msg, err) return 0, errors.New("不能修改别人的留言") } msg.CreateAt = time.Now() if num, err := o.Update(msg, "content","update_at"); num == 0 || err != nil { log.Printf("update user %v error,error info is %v \n", msg, err) return 0, errors.New("保存失败,请稍后再试") } } else { if id, err := o.Insert(msg); err != nil || id <= 0 { log.Printf("insert user %v error,error info is %v \n", msg, err) return 0, errors.New("保存失败,请稍后再试") } } return msg.Id, nil } /** 搜索留言 分页 1. 联表查询记录列表 2. 筛选符合条件的结果 3. 加入分页 */ func (msg LeaveMessage) GetList(limit, page int, content string) (MessageList, error) { qb, _ := orm.NewQueryBuilder("mysql") qb2, _ := orm.NewQueryBuilder("mysql") if limit == 0 { limit = 20 } offset := 0 if page > 0 { offset = (page - 1) * limit } qb.Select("count(*) "). From("leave_message"). LeftJoin("user").On("leave_message.uid = user.id") if content != "" { qb.Where("content like '%" + content + "%' ") } qb2.Select("user.name,leave_message.id,leave_message.content,leave_message.create_at"). From("leave_message"). LeftJoin("user").On("leave_message.uid = user.id") if content != "" { qb2.Where("content like '%" + content + "%' ") } qb2.OrderBy("leave_message.id desc").Limit(limit).Offset(offset) sqlCount := qb.String() sqlRows := qb2.String() o := orm.NewOrm() var messageList MessageList var count []int var msgDatas []MsgData if num, err := o.Raw(sqlCount).QueryRows(&count); err != nil || num == 0 { return MessageList{}, errors.New("查询失败,请稍后再试") } messageList.Count = count[0] if num, err := o.Raw(sqlRows).QueryRows(&msgDatas); err != nil || num == 0 { return MessageList{}, errors.New("查询失败,请稍后再试") } messageList.List = msgDatas return messageList, nil } /** 删除留言 */ func (msg *LeaveMessage) DelMsg(username string) error { o := orm.NewOrm() user := User{Name: username} if err := user.GetUserId(); err != nil { return err } msg.Uid = user.Id msg.Status = 1 msg.CreateAt = time.Now() msg.UpdateAt = time.Now() if msg.Id > 0 { //需要判断是否是自己的留言 if err := o.Read(msg, "uid", "id"); err != nil { log.Printf("delete user %v error,error info is %v ,is not yourself \n", msg, err) return errors.New("不能删除别人的留言") } if num,err := o.Delete(msg,"id");err != nil || num == 0{ log.Printf("delete user %v error,error info is %v ,is not yourself \n", msg, err) return errors.New("删除失败,请稍后再试") } return nil } else { return errors.New("请选择你要删除的留言") } } ``` > 需要说明一下的是: > 1. list需要联表查询,orm的高级查询比较复杂,可以使用构造查询 具体文档可参见: https://www.kancloud.cn/hello123/beego/126107 其中有一个bug,不知道是什么原因, `where`中使用 `content like '%?%' ` 的 `?`参数不能被 识别,导致无法进行参数替换,本例直接拼装了条件(注意这里会有sql注入)请自行进行参数过滤 > 2. 修改之前需要查询留言是否是自己的,这时尤其要注意我们`orm` 的传参基本上是指针地址传参 如果传入原对象,会直接将数据库读到的数据重新覆盖掉传进来的数据,所以务必使用新变量存储 > 3. 使用`orm`原生sql查询,返回的是一个`切片`类型,不管你是查一条还是查多条,这里注意一定 传入的是`切片`,否则会报错 ### 4. 模板 > 具体参见github:https://github.com/wujiangweiphp/beegostudy 运行截图: <img src="https://static.studygolang.com/190116/68b59a94b2f152cce1bf2a011d5cb931.png" width="80%" align=center/> > 本教程完结,如果觉得对你有帮助,麻烦github上打个 `※`。

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1716 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
1 回复  |  直到 2020-10-10 15:20:52
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传