func getPostsByUserAction(u *User, action string, start, count int) ([]*Post, error) { var ( err error actions []UserAction posts []*Post ) err = db.Where("user_id=? and action=?", u.Id, action).Offset(start).Limit(count).Find(&actions).Error if err != nil { if err == gorm.RecordNotFound { return []*Post{}, nil } return []*Post{}, err } for _, a := range actions { var p = new(Post) p.Id = a.TargetId err = db.Find(p).Error if err != nil { glog.Error("Find Post by Id %s failed: %s\n", p.Id, err.Error()) continue } posts = append(posts, p) } return posts, nil }
/* 创建文章: POST /api/topic/{id} 1 post的body是一个json结构体,post从这个结构体unmarshal得到 2 post的类别信息也在这个结构体中,字段设置如下: taxonomy string name string 或者: tax_id string */ func createNewTopic(c *gin.Context) { if c.Request.Method != "POST" { c.JSON(200, RespResult{ErrCodeInvalidMethod, "invalid method, should be post", nil}) return } user := getCurrent(c) if user == nil { c.JSON(200, RespResult{ErrCodeNeedLogin, "need login", nil}) return } // read request post body defer c.Request.Body.Close() body, err := ioutil.ReadAll(c.Request.Body) if err != nil { c.JSON(200, RespResult{ErrCodeReadRequest, err.Error(), nil}) return } // read post from body post, err := readPostFromRequest(body) if err != nil { return } id := c.Param("id") if post.Id != id { c.JSON(200, RespResult{ErrCodeParam, "post id not equal with path param id", nil}) return } if post.AuthorId != "" { if user.Id != post.AuthorId { c.JSON(200, RespResult{ErrCodeNeeAuthen, "you have no permission", nil}) return } } else { post.AuthorId = user.Id post.AuthorName = user.Name } tax, _ := readTaxFromRequest(body) if err := createPost(post, user); err != nil { c.JSON(200, RespResult{ErrCodeDBQuery, err.Error(), nil}) return } else { // 保存post与taxnomy的关系 err = setPostTaxonmoy(post, tax) if err != nil { glog.Error("set post-taxonomy failed: post id %s\n", post.Id) } } c.JSON(200, RespResult{0, "ok", nil}) }
// 根据用户名查找用户 // func getUserByName(name string) *User { var u User if err := db.Where("name=?", name).First(&u).Error; err != nil { if err != gorm.RecordNotFound { glog.Error("getUserByName failed: name=%s err=%v\n", name, err) } return nil } return &u }
func getUserByEmail(email string) (*User, error) { var u User if err := db.Where("email=?", email).First(&u).Error; err != nil { if err != gorm.RecordNotFound { glog.Error("getUserByEmail failed: email=%s err=%v\n", email, err) } return nil, err } return &u, nil }
// 根据ObjectId来查找用户 func getUserById(oid string) *User { var u User if err := db.Where("id=?", oid).First(&u).Error; err != nil { if err != gorm.RecordNotFound { glog.Error("getUserById failed: oid=%s err=%v\n", oid, err) } return nil } return &u }
func getTopicByPoint(c *gin.Context, point string) { start := getQueryIntDefault(c, "start", 0) count := getQueryIntDefault(c, "count", 20) posts, ret, err := getPostsByPoint(point, start, count) if ret != 0 { glog.Error("getPostsByPoint failed: point=%s ret=%d err=%s\n", point, ret, err.Error()) c.JSON(200, RespResult{ret, "get post by " + point + " failed: " + err.Error(), nil}) return } c.JSON(200, RespResult{0, "ok", posts}) }
func readTaxFromRequest(body []byte) ([]*Taxonomy, error) { var ( taxes []*Taxonomy taxInfo CategoryInfo ) if err := json.Unmarshal(body, &taxInfo); err != nil { glog.Error("unmarshal categroy info failed: %s %s\n", err.Error(), string(body)) taxes = []*Taxonomy{&UnCategory} } else { //glog.Info("category info: %v %s\n", taxInfo, string(body)) taxes = getTaxFromInfos(taxInfo.Infoes) } return taxes, nil }
// 创建回复 func createReply(reply *Post, post *Post, user *User) (err error) { setPostDefaultValue(reply) reply.PostParent = post.Id reply.AuthorId = user.Id reply.AuthorName = user.Name err = db.Create(reply).Error if err == nil { post.ReplyCount += 1 post.LastReplyAt = time.Now() if err2 := db.Save(post).Error; err2 != nil { glog.Error("update post %s reply info failed, reply id: %s\n", post.Id, reply.Id) } } else { return err } return }
// 删除post func deletePost(post *Post, user *User, delReplies bool) (err error) { if user.Id == "administrator" { user.parseUserCap() } if post.AuthorId != user.Id && user.capability["delete_others_posts"] == false { err = errors.New("need perm") return } //db.LogMode(true) if delReplies { err = db.Where("post_parent=? AND sub_type=?", post.Id, "reply").Delete(&Post{}).Error if err != nil { glog.Error("delete post %d replies failed: %v\n", post.Id, err) } } err = db.Delete(post).Error //db.LogMode(false) return }
// 设置post的分类 func setPostTaxonmoy(post *Post, taxes []*Taxonomy) error { var ( tr TermRelation now = time.Now() err error ) for _, tax := range taxes { tr = TermRelation{ ObjectId: post.Id, TermId: tax.Id, CreatedAt: now, } err = db.Create(&tr).Error if err != nil { glog.Error("set post %s to taxonomy %s (%s %s) failed: %s\n", post.Id, tax.Id, tax.Name) } } return err }
// 从[]TaxInfo中查找对应的Taxonomy, 并去重 func getTaxFromInfos(infos []TaxInfo) []*Taxonomy { var ( err error tax *Taxonomy taxesMap = make(map[*Taxonomy]struct{}) taxes = []*Taxonomy{} ) for _, taxInfo := range infos { //首先根据tax_id来查找 if taxInfo.TaxId != "" { if taxInfo.TaxId == "0" { tax = &UnCategory } else { tax = getTaxById(taxInfo.TaxId) } taxesMap[tax] = struct{}{} } else { // 根据taxonomy和name来查找 tax, err = getTaxByName(taxInfo.TaxName, taxInfo.Taxonomy) if err != nil { glog.Error("Not found category by name %s taxonomy %s\n", taxInfo.TaxName, taxInfo.Taxonomy) } else { taxesMap[tax] = struct{}{} } } } // 使用map来过滤可能出现的重复taxonomy问题 for key, _ := range taxesMap { taxes = append(taxes, key) } // 如果没有找到任何分类,设置为未分类 if len(taxes) == 0 { taxes = []*Taxonomy{&UnCategory} } return taxes }