Day02

117 阅读3分钟

Dao

// 连接数据库
var db *gorm.DB

func Init() error {
   var err error
   db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
   return err
}

topic(主题)

//Topic表
type Topic struct {
   Id         int64     `gorm:"column:id"`
   UserId     int64     `gorm:"column:user_id"`
   Title      string    `gorm:"column:title"`
   Content    string    `gorm:"column:content"`
   CreateTime time.Time `gorm:"column:create_time"`
}

type TopicDao struct {
}

var topicDao *TopicDao
var topicOnce sync.Once

func NewTopicDaoInstance() *TopicDao {
   //TopicDao是无状态的,采用单例
   topicOnce.Do(
      func() {
         topicDao = &TopicDao{}
      })
   return topicDao
}

//查询主题
func (*TopicDao) QueryTopicById(id int64) (*Topic, error) {
   var topic Topic
   //查询id为id的条目并放入Topic结构体
   err := db.Where("id = ?", id).Find(&topic).Error
   if err != nil {
      util.Logger.Error("find topic by id err:" + err.Error())
      return nil, err
   }
   return &topic, nil
}

post(发帖)

// post表
type Post struct {
   Id         int64     `gorm:"column:id"`
   ParentId   int64     `gorm:"parent_id"`
   UserId     int64     `gorm:"column:user_id"`
   Content    string    `gorm:"column:content"`
   DiggCount  int32     `gorm:"column:digg_count"`
   CreateTime time.Time `gorm:"column:create_time"`
}

func (Post) TableName() string {
   return "post"
}

type PostDao struct {
}

var postDao *PostDao
var postOnce sync.Once

func NewPostDaoInstance() *PostDao {
   postOnce.Do(
      func() {
         postDao = &PostDao{}
      })
   return postDao
}

func (*PostDao) QueryPostById(id int64) (*Post, error) {
   var post Post
   err := db.Where("id = ?", id).Find(&post).Error
   if err == gorm.ErrRecordNotFound {
      return nil, nil
   }
   if err != nil {
      util.Logger.Error("find post by id err:" + err.Error())
      return nil, err
   }
   return &post, nil
}

//查找给定主题下的所有帖子
func (*PostDao) QueryPostByParentId(parentId int64) ([]*Post, error) {
   var posts []*Post
   err := db.Where("parent_id = ?", parentId).Find(&posts).Error
   if err != nil {
      util.Logger.Error("find posts by parent_id err:" + err.Error())
      return nil, err
   }
   return posts, nil
}

//发帖
func (*PostDao) CreatePost(post *Post) error {
   if err := db.Create(post).Error; err != nil {
      util.Logger.Error("insert post err:" + err.Error())
      return err
   }
   return nil
}

Service

发布帖子服务

//主要函数
func PublishPost(topicId, userId int64, content string) (int64, error) {
   return NewPublishPostFlow(topicId, userId, content).Do()
}

//service模型
type PublishPostFlow struct {
   userId  int64
   content string
   topicId int64

   postId int64
}

//构造函数
func NewPublishPostFlow(topicId, userId int64, content string) *PublishPostFlow {
   return &PublishPostFlow{
      userId:  userId,
      content: content,
      topicId: topicId,
   }
}
//模版,检验并发布
func (f *PublishPostFlow) Do() (int64, error) {
   if err := f.checkParam(); err != nil {
      return 0, err
   }
   if err := f.publish(); err != nil {
      return 0, err
   }
   return f.postId, nil
}
//参数检验
func (f *PublishPostFlow) checkParam() error {
   if f.userId <= 0 {
      return errors.New("userId id must be larger than 0")
   }
   if utf8.RuneCountInString(f.content) >= 500 {
      return errors.New("content length must be less than 500")
   }
   return nil
}
//发布
func (f *PublishPostFlow) publish() error {
   post := &repository.Post{
      ParentId:   f.topicId,
      UserId:     f.userId,
      Content:    f.content,
      CreateTime: time.Now(),
   }
   if err := repository.NewPostDaoInstance().CreatePost(post); err != nil {
      return err
   }
   f.postId = post.Id
   return nil
}

