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

栏目: Go · 发布时间: 5年前

内容简介:留言本实现流程:第一个是视图模板文件,第二个是获取列表,一般查询用需要说明一下的是:

留言本实现流程:

  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. 增加路由

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. 增加控制器

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. 模型

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 注入)请自行进行参数过滤
  1. 修改之前需要查询留言是否是自己的,这时尤其要注意我们 orm 的传参基本上是指针地址传参 如果传入原对象,会直接将数据库读到的数据重新覆盖掉传进来的数据,所以务必使用新变量存储
  1. 使用 orm 原生sql查询,返回的是一个 切片 类型,不管你是查一条还是查多条,这里注意一定 传入的是 切片 ,否则会报错

4. 模板

具体参见github:https://github.com/wujiangweiphp/beegostudy 运行截图:

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

本教程完结,如果觉得对你有帮助,麻烦github上打个


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

构建高可用Linux服务器

构建高可用Linux服务器

余洪春 / 机械工业出版社华章公司 / 2011-11-1 / 79.00元

资深Linux/Unix系统管理专家兼架构师多年一线工作经验结晶,51CTO和ChinaUnix等知名社区联袂推荐。结合实际生产环境,从Linux虚拟化、集群、服务器故障诊断与排除、系统安全性等多角度阐述构建高可用Linux服务器的最佳实践。本书实践性非常强,包含大量企业级的应用案例及相应的解决方案,读者可以直接用这些方案解决在实际工作中遇到的问题。 全书一共10章。第1章以作者的项目实践为......一起来看看 《构建高可用Linux服务器》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具