package service import ( "github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/db" . "github.com/leanote/leanote/app/lea" "gopkg.in/mgo.v2/bson" // "time" // "sort" "strings" "time" ) // blog /* note, notebook都可设为blog 关键是, 怎么得到blog列表? 还要分页 ??? 不用新建, 直接使用notes表, 添加IsBlog字段. 新建表 blogs {NoteId, UserId, CreatedTime, IsTop(置顶)}, NoteId, UserId 为unique!! // 设置一个note为blog 添加到blogs中 // 设置/取消notebook为blog 创建一个note时, 如果其notebookId已设为blog, 那么添加该note到blog中. 设置一个notebook为blog时, 将其下所有的note添加到blogs里 -> 更新其IsBlog为true 取消一个notebook不为blog时, 删除其下的所有note -> 更新其IsBlog为false */ type BlogService struct { } // 得到某博客具体信息 func (this *BlogService) GetBlog(noteId string) (blog info.BlogItem) { note := noteService.GetBlogNote(noteId) if note.NoteId == "" || !note.IsBlog { return } // 内容 noteContent := noteService.GetNoteContent(note.NoteId.Hex(), note.UserId.Hex()) // 组装成blogItem blog = info.BlogItem{note, noteContent.Content, false, info.User{}} return } // 得到用户共享的notebooks func (this *BlogService) ListBlogNotebooks(userId string) []info.Notebook { notebooks := []info.Notebook{} db.ListByQ(db.Notebooks, bson.M{"UserId": bson.ObjectIdHex(userId), "IsBlog": true}, ¬ebooks) return notebooks } // 博客列表 // userId 表示谁的blog func (this *BlogService) ListBlogs(userId, notebookId string, page, pageSize int, sortField string, isAsc bool) (int, []info.BlogItem) { count, notes := noteService.ListNotes(userId, notebookId, false, page, pageSize, sortField, isAsc, true); if(notes == nil || len(notes) == 0) { return 0, nil } // 得到content, 并且每个都要substring noteIds := make([]bson.ObjectId, len(notes)) for i, note := range notes { noteIds[i] = note.NoteId } // 直接得到noteContents表的abstract // 这里可能是乱序的 noteContents := noteService.ListNoteAbstractsByNoteIds(noteIds) // 返回[info.NoteContent] noteContentsMap := make(map[bson.ObjectId]info.NoteContent, len(noteContents)) for _, noteContent := range noteContents { noteContentsMap[noteContent.NoteId] = noteContent } // 组装成blogItem // 按照notes的顺序 blogs := make([]info.BlogItem, len(noteIds)) for i, note := range notes { hasMore := true var content string if noteContent, ok := noteContentsMap[note.NoteId]; ok { content = noteContent.Abstract } blogs[i] = info.BlogItem{note, content, hasMore, info.User{}} } return count, blogs } func (this *BlogService) SearchBlog(key, userId string, page, pageSize int, sortField string, isAsc bool) (int, []info.BlogItem) { count, notes := noteService.SearchNote(key, userId, page, pageSize, sortField, isAsc, true); if(notes == nil || len(notes) == 0) { return 0, nil } // 得到content, 并且每个都要substring noteIds := make([]bson.ObjectId, len(notes)) for i, note := range notes { noteIds[i] = note.NoteId } // 直接得到noteContents表的abstract // 这里可能是乱序的 noteContents := noteService.ListNoteAbstractsByNoteIds(noteIds) // 返回[info.NoteContent] noteContentsMap := make(map[bson.ObjectId]info.NoteContent, len(noteContents)) for _, noteContent := range noteContents { noteContentsMap[noteContent.NoteId] = noteContent } // 组装成blogItem // 按照notes的顺序 blogs := make([]info.BlogItem, len(noteIds)) for i, note := range notes { hasMore := true var content string if noteContent, ok := noteContentsMap[note.NoteId]; ok { content = noteContent.Abstract } blogs[i] = info.BlogItem{note, content, hasMore, info.User{}} } return count, blogs } //------- // p // 平台 lea+ // 博客列表 func (this *BlogService) ListAllBlogs(tag string, keywords string, isRecommend bool, page, pageSize int, sorterField string, isAsc bool) (info.Page, []info.BlogItem) { pageInfo := info.Page{CurPage: page} notes := []info.Note{} skipNum, sortFieldR := parsePageAndSort(page, pageSize, sorterField, isAsc) // 不是trash的 query := bson.M{"IsTrash": false, "IsBlog": true, "Title": bson.M{"$ne":"欢迎来到leanote!"}} if tag != "" { query["Tags"] = bson.M{"$in": []string{tag}} } // 不是demo的博客 demoUserId := configService.GetGlobalStringConfig("demoUserId") if demoUserId != "" { query["UserId"] = bson.M{"$ne": bson.ObjectIdHex(demoUserId)} } if isRecommend { query["IsRecommend"] = isRecommend } if keywords != "" { query["Title"] = bson.M{"$regex": bson.RegEx{".*?" + keywords + ".*", "i"}} } q := db.Notes.Find(query); // 总记录数 count, _ := q.Count() q.Sort(sortFieldR). Skip(skipNum). Limit(pageSize). All(¬es) if(notes == nil || len(notes) == 0) { return pageInfo, nil } // 得到content, 并且每个都要substring noteIds := make([]bson.ObjectId, len(notes)) userIds := make([]bson.ObjectId, len(notes)) for i, note := range notes { noteIds[i] = note.NoteId userIds[i] = note.UserId } // 可以不要的 // 直接得到noteContents表的abstract // 这里可能是乱序的 /* noteContents := noteService.ListNoteAbstractsByNoteIds(noteIds) // 返回[info.NoteContent] noteContentsMap := make(map[bson.ObjectId]info.NoteContent, len(noteContents)) for _, noteContent := range noteContents { noteContentsMap[noteContent.NoteId] = noteContent } */ // 得到用户信息 userMap := userService.MapUserInfoAndBlogInfosByUserIds(userIds) // 组装成blogItem // 按照notes的顺序 blogs := make([]info.BlogItem, len(noteIds)) for i, note := range notes { hasMore := true var content string /* if noteContent, ok := noteContentsMap[note.NoteId]; ok { content = noteContent.Abstract } */ blogs[i] = info.BlogItem{note, content, hasMore, userMap[note.UserId]} } pageInfo = info.NewPage(page, pageSize, count, nil) return pageInfo, blogs } //------------------------ // 博客设置 func (this *BlogService) fixUserBlog(userBlog *info.UserBlog) { /* if userBlog.Title == "" { userInfo := userService.GetUserInfo(userBlog) userBlog.Title = userInfo.Username + " 's Blog" } */ // Logo路径问题, 有些有http: 有些没有 Log(userBlog.Logo) if userBlog.Logo != "" && !strings.HasPrefix(userBlog.Logo, "http") { userBlog.Logo = strings.Trim(userBlog.Logo, "/") userBlog.Logo = siteUrl + "/" + userBlog.Logo } } func (this *BlogService) GetUserBlog(userId string) info.UserBlog { userBlog := info.UserBlog{} db.Get(db.UserBlogs, userId, &userBlog) this.fixUserBlog(&userBlog) return userBlog } // 修改之 func (this *BlogService) UpdateUserBlog(userBlog info.UserBlog) bool { return db.Upsert(db.UserBlogs, bson.M{"_id": userBlog.UserId}, userBlog) } // 修改之UserBlogBase func (this *BlogService) UpdateUserBlogBase(userId string, userBlog info.UserBlogBase) bool { ok := db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, userBlog) return ok } func (this *BlogService) UpdateUserBlogComment(userId string, userBlog info.UserBlogComment) bool { return db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, userBlog) } func (this *BlogService) UpdateUserBlogStyle(userId string, userBlog info.UserBlogStyle) bool { return db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, userBlog) } //--------------------- // 后台管理 // 推荐博客 func (this *BlogService) SetRecommend(noteId string, isRecommend bool) bool { data := bson.M{"IsRecommend": isRecommend} if isRecommend { data["RecommendTime"] = time.Now() } return db.UpdateByQMap(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId), "IsBlog": true}, data) } //---------------------- // 博客社交, 评论 // 返回所有liked用户, bool是否还有 func (this *BlogService) ListLikedUsers(noteId string, isAll bool) ([]info.User, bool) { // 默认前5 pageSize := 5 skipNum, sortFieldR := parsePageAndSort(1, pageSize, "CreatedTime", false) likes := []info.BlogLike{} query := bson.M{"NoteId": bson.ObjectIdHex(noteId)} q := db.BlogLikes.Find(query); // 总记录数 count, _ := q.Count() if count == 0 { return nil, false } if isAll { q.Sort(sortFieldR).Skip(skipNum).Limit(pageSize).All(&likes) } else { q.Sort(sortFieldR).All(&likes) } // 得到所有userIds userIds := make([]bson.ObjectId, len(likes)) for i, like := range likes { userIds[i] = like.UserId } // 得到用户信息 userMap := userService.MapUserInfoAndBlogInfosByUserIds(userIds) users := make([]info.User, len(likes)); for i, like := range likes { users[i] = userMap[like.UserId] } return users, count > pageSize } func (this *BlogService) IsILikeIt(noteId, userId string) bool { if userId == "" { return false } if db.Has(db.BlogLikes, bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId)}) { return true } return false } // 阅读次数统计+1 func (this *BlogService) IncReadNum(noteId string) bool { note := noteService.GetNoteById(noteId) if note.IsBlog { return db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"ReadNum": 1}}) } return false } // 点赞 // retun ok , isLike func (this *BlogService) LikeBlog(noteId, userId string) (ok bool, isLike bool) { ok = false isLike = false if noteId == "" || userId == "" { return } // 判断是否点过赞, 如果点过那么取消点赞 note := noteService.GetNoteById(noteId) if !note.IsBlog /*|| note.UserId.Hex() == userId */{ return } noteIdO := bson.ObjectIdHex(noteId) userIdO := bson.ObjectIdHex(userId) var n int if !db.Has(db.BlogLikes, bson.M{"NoteId": noteIdO, "UserId": userIdO}) { n = 1 // 添加之 db.Insert(db.BlogLikes, info.BlogLike{LikeId: bson.NewObjectId(), NoteId: noteIdO, UserId: userIdO, CreatedTime: time.Now()}) isLike = true } else { // 已点过, 那么删除之 n = -1 db.Delete(db.BlogLikes, bson.M{"NoteId": noteIdO, "UserId": userIdO}) isLike = false } ok = db.Update(db.Notes, bson.M{"_id": noteIdO}, bson.M{"$inc": bson.M{"LikeNum": n}}) return } // 评论 // 在noteId博客下userId 给toUserId评论content // commentId可为空(针对某条评论评论) func (this *BlogService) Comment(noteId, toCommentId, userId, content string) (bool, info.BlogComment) { var comment info.BlogComment if content == "" { return false, comment } note := noteService.GetNoteById(noteId) if !note.IsBlog { return false, comment } comment = info.BlogComment{CommentId: bson.NewObjectId(), NoteId: bson.ObjectIdHex(noteId), UserId: bson.ObjectIdHex(userId), Content: content, CreatedTime: time.Now(), } var comment2 = info.BlogComment{} if toCommentId != "" { comment2 = info.BlogComment{} db.Get(db.BlogComments, toCommentId, &comment2) if comment2.CommentId != "" { comment.ToCommentId = comment2.CommentId comment.ToUserId = comment2.UserId } } else { // comment.ToUserId = note.UserId } ok := db.Insert(db.BlogComments, comment) if ok { // 评论+1 db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"CommentNum": 1}}) } if userId != note.UserId.Hex() || toCommentId != "" { go func() { this.sendEmail(note, comment2, userId, content); }() } return ok, comment } // 发送email func (this *BlogService) sendEmail(note info.Note, comment info.BlogComment, userId, content string) { emailService.SendCommentEmail(note, comment, userId, content); /* toUserId := note.UserId.Hex() // title := "评论提醒" // 表示回复回复的内容, 那么发送给之前回复的 if comment.CommentId != "" { toUserId = comment.UserId.Hex() } toUserInfo := userService.GetUserInfo(toUserId) sendUserInfo := userService.GetUserInfo(userId) subject := note.Title + " 收到 " + sendUserInfo.Username + " 的评论"; if comment.CommentId != "" { subject = "您在 " + note.Title + " 发表的评论收到 " + sendUserInfo.Username; if userId == note.UserId.Hex() { subject += "(作者)"; } subject += " 的评论"; } body := "{header}评论内容:
" + content + "
"; href := "http://"+ configService.GetBlogDomain() + "/view/" + note.NoteId.Hex() body += "
博客链接: " + href + "{footer}"; emailService.SendEmail(toUserInfo.Email, subject, body) */ } // 作者(或管理员)可以删除所有评论 // 自己可以删除评论 func (this *BlogService) DeleteComment(noteId, commentId, userId string) bool { note := noteService.GetNoteById(noteId) if !note.IsBlog { return false } comment := info.BlogComment{} db.Get(db.BlogComments, commentId, &comment) if comment.CommentId == "" { return false } if userId == adminUserId || note.UserId.Hex() == userId || comment.UserId.Hex() == userId { if db.Delete(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}) { // 评论-1 db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"CommentNum": -1}}) return true } } return false } // 点赞/取消赞 func (this *BlogService) LikeComment(commentId, userId string) (ok bool, isILike bool, num int) { ok = false isILike = false num = 0 comment := info.BlogComment{} db.Get(db.BlogComments, commentId, &comment) var n int if comment.LikeUserIds != nil && len(comment.LikeUserIds) > 0 && InArray(comment.LikeUserIds, userId) { n = -1 // 从点赞名单删除 db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, bson.M{"$pull": bson.M{"LikeUserIds": userId}}) isILike = false } else { n = 1 // 添加之 db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, bson.M{"$push": bson.M{"LikeUserIds": userId}}) isILike = true } if comment.LikeUserIds == nil { num = 0 } else { num = len(comment.LikeUserIds) + n } ok = db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, bson.M{"$set": bson.M{"LikeNum": num}}) return } // 评论列表 // userId主要是显示userId是否点过某评论的赞 // 还要获取用户信息 func (this *BlogService) ListComments(userId, noteId string, page, pageSize int) (info.Page, []info.BlogCommentPublic, map[string]info.User) { pageInfo := info.Page{CurPage: page} comments2 := []info.BlogComment{} skipNum, sortFieldR := parsePageAndSort(page, pageSize, "CreatedTime", false) query := bson.M{"NoteId": bson.ObjectIdHex(noteId)} q := db.BlogComments.Find(query); // 总记录数 count, _ := q.Count() q.Sort(sortFieldR).Skip(skipNum).Limit(pageSize).All(&comments2) if(len(comments2) == 0) { return pageInfo, nil, nil } comments := make([]info.BlogCommentPublic, len(comments2)) // 我是否点过赞呢? for i, comment := range comments2 { comments[i].BlogComment = comment if comment.LikeNum > 0 && comment.LikeUserIds != nil && len(comment.LikeUserIds) > 0 && InArray(comment.LikeUserIds, userId) { comments[i].IsILikeIt = true } } note := noteService.GetNoteById(noteId); // 得到用户信息 userIdsMap := map[bson.ObjectId]bool{note.UserId: true} for _, comment := range comments { userIdsMap[comment.UserId] = true if comment.ToUserId != "" { // 可能为空 userIdsMap[comment.ToUserId] = true } } userIds := make([]bson.ObjectId, len(userIdsMap)) i := 0 for userId, _ := range userIdsMap { userIds[i] = userId i++ } // 得到用户信息 userMap := userService.MapUserInfoByUserIds(userIds) userMap2 := make(map[string]info.User, len(userMap)) for userId, v := range userMap { userMap2[userId.Hex()] = v } pageInfo = info.NewPage(page, pageSize, count, nil) return pageInfo, comments, userMap2 } // 举报 func (this *BlogService) Report(noteId, commentId, reason, userId string) (bool) { note := noteService.GetNoteById(noteId) if !note.IsBlog { return false } report := info.Report{ReportId: bson.NewObjectId(), NoteId: bson.ObjectIdHex(noteId), UserId: bson.ObjectIdHex(userId), Reason: reason, CreatedTime: time.Now(), } if commentId != "" { report.CommentId = bson.ObjectIdHex(commentId) } return db.Insert(db.Reports, report) }