查询一个主题下的所有帖子信息

//query_page_info.go

Controller

//Controller模型
type PageData struct {
   Code int64       `json:"code"`
   Msg  string      `json:"msg"`
   Data interface{} `json:"data"`
}

//查询一个主题和其帖子
func QueryPageInfo(topicIdStr string) *PageData {
   //参数转换
   topicId, err := strconv.ParseInt(topicIdStr, 10, 64)
   if err != nil {
      return &PageData{
         Code: -1,
         Msg:  err.Error(),
      }
   }
   //获取service层结果
   pageInfo, err := service.QueryPageInfo(topicId)
   if err != nil {
      return &PageData{
         Code: -1,
         Msg:  err.Error(),
      }
   }
   return &PageData{
      Code: 0,
      Msg:  "success",
      Data: pageInfo,
   }
}

//发布一个帖子
func PublishPost(uidStr, topicIdStr, content string) *PageData {
   //参数转换
   uid, _ := strconv.ParseInt(uidStr, 10, 64)
   topic, _ := strconv.ParseInt(topicIdStr, 10, 64)
   //获取service层结果
   postId, err := service.PublishPost(topic, uid, content)
   if err != nil {
      return &PageData{
         Code: -1,
         Msg:  err.Error(),
      }
   }
   return &PageData{
      Code: 0,
      Msg:  "success",
      Data: map[string]int64{
         "post_id": postId,
      },
   }

}

路由

func main() {
   if err := Init(); err != nil {
      os.Exit(-1)
   }
   r := gin.Default()

   r.Use(gin.Logger())

   r.GET("/ping", func(c *gin.Context) {
      c.JSON(200, gin.H{
         "message": "pong",
      })
   })

   r.GET("/community/page/get/:id", func(c *gin.Context) {
      topicId := c.Param("id")
      data := handler.QueryPageInfo(topicId)
      c.JSON(200, data)
   })

   //post Content-Type: application/json
   //Q: 如果属性名小写则在数据解析(如json解析,或将结构体作为请求或访问参数)时无法解析
   //如果首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用
   //r.POST("/community/post/do", func(c *gin.Context) {
   // json:= struct {
   //    Uid string `json:"uid"`
   //    TopicId string `json:"topic_id"`
   //    Content string `json:"content"`
   // }{}
   // c.BindJSON(&json)
   // data := handler.PublishPost(json.Uid, json.TopicId, json.Content)
   // c.JSON(200, data)
   //})


   //post Content-Type: application/json

   //r.POST("/community/post/do", func(c *gin.Context) {
   // json:= make(map[string]interface{})
   // c.BindJSON(&json)
   // data := handler.PublishPost(json["uid"].(string), json["topic_id"].(string), json["content"].(string))
   // c.JSON(200, data)
   //})

   //post Content-Type: application/x-www-form-urlencoded

   r.POST("/community/post/do", func(c *gin.Context) {
      uid, _ := c.GetPostForm("uid")
      topicId, _ := c.GetPostForm("topic_id")
      content, _ := c.GetPostForm("content")
      data := handler.PublishPost(uid, topicId, content)
      c.JSON(200, data)
   })
   err := r.Run()
   if err != nil {
      return
   }
}

func Init() error {
   if err := repository.Init(); err != nil {
      return err
   }
   if err := util.InitLogger(); err != nil {
      return err
   }
   return nil
}

接口测试

###发布帖子,json格式
POST http://localhost:8080/community/post/do
Content-Type: application/json

{
  "uid": "1",
  "topic_id": "1",
  "content": "举手报名+4"
}

### 发布帖子,url格式    Q:+变空格  A:将+换为%2B
POST http://localhost:8080/community/post/do
Content-Type: application/x-www-form-urlencoded

uid=1&topic_id=1&content=举手报名%2B2

###查询主题
GET http://localhost:8080/community/page/get/1
Accept: application/json