本课的课后作业要求我们使该项目新增支持发布帖子的功能。 首先我们先针对数据层repository中的文件对项目代码进行修改 对于db_init中的initPostIndexMap函数的代码增加
if LastId < post.Id {
LastId = post.Id
}
由此来记录文件里最后的id,以便在发布帖子时以从小到大的顺序更新帖子的id。
接着,对于post文件新增函数AddPost来新增帖子
func (d *PostDao) AddPost(post *Post) error {
lock := sync.Mutex{}
lock.Lock()
posts, ok := postIndexMap[post.ParentId]
if !ok {
return errors.New("parentId not exist")
}
postIndexMap[post.ParentId] = append(posts, post)
err := d.InsertPost2Data("./data/", post)
if err != nil {
return err
}
lock.Unlock()
return nil
}
首先先进行判断所新增帖子的ParenId是否存在,如没问题便将其加入到对应的map并将其写入到文件中。其中需要注意通过加锁来防止对map进行append操作时出现并发安全问题。
关于post文件中的InsertPost2Data函数
func (d *PostDao) InsertPost2Data(path string, post *Post) error {
file, err := os.OpenFile(path+"post", os.O_WRONLY|os.O_APPEND, 0777)
defer file.Close()
if err != nil {
return err
}
writer := bufio.NewWriter(file)
data, err := json.Marshal(*post)
if err != nil {
return err
}
writer.Write(data)
writer.WriteString("\n")
writer.Flush()
return nil
}
首先该函数需要对post文件的尾部插入数据于是Openfile的flag选择读写和增添末尾的模式来打开post文件,并考虑性能决定以带缓冲的方式对文件进行写入,通过变量post进行序列化并将他写入缓冲流再利用Flush()进行刷新使缓冲中的内容写入到文件中。
以上就是为了发布帖子功能而对数据层进行的改动
接下来针对逻辑层service 新建publish-post文件
func (f *PublishPostFlow) Do() (int64, error) {
if err := f.checkParam(); err != nil {
return 0, err
}
if err := f.publishPost(); err != nil {
return 0, err
}
return f.id, nil
}
以上是关于发布帖子service层中的流程编排,其中checkParam函数检查帖子的话题id是否合理,即大于0,publishPost则是通过repository进行发布帖子操作并同时更新LastId
service层实现完成,接下来就是controller层
func PublishPost(parent_idStr, content string) *PageData {
parent_id, err := strconv.ParseInt(parent_idStr, 10, 64)
if err != nil {
return &PageData{
Code: -1,
Msg: err.Error(),
}
}
pageInfo, err := service.PublishPost(parent_id, content)
if err != nil {
return &PageData{
Code: -1,
Msg: err.Error(),
}
}
return &PageData{
Code: 0,
Msg: "success",
Data: pageInfo,
}
这里借助之前定义的PageData结构体作为view对象,通过code和msg打包业务状态信息,data承载业务实体信息
r.POST("/community/page/post", func(c *gin.Context) {
//id, _ := c.GetPostForm("id")
parent_id, _ := c.GetPostForm("parent_id")
content, _ := c.GetPostForm("content")
data := cotroller.PublishPost(parent_id, content)
c.JSON(200, data)
})
最后是server文件中的web引擎设置,通过path变量传递帖子的相关话题id和帖子的内容。过程包括初始化数据索引、初始化引擎配置、构建路由、启动服务。