This commit is contained in:
life committed 2014-05-07 13:06:24 +08:00
1 parent fac05a7b6c
commit 476ade10e7
1085 files changed
+259628

No files matched your search

+113
View File
@@ -0,0 +1,113 @@
package service
import (
"labix.org/v2/mgo/bson"
// "github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"fmt"
)
// 登录与权限
type AuthService struct {
}
// pwd已md5了
func (this *AuthService) Login(emailOrUsername, pwd string) info.User {
return userService.LoginGetUserInfo(emailOrUsername, Md5(pwd))
}
// 注册
/*
注册 leanote@leanote.com userId = "5368c1aa99c37b029d000001"
添加 在博客上添加一篇欢迎note, note1 5368c1b919807a6f95000000
将nk1(只读), nk2(可写) 分享给该用户
将note1 复制到用户的生活nk上
*/
// 1. 添加用户
// 2. 将leanote共享给我
// [ok]
func (this *AuthService) Register(email, pwd string) (bool, string) {
// 用户是否已存在
if userService.IsExistsUser(email) {
return false, email + " 已被注册"
}
user := info.User{UserId: bson.NewObjectId(), Email: email, Username: email, Pwd: Md5(pwd)}
return this.register(user)
}
func (this *AuthService) register(user info.User) (bool, string) {
if userService.AddUser(user) {
// 添加笔记本, 生活, 学习, 工作
notebook := info.Notebook{
Seq: -1,
UserId: user.UserId}
title2Id := map[string]bson.ObjectId{"life": bson.NewObjectId(), "study": bson.NewObjectId(), "work": bson.NewObjectId()}
for title, objectId := range title2Id {
notebook.Title = title
notebook.NotebookId = objectId
notebook.UserId = user.UserId
notebookService.AddNotebook(notebook);
}
email := user.Email
// 添加leanote -> 该用户的共享
leanoteUserId := "5368c1aa99c37b029d000001";
nk1 := "5368c1aa99c37b029d000002" // leanote
welcomeNoteId := "5368c1b919807a6f95000000" // 欢迎来到leanote
shareService.AddShareNotebook(nk1, 0, leanoteUserId, email);
shareService.AddShareNote(welcomeNoteId, 0, leanoteUserId, email);
// 将welcome copy给我
note := noteService.CopySharedNote(welcomeNoteId, title2Id["life"].Hex(), leanoteUserId, user.UserId.Hex());
// 公开为博客
noteUpdate := bson.M{"IsBlog": true}
noteService.UpdateNote(user.UserId.Hex(), user.UserId.Hex(), note.NoteId.Hex(), noteUpdate)
//---------------
// 添加一条userBlog
blogService.UpdateUserBlog(info.UserBlog{UserId: user.UserId,
Title: user.Username + " 's Blog",
SubTitle: "love leanote!",
AboutMe: "Hello, I am (^_^)",
})
}
return true, ""
}
//--------------
// 第三方注册
// 第三方得到用户名, 可能需要多次判断
func (this *AuthService) getUsername(thirdType, thirdUsername string) (username string) {
username = thirdType + "-" + thirdUsername
i := 1
for ;; {
if !userService.IsExistsUserByUsername(username) {
return
}
username = fmt.Sprintf("%v%v", username, i)
}
}
func (this *AuthService) ThirdRegister(thirdType, thirdUserId, thirdUsername string) (exists bool, userInfo info.User) {
userInfo = userService.GetUserInfoByThirdUserId(thirdUserId)
if userInfo.UserId != "" {
exists = true
return
}
username := this.getUsername(thirdType, thirdUsername)
userInfo = info.User{UserId: bson.NewObjectId(),
Username: username,
ThirdUserId: thirdUserId,
ThirdUsername: thirdUsername,
}
_, _ = this.register(userInfo)
return
}
+155
View File
@@ -0,0 +1,155 @@
package service
import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db"
// . "github.com/leanote/leanote/app/lea"
"labix.org/v2/mgo/bson"
// "time"
// "sort"
)
// 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}
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}, &notebooks)
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}
}
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}
}
return count, blogs
}
//------------------------
// 博客设置
func (this *BlogService) GetUserBlog(userId string) info.UserBlog {
userBlog := info.UserBlog{}
db.Get(db.UserBlogs, userId, &userBlog)
if userBlog.Title == "" {
userInfo := userService.GetUserInfo(userId)
userBlog.Title = userInfo.Username + " 的博客"
}
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 {
return db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, userBlog)
}
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)
}
+64
View File
@@ -0,0 +1,64 @@
package service
import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db"
// . "github.com/leanote/leanote/app/lea"
"labix.org/v2/mgo/bson"
// "time"
)
// 历史记录
type NoteContentHistoryService struct {
}
// 每个历史记录最大值
var maxSize = 10
// 新建一个note, 不需要添加历史记录
// 添加历史
func (this *NoteContentHistoryService) AddHistory(noteId, userId string, eachHistory info.EachHistory) {
// 检查是否是空
if eachHistory.Content == "" {
return
}
// 先查是否存在历史记录, 没有则添加之
history := info.NoteContentHistory{}
db.GetByIdAndUserId(db.NoteContentHistories, noteId, userId, &history)
if history.NoteId == "" {
this.newHistory(noteId, userId, eachHistory)
} else {
// 判断是否超出 maxSize, 如果超出则pop最后一个, 再push之, 不用那么麻烦, 直接update吧, 虽然影响性能
// TODO
l := len(history.Histories)
if l >= maxSize {
history.Histories = history.Histories[l-maxSize:]
}
newHistory := []info.EachHistory{eachHistory}
newHistory = append(newHistory, history.Histories...) // 在开头加了, 最近的在最前
history.Histories = newHistory
// 更新之
db.UpdateByIdAndUserId(db.NoteContentHistories, noteId, userId, history)
}
return
}
// 新建历史
func (this *NoteContentHistoryService) newHistory(noteId, userId string, eachHistory info.EachHistory) {
history := info.NoteContentHistory{NoteId: bson.ObjectIdHex(noteId),
UserId: bson.ObjectIdHex(userId),
Histories: []info.EachHistory{eachHistory},
}
// 保存之
db.Insert(db.NoteContentHistories, history)
}
// 列表展示
func (this *NoteContentHistoryService) ListHistories(noteId, userId string) []info.EachHistory {
histories := info.NoteContentHistory{}
db.GetByIdAndUserId(db.NoteContentHistories, noteId, userId, &histories)
return histories.Histories
}
+449
View File
@@ -0,0 +1,449 @@
package service
import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db"
. "github.com/leanote/leanote/app/lea"
"labix.org/v2/mgo/bson"
"time"
)
type NoteService struct {
}
// 通过id, userId得到note
func (this *NoteService) GetNote(noteId, userId string) (note info.Note) {
note = info.Note{}
db.GetByIdAndUserId(db.Notes, noteId, userId, &note)
return
}
// 得到blog, blogService用
// 不要传userId, 因为是公开的
func (this *NoteService) GetBlogNote(noteId string) (note info.Note) {
note = info.Note{}
db.GetByQ(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId), "IsBlog": true, "IsTrash": false}, &note)
return
}
// 通过id, userId得到noteContent
func (this *NoteService) GetNoteContent(noteContentId, userId string) (noteContent info.NoteContent) {
noteContent = info.NoteContent{}
db.GetByIdAndUserId(db.NoteContents, noteContentId, userId, &noteContent)
return
}
// 列出note, 排序规则, 还有分页
// CreatedTime, UpdatedTime, title 来排序
func (this *NoteService) ListNotes(userId, notebookId string,
isTrash bool, pageNumber, pageSize int, sortField string, isAsc bool, isBlog bool) (count int, notes []info.Note) {
notes = []info.Note{}
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
// 不是trash的
query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsTrash": isTrash}
if isBlog {
query["IsBlog"] = true
}
if notebookId != "" {
query["NotebookId"] = bson.ObjectIdHex(notebookId)
}
q := db.Notes.Find(query);
// 总记录数
count, _ = q.Count()
q.Sort(sortFieldR).
Skip(skipNum).
Limit(pageSize).
All(&notes)
return
}
// 通过noteIds来查询
// ShareService调用
func (this *NoteService) ListNotesByNoteIdsWithPageSort(noteIds []bson.ObjectId, userId string,
pageNumber, pageSize int, sortField string, isAsc bool, isBlog bool) (notes []info.Note) {
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
notes = []info.Note{}
// 不是trash
db.Notes.
Find(bson.M{"_id": bson.M{"$in": noteIds}, "IsTrash": false}).
Sort(sortFieldR).
Skip(skipNum).
Limit(pageSize).
All(&notes)
return
}
// shareService调用
func (this *NoteService) ListNotesByNoteIds(noteIds []bson.ObjectId) (notes []info.Note) {
notes = []info.Note{}
db.Notes.
Find(bson.M{"_id": bson.M{"$in": noteIds}}).
All(&notes)
return
}
// blog需要
func (this *NoteService) ListNoteContentsByNoteIds(noteIds []bson.ObjectId) (notes []info.NoteContent) {
notes = []info.NoteContent{}
db.NoteContents.
Find(bson.M{"_id": bson.M{"$in": noteIds}}).
All(&notes)
return
}
// 只得到abstract, 不需要content
func (this *NoteService) ListNoteAbstractsByNoteIds(noteIds []bson.ObjectId) (notes []info.NoteContent) {
notes = []info.NoteContent{}
db.ListByQWithFields(db.NoteContents, bson.M{"_id": bson.M{"$in": noteIds}}, []string{"_id", "Abstract"}, &notes)
return
}
// 添加笔记
// 首先要判断Notebook是否是Blog, 是的话设为blog
// [ok]
func (this *NoteService) AddNote(note info.Note) info.Note {
if(note.NoteId.Hex() == "") {
noteId := bson.NewObjectId();
note.NoteId = noteId;
}
note.CreatedTime = time.Now()
note.UpdatedTime = note.CreatedTime
note.IsTrash = false
note.UpdatedUserId = note.UserId
// 设为blog
note.IsBlog = notebookService.IsBlog(note.NotebookId.Hex())
db.Insert(db.Notes, note)
// tag1
tagService.AddTags(note.UserId.Hex(), note.Tags)
return note
}
// 添加共享d笔记
func (this *NoteService) AddSharedNote(note info.Note, myUserId bson.ObjectId) info.Note {
// 判断我是否有权限添加
if shareService.HasUpdateNotebookPerm(note.UserId.Hex(), myUserId.Hex(), note.NotebookId.Hex()) {
note.CreatedUserId = myUserId // 是我给共享我的人创建的
return this.AddNote(note)
}
return info.Note{}
}
// 添加笔记本内容
// [ok]
func (this *NoteService) AddNoteContent(noteContent info.NoteContent) info.NoteContent {
noteContent.CreatedTime = time.Now()
noteContent.UpdatedTime = noteContent.CreatedTime
noteContent.UpdatedUserId = noteContent.UserId
db.Insert(db.NoteContents, noteContent)
return noteContent;
}
// 添加笔记和内容
// 这里使用 info.NoteAndContent 接收?
func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note {
if(note.NoteId.Hex() == "") {
noteId := bson.NewObjectId()
note.NoteId = noteId
}
noteContent.NoteId = note.NoteId
if note.UserId != myUserId {
note = this.AddSharedNote(note, myUserId)
} else {
note = this.AddNote(note)
}
if note.NoteId != "" {
this.AddNoteContent(noteContent)
}
return note
}
// 修改笔记
// [ok] TODO perm还没测
func (this *NoteService) UpdateNote(userId, updatedUserId, noteId string, needUpdate bson.M) bool {
// updatedUserId 要修改userId的note, 此时需要判断是否有修改权限
if userId != updatedUserId {
if !shareService.HasUpdatePerm(userId, updatedUserId, noteId) {
Log("NO AUTH")
return false
} else {
Log("HAS AUTH -----------")
}
}
needUpdate["UpdatedUserId"] = bson.ObjectIdHex(updatedUserId);
needUpdate["UpdatedTime"] = time.Now();
// 添加tag2
if tags, ok := needUpdate["Tags"]; ok {
tagService.AddTagsI(userId, tags)
}
// 是否修改了isBlog
// 也要修改noteContents的IsBlog
if isBlog, ok := needUpdate["IsBlog"]; ok {
db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId, bson.M{"IsBlog": isBlog})
}
return db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, needUpdate)
}
// 这里要判断权限, 如果userId != updatedUserId, 那么需要判断权限
// [ok] TODO perm还没测 [del]
func (this *NoteService) UpdateNoteTitle(userId, updatedUserId, noteId, title string) bool {
// updatedUserId 要修改userId的note, 此时需要判断是否有修改权限
if userId != updatedUserId {
if !shareService.HasUpdatePerm(userId, updatedUserId, noteId) {
println("NO AUTH")
return false
}
}
return db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId), "Title": title, "UpdatedTime": time.Now()})
}
// 修改笔记本内容
// [ok] TODO perm未测
func (this *NoteService) UpdateNoteContent(userId, updatedUserId, noteId, content, abstract string) bool {
// updatedUserId 要修改userId的note, 此时需要判断是否有修改权限
if userId != updatedUserId {
if !shareService.HasUpdatePerm(userId, updatedUserId, noteId) {
Log("NO AUTH")
return false
}
}
if db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId,
bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId),
"Content": content,
"Abstract": abstract,
"UpdatedTime": time.Now()}) {
// 这里, 添加历史记录
noteContentHistoryService.AddHistory(noteId, userId, info.EachHistory{UpdatedUserId: bson.ObjectIdHex(updatedUserId),
Content: content,
UpdatedTime: time.Now(),
})
return true
}
return false
}
// 更新tags
// [ok] [del]
func (this *NoteService) UpdateTags(noteId string, userId string, tags []string) bool {
return db.UpdateByIdAndUserIdField(db.Notes, noteId, userId, "Tags", tags)
}
// 移动note
// trash, 正常的都可以用
// 1. 要检查下notebookId是否是自己的
// 2. 要判断之前是否是blog, 如果不是, 那么notebook是否是blog?
func (this *NoteService) MoveNote(noteId, notebookId, userId string) info.Note {
if notebookService.IsMyNotebook(notebookId, userId) {
re := db.UpdateByIdAndUserId(db.Notes, noteId, userId,
bson.M{"$set": bson.M{"IsTrash": false,
"NotebookId": bson.ObjectIdHex(notebookId)}})
if re {
// 更新blog状态
this.updateToNotebookBlog(noteId, notebookId, userId)
}
return this.GetNote(noteId, userId);
}
return info.Note{}
}
// 如果自己的blog状态是true, 不用改变,
// 否则, 如果notebookId的blog是true, 则改为true之
// 返回blog状态
func (this *NoteService) updateToNotebookBlog(noteId, notebookId, userId string) bool {
if this.IsBlog(noteId) {
return true
}
if notebookService.IsBlog(notebookId) {
db.UpdateByIdAndUserId(db.Notes, noteId, userId,
bson.M{"$set": bson.M{"IsBlog": true}})
return true
}
return false
}
// 判断是否是blog
func (this *NoteService) IsBlog(noteId string) bool {
note := info.Note{}
db.GetByQWithFields(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, []string{"IsBlog"}, &note);
return note.IsBlog
}
// 复制note
// 正常的可以用
// 先查, 再新建
// 要检查下notebookId是否是自己的
func (this *NoteService) CopyNote(noteId, notebookId, userId string) info.Note {
if notebookService.IsMyNotebook(notebookId, userId) {
note := this.GetNote(noteId, userId)
noteContent := this.GetNoteContent(noteId, userId)
// 重新生成noteId
note.NoteId = bson.NewObjectId();
note.NotebookId = bson.ObjectIdHex(notebookId)
noteContent.NoteId = note.NoteId
this.AddNoteAndContent(note, noteContent, note.UserId);
// 更新blog状态
isBlog := this.updateToNotebookBlog(note.NoteId.Hex(), notebookId, userId)
note.IsBlog = isBlog
return note
}
return info.Note{}
}
// 复制别人的共享笔记给我
// TODO 判断是否共享了给我
func (this *NoteService) CopySharedNote(noteId, notebookId, fromUserId, myUserId string) info.Note {
if notebookService.IsMyNotebook(notebookId, myUserId) {
note := this.GetNote(noteId, fromUserId)
if note.NoteId == "" {
return info.Note{}
}
noteContent := this.GetNoteContent(noteId, fromUserId)
// 重新生成noteId
note.NoteId = bson.NewObjectId();
note.NotebookId = bson.ObjectIdHex(notebookId)
note.UserId = bson.ObjectIdHex(myUserId)
note.IsTop = false
note.IsBlog = false // 别人的可能是blog
// content
noteContent.NoteId = note.NoteId
noteContent.UserId = note.UserId
// 添加之
note = this.AddNoteAndContent(note, noteContent, note.UserId);
// 更新blog状态
isBlog := this.updateToNotebookBlog(note.NoteId.Hex(), notebookId, myUserId)
note.IsBlog = isBlog
return note
}
return info.Note{}
}
// 通过noteId得到notebookId
// shareService call
// [ok]
func (this *NoteService) GetNotebookId(noteId string) bson.ObjectId {
note := &info.Note{}
db.Get(db.Notes, noteId, note)
return note.NotebookId
}
//------------------
// 搜索Note
func (this *NoteService) SearchNote(key, userId string, pageNumber, pageSize int, sortField string, isAsc, isBlog bool) (count int, notes []info.Note) {
notes = []info.Note{}
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
// 不是trash的
query := bson.M{"UserId": bson.ObjectIdHex(userId),
"IsTrash": false,
"Title": bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}},
}
if isBlog {
query["IsBlog"] = true
}
q := db.Notes.Find(query);
// 总记录数
count, _ = q.Count()
q.Sort(sortFieldR).
Skip(skipNum).
Limit(pageSize).
All(&notes)
// 如果 < pageSize 那么搜索content, 且id不在这些id之间的
if len(notes) < pageSize {
notes = this.searchNoteFromContent(notes, userId, key, pageSize, sortFieldR, isBlog)
}
return
}
// 搜索noteContents, 补集pageSize个
func (this *NoteService) searchNoteFromContent(notes []info.Note, userId, key string, pageSize int, sortField string, isBlog bool) []info.Note {
var remain = pageSize - len(notes)
noteIds := make([]bson.ObjectId, len(notes))
for i, note := range notes {
noteIds[i] = note.NoteId
}
LogJ(noteIds)
noteContents := []info.NoteContent{}
query := bson.M{"_id": bson.M{"$nin": noteIds}, "UserId": bson.ObjectIdHex(userId), "Content": bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}}}
if isBlog {
query["IsBlog"] = true
}
db.NoteContents.
Find(query).
Sort(sortField).
Limit(remain).
Select(bson.M{"_id": true}).
All(&noteContents)
var lenContent = len(noteContents)
if(lenContent == 0) {
return notes
}
// 收集ids
noteIds2 := make([]bson.ObjectId, lenContent)
for i, content := range noteContents {
noteIds2[i] = content.NoteId
}
// Log(" content search ")
// Log(lenContent)
// 得到notes
notes2 := this.ListNotesByNoteIds(noteIds2)
// 合并之
notes = append(notes, notes2...)
return notes
}
//----------------
// tag搜索
func (this *NoteService) SearchNoteByTags(tags []string, userId string, pageNumber, pageSize int, sortField string, isAsc bool) (count int, notes []info.Note) {
notes = []info.Note{}
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
// 不是trash的
query := bson.M{"UserId": bson.ObjectIdHex(userId),
"IsTrash": false,
"Tags": bson.M{"$all": tags}}
q := db.Notes.Find(query);
// 总记录数
count, _ = q.Count()
Log(count)
q.Sort(sortFieldR).
Skip(skipNum).
Limit(pageSize).
All(&notes)
return
}
+211
View File
@@ -0,0 +1,211 @@
package service
import (
// "fmt"
"labix.org/v2/mgo/bson"
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
// . "github.com/leanote/leanote/app/lea"
"sort"
"time"
)
// 笔记本
type NotebookService struct {
}
// 排序
func sortSubNotebooks(eachNotebooks info.SubNotebooks) info.SubNotebooks {
// 遍历子, 则子往上进行排序
for _, eachNotebook := range eachNotebooks {
if eachNotebook.Subs != nil && len(eachNotebook.Subs) > 0 {
eachNotebook.Subs = sortSubNotebooks(eachNotebook.Subs)
}
}
// 子排完了, 本层排
sort.Sort(&eachNotebooks)
return eachNotebooks
}
// 整理(成有关系)并排序
// GetNotebooks()调用
// ShareService调用
func ParseAndSortNotebooks(userNotebooks []info.Notebook, noParentDelete, needSort bool) info.SubNotebooks {
// 整理成info.Notebooks
// 第一遍, 建map
// notebookId => info.Notebooks
userNotebooksMap := make(map[bson.ObjectId]*info.Notebooks, len(userNotebooks))
for _, each := range userNotebooks {
newNotebooks := info.Notebooks{Subs: info.SubNotebooks{}}
newNotebooks.NotebookId = each.NotebookId
newNotebooks.Title = each.Title
newNotebooks.Seq = each.Seq
newNotebooks.UserId = each.UserId
newNotebooks.ParentNotebookId = each.ParentNotebookId
newNotebooks.NumberNotes = each.NumberNotes
newNotebooks.IsTrash = each.IsTrash
newNotebooks.IsBlog = each.IsBlog
userNotebooksMap[each.NotebookId] = &newNotebooks
}
// 第二遍, 追加到父下
// nilObjectId := bson.ObjectIdHex("")
for id, each := range userNotebooksMap {
// 如果有父, 那么追加到父下, 并剪掉当前, 那么最后就只有根的元素
if each.ParentNotebookId.Hex() != "" {
if userNotebooksMap[each.ParentNotebookId] != nil {
userNotebooksMap[each.ParentNotebookId].Subs = append(userNotebooksMap[each.ParentNotebookId].Subs, *each)
// 并剪掉
delete(userNotebooksMap, id)
} else if noParentDelete {
// 没有父, 且设置了要删除
delete(userNotebooksMap, id)
}
}
}
// 第三遍, 得到所有根
final := make(info.SubNotebooks, len(userNotebooksMap))
i := 0
for _, each := range userNotebooksMap {
final[i] = *each
i++
}
// 最后排序
if needSort {
return sortSubNotebooks(final)
}
return final
}
// 得到某notebook
func (this *NotebookService) GetNotebook(notebookId, userId string) info.Notebook {
notebook := info.Notebook{}
db.GetByIdAndUserId(db.Notebooks, notebookId, userId, &notebook)
return notebook
}
// 得到用户下所有的notebook
// 排序好之后返回
// [ok]
func (this *NotebookService) GetNotebooks(userId string) info.SubNotebooks {
userNotebooks := []info.Notebook{}
db.Notebooks.Find(bson.M{"UserId": bson.ObjectIdHex(userId)}).All(&userNotebooks)
if len(userNotebooks) == 0 {
return nil
}
return ParseAndSortNotebooks(userNotebooks, true, true)
}
// share调用, 不需要删除没有父的notebook
// 不需要排序, 因为会重新排序
// 通过notebookIds得到notebooks, 并转成层次有序
func (this *NotebookService) GetNotebooksByNotebookIds(notebookIds []bson.ObjectId) info.SubNotebooks {
userNotebooks := []info.Notebook{}
db.Notebooks.Find(bson.M{"_id": bson.M{"$in": notebookIds}}).All(&userNotebooks)
if len(userNotebooks) == 0 {
return nil
}
return ParseAndSortNotebooks(userNotebooks, false, false)
}
// 添加
// [ok]
func (this *NotebookService) AddNotebook(notebook info.Notebook) bool {
err := db.Notebooks.Insert(notebook)
if err != nil {
panic(err)
} else {
}
return true
}
// 判断是否是blog
func (this *NotebookService) IsBlog(notebookId string) bool {
notebook := info.Notebook{}
db.GetByQWithFields(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId)}, []string{"IsBlog"}, &notebook);
return notebook.IsBlog
}
// 判断是否是我的notebook
func (this *NotebookService) IsMyNotebook(notebookId, userId string) bool {
return db.Has(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId)})
}
// 更新笔记本信息
// 太广, 不用
/*
func (this *NotebookService) UpdateNotebook(notebook info.Notebook) bool {
return db.UpdateByIdAndUserId2(db.Notebooks, notebook.NotebookId, notebook.UserId, notebook)
}
*/
// 更新笔记本标题
// [ok]
func (this *NotebookService) UpdateNotebookTitle(notebookId, userId, title string) bool {
return db.UpdateByIdAndUserIdField(db.Notebooks, notebookId, userId, "Title", title)
}
// 更新notebook
func (this *NotebookService) UpdateNotebook(userId, notebookId string, needUpdate bson.M) bool {
needUpdate["UpdatedTime"] = time.Now();
// 如果有IsBlog之类的, 需要特殊处理
if isBlog, ok := needUpdate["IsBlog"]; ok {
// 设为blog/取消
if is, ok2 := isBlog.(bool); ok2 {
q := bson.M{"UserId": bson.ObjectIdHex(userId),
"NotebookId": bson.ObjectIdHex(notebookId)}
db.UpdateByQMap(db.Notes, q, bson.M{"IsBlog": is})
// noteContents也更新, 这个就麻烦了, noteContents表没有NotebookId
// 先查该notebook下所有notes, 得到id
notes := []info.Note{}
db.ListByQWithFields(db.Notes, q, []string{"_id"}, &notes)
if len(notes) > 0 {
noteIds := make([]bson.ObjectId, len(notes))
for i, each := range notes {
noteIds[i] = each.NoteId
}
db.UpdateByQMap(db.NoteContents, bson.M{"_id": bson.M{"$in": noteIds}}, bson.M{"IsBlog": isBlog})
}
}
}
return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, needUpdate)
}
// 先查看该notebookId下是否有notes, 没有则删除
func (this *NotebookService) DeleteNotebook(userId, notebookId string) (bool, string) {
if db.Count(db.Notes, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
"UserId": bson.ObjectIdHex(userId),
"IsTrash": false}) == 0 { // 不包含trash
return db.DeleteByIdAndUserId(db.Notebooks, notebookId, userId), ""
}
return false, "笔记本下有笔记"
}
// 排序
// 传入 notebookId => Seq
// 为什么要传入userId, 防止修改其它用户的信息 (恶意)
// [ok]
func (this *NotebookService) SortNotebooks(userId string, notebookId2Seqs map[string]int) bool {
if len(notebookId2Seqs) == 0 {
return false
}
for notebookId, seq := range notebookId2Seqs {
if !db.UpdateByIdAndUserIdField2(db.Notebooks, bson.ObjectIdHex(notebookId), bson.ObjectIdHex(userId), "Seq", seq) {
return false
}
}
return true
}
+63
View File
@@ -0,0 +1,63 @@
package service
import (
"labix.org/v2/mgo/bson"
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"fmt"
)
// 找回密码
// 修改密码
var overHours = 2.0 // 小时后过期
type PwdService struct {
}
// 1. 找回密码, 通过email找用户,
// 用户存在, 生成code
func (this *PwdService) FindPwd(email string) (ok bool, msg string) {
ok = false
userId := userService.GetUserId(email)
if userId == "" {
msg = "用户不存在"
return
}
token := tokenService.NewToken(userId, email, info.TokenPwd)
if token == "" {
return false, "db error"
}
// 发送邮件
url := "http://leanote.com/findPassword/" + token
body := fmt.Sprintf("请点击链接修改密码: <a href='%v'>%v</a>. %v小时后过期.", url, url, int(overHours));
if !SendEmail(email, "leanote-找回密码", "找回密码", body) {
return false, "邮箱发送失败"
}
ok = true
return
}
// 修改密码
// 先验证
func (this *PwdService) UpdatePwd(token, pwd string) (bool, string) {
var tokenInfo info.Token
var ok bool
var msg string
// 先验证
if ok, msg, tokenInfo = tokenService.VerifyToken(token, info.TokenPwd); !ok {
return ok, msg
}
// 修改密码之
ok = db.UpdateByQField(db.Users, bson.M{"_id": tokenInfo.UserId}, "Pwd", Md5(pwd))
// 删除token
tokenService.DeleteToken(tokenInfo.UserId.Hex(), info.TokenPwd)
return ok, ""
}
+1
View File
@@ -0,0 +1 @@
All services. Called by controller
+510
View File
@@ -0,0 +1,510 @@
package service
import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db"
// . "github.com/leanote/leanote/app/lea"
"labix.org/v2/mgo/bson"
"time"
"sort"
)
// 共享Notebook, Note服务
type ShareService struct {
}
//-----------------
// 总体来说, 这个方法比较麻烦, 速度未知. 以后按以下方案来缓存用户基础数据
// 以后建个用户的基本数据表, 放所有notebook, sharedNotebook的缓存!!
// 每更新一次则启动一个goroutine异步更新
// 共享只能共享本notebook下的, 如果其子也要共享, 必须设置其子!!!
// 那么, 父, 子在shareNotebooks表中都会有记录
// 得到用户的所有*被*共享的Notebook
// 1 得到别人共享给我的所有notebooks
// 2 按parent进行层次化
// 3 每个层按seq进行排序
// 4 按用户分组
// [ok]
func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksByUser, []info.User) {
//-------------
// 查询HasShareNote表得到所有其它用户信息
hasShareNotes := []info.HasShareNote{}
db.ListByQ(db.HasShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(userId)}, &hasShareNotes);
userIds := make([]bson.ObjectId, len(hasShareNotes))
for i, each := range hasShareNotes {
userIds[i] = each.UserId
}
userInfos := userService.GetUserInfosOrderBySeq(userIds);
//--------------------
// 得到他们共享给我的notebooks
shareNotebooks := []info.ShareNotebook{}
db.ShareNotebooks.Find(bson.M{"ToUserId": bson.ObjectIdHex(userId)}).All(&shareNotebooks)
if len(shareNotebooks) == 0 {
return nil, userInfos
}
shareNotebooksLen := len(shareNotebooks)
// 找到了所有的notbookId, 那么找notebook表得到其详细信息
notebookIds := make([]bson.ObjectId, shareNotebooksLen)
shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, shareNotebooksLen)
for i, each := range shareNotebooks {
// 默认的是没有notebookId的
notebookIds[i] = each.NotebookId
shareNotebooksMap[each.NotebookId] = each
}
// 1, 2
subNotebooks := notebookService.GetNotebooksByNotebookIds(notebookIds)
// 填充其它信息变成SubShareNotebooks
subShareNotebooks := this.parseToSubShareNotebooks(&subNotebooks, &shareNotebooksMap)
// 3 按用户进行分组成ShareNotebooksByUser
shareNotebooksByUsersMap := map[bson.ObjectId] []info.ShareNotebooks{}
// 先建立userId => []
for _, eachSub := range subShareNotebooks {
userId := eachSub.Notebook.UserId
if _, ok := shareNotebooksByUsersMap[userId]; ok {
shareNotebooksByUsersMap[userId] = append(shareNotebooksByUsersMap[userId], eachSub)
} else {
shareNotebooksByUsersMap[userId] = []info.ShareNotebooks{eachSub}
}
}
shareNotebooksByUser := info.ShareNotebooksByUser{};
for userId, eachShareNotebooks := range shareNotebooksByUsersMap {
// 4, 按用户排序
shareNotebooksByUser[userId.Hex()] = sortSubShareNotebooks(eachShareNotebooks)
}
return shareNotebooksByUser, userInfos
}
// 排序
func sortSubShareNotebooks(eachNotebooks info.SubShareNotebooks) info.SubShareNotebooks {
// 遍历子, 则子往上进行排序
for _, eachNotebook := range eachNotebooks {
if eachNotebook.Subs != nil && len(eachNotebook.Subs) > 0 {
eachNotebook.Subs = sortSubShareNotebooks(eachNotebook.Subs)
}
}
// 子排完了, 本层排
sort.Sort(&eachNotebooks)
return eachNotebooks
}
// 将普通的notebooks添加perm及shareNotebook信息
func (this *ShareService) parseToSubShareNotebooks(subNotebooks *info.SubNotebooks, shareNotebooksMap *map[bson.ObjectId]info.ShareNotebook) info.SubShareNotebooks {
subShareNotebooks := info.SubShareNotebooks{}
for _, each := range *subNotebooks {
shareNotebooks := info.ShareNotebooks{}
shareNotebooks.Notebook = each.Notebook // 基本信息有了
shareNotebooks.ShareNotebook = (*shareNotebooksMap)[each.NotebookId] // perm有了
// 公用的, 单独赋值
shareNotebooks.Seq = shareNotebooks.ShareNotebook.Seq
shareNotebooks.NotebookId = shareNotebooks.ShareNotebook.NotebookId
// 还有其子, 递归解析之
if each.Subs != nil && len(each.Subs) > 0 {
shareNotebooks.Subs = this.parseToSubShareNotebooks(&each.Subs, shareNotebooksMap)
}
subShareNotebooks = append(subShareNotebooks, shareNotebooks)
}
return subShareNotebooks
}
//-------------
// 得到共享笔记本下的notes
func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, sharedUserId string,
page, pageSize int, sortField string, isAsc bool) ([]info.ShareNoteWithPerm) {
// 1 首先判断是否真的sharedUserId 共享了 notebookId 给 myUserId
shareNotebook := info.ShareNotebook{}
db.GetByQ(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
"UserId": bson.ObjectIdHex(sharedUserId), "ToUserId": bson.ObjectIdHex(myUserId)}, &shareNotebook)
if shareNotebook.NotebookId == "" {
return nil
}
perm := shareNotebook.Perm
// 2 得到该notebook下分页显示所有的notes
_, notes := noteService.ListNotes(sharedUserId, notebookId, false, page, pageSize, sortField, isAsc, false);
// 3 添加权限信息
// 3.1 如果该notebook自己有其它权限信息, 比如1, 那么覆盖notebook的权限信息
noteIds := make([]bson.ObjectId, len(notes))
for i, note := range notes {
noteIds[i] = note.NoteId
}
notePerms := this.getNotesPerm(noteIds, myUserId, sharedUserId);
// 3.2 组合
notesWithPerm := make([]info.ShareNoteWithPerm, len(notes))
for i, each := range notes {
thisPerm := perm;
if selfPerm, ok := notePerms[each.NoteId]; ok {
thisPerm = selfPerm
}
notesWithPerm[i] = info.ShareNoteWithPerm{each, thisPerm}
}
return notesWithPerm
}
// 得到note的perm信息
func (this *ShareService) getNotesPerm(noteIds []bson.ObjectId, myUserId, sharedUserId string) map[bson.ObjectId]int {
shareNotes := []info.ShareNote{}
db.ListByQ(db.ShareNotes, bson.M{"NoteId": bson.M{"$in": noteIds}, "UserId": bson.ObjectIdHex(sharedUserId), "ToUserId": bson.ObjectIdHex(myUserId)}, &shareNotes)
notesPerm := make(map[bson.ObjectId]int, len(shareNotes))
for _, each := range shareNotes {
notesPerm[each.NoteId] = each.Perm
}
return notesPerm
}
// 得到默认的单个的notes 共享集
// 如果真要支持排序, 这里得到所有共享的notes, 到noteService方再sort和limit
// 可以这样! 到时将零散的共享noteId放在用户基本数据中
// 这里不好排序
func (this *ShareService) ListShareNotes(myUserId, sharedUserId string,
pageNumber, pageSize int, sortField string, isAsc bool) ([]info.ShareNoteWithPerm) {
skipNum, _ := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
shareNotes := []info.ShareNote{}
db.ShareNotes.
Find(bson.M{"UserId": bson.ObjectIdHex(sharedUserId), "ToUserId": bson.ObjectIdHex(myUserId)}).
// Sort(sortFieldR).
Skip(skipNum).
Limit(pageSize).
All(&shareNotes)
if len(shareNotes) == 0 {
return nil
}
noteIds := make([]bson.ObjectId, len(shareNotes))
for i, each := range shareNotes {
noteIds[i] = each.NoteId
}
notes := noteService.ListNotesByNoteIds(noteIds)
notesMap := make(map[bson.ObjectId]info.Note, len(notes))
for _, each := range notes {
notesMap[each.NoteId] = each
}
// 将shareNotes与notes结合起来
notesWithPerm := make([]info.ShareNoteWithPerm, len(shareNotes))
for i, each := range shareNotes {
notesWithPerm[i] = info.ShareNoteWithPerm{notesMap[each.NoteId], each.Perm}
}
return notesWithPerm
}
func (this *ShareService) notes2NotesWithPerm(notes []info.Note) {
}
// 添加一个notebook共享
// [ok]
func (this *ShareService) AddShareNotebook1(shareNotebook info.ShareNotebook) bool {
// 添加一条记录说明两者存在关系
this.AddHasShareNote(shareNotebook.UserId.Hex(), shareNotebook.ToUserId.Hex());
shareNotebook.CreatedTime = time.Now()
return db.Insert(db.ShareNotebooks, shareNotebook)
}
// 添加共享笔记本
func (this *ShareService) AddShareNotebook(notebookId string, perm int, userId, email string) (bool, string, string) {
// 通过email得到被共享的userId
toUserId := userService.GetUserId(email)
if toUserId == "" {
return false, "无该用户", ""
}
// 添加一条记录说明两者存在关系
this.AddHasShareNote(userId, toUserId);
// 先删除之
db.Delete(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
"UserId": bson.ObjectIdHex(userId),
"ToUserId": bson.ObjectIdHex(toUserId),
});
shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId),
UserId: bson.ObjectIdHex(userId),
ToUserId: bson.ObjectIdHex(toUserId),
Perm: perm,
CreatedTime: time.Now(),
}
return db.Insert(db.ShareNotebooks, shareNotebook), "", toUserId
}
// 添加一个note共享
// [ok]
/*
func (this *ShareService) AddShareNote(shareNote info.ShareNote) bool {
shareNote.CreatedTime = time.Now()
return db.Insert(db.ShareNotes, shareNote)
}
*/
func (this *ShareService) AddShareNote(noteId string, perm int, userId, email string) (bool, string, string) {
// 通过email得到被共享的userId
toUserId := userService.GetUserId(email)
if toUserId == "" {
return false, "无该用户", ""
}
// 添加一条记录说明两者存在关系
this.AddHasShareNote(userId, toUserId);
// 先删除之
db.Delete(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId),
"UserId": bson.ObjectIdHex(userId),
"ToUserId": bson.ObjectIdHex(toUserId),
});
shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId),
UserId: bson.ObjectIdHex(userId),
ToUserId: bson.ObjectIdHex(toUserId),
Perm: perm,
CreatedTime: time.Now(),
}
return db.Insert(db.ShareNotes, shareNote), "", toUserId
}
// updatedUserId是否有修改userId noteId的权限?
func (this *ShareService) HasUpdatePerm(userId, updatedUserId, noteId string) bool {
// 1. noteId是否被共享了?
// 得到该note share的信息
/*
UserId bson.ObjectId `bson:"UserId"`
ToUserId bson.ObjectId `bson:"ToUserId"`
NoteId bson.ObjectId `bson:"NoteId"`
Perm int `bson:"Perm"` // 权限, 0只读, 1可修改
*/
if !db.Has(db.ShareNotes,
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NoteId": bson.ObjectIdHex(noteId), "Perm": 1}) {
// noteId的notebookId是否被共享了?
notebookId := noteService.GetNotebookId(noteId)
if notebookId.Hex() == "" {
return false
}
// 判断notebook是否被共享
if !db.Has(db.ShareNotebooks,
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NotebookId": notebookId, "Perm": 1}) {
return false
} else {
return true
}
} else {
return true
}
}
// updatedUserId是否有修改userId notebookId的权限?
func (this *ShareService) HasUpdateNotebookPerm(userId, updatedUserId, notebookId string) bool {
// 判断notebook是否被共享
if !db.Has(db.ShareNotebooks,
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NotebookId": bson.ObjectIdHex(notebookId), "Perm": 1}) {
return false
} else {
return true
}
}
// 共享note, notebook时使用
func (this *ShareService) AddHasShareNote(userId, toUserId string) bool {
db.Insert(db.HasShareNotes, info.HasShareNote{UserId: bson.ObjectIdHex(userId), ToUserId: bson.ObjectIdHex(toUserId)})
return true;
}
// userId是否被共享了noteId
func (this *ShareService) hasSharedNote(noteId, myUserId string) bool {
return db.Has(db.ShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(myUserId), "NoteId": bson.ObjectIdHex(noteId)})
}
// noteId的notebook是否共享了给我
func (this *ShareService) hasSharedNotebook(noteId, myUserId, sharedUserId string) bool {
note := noteService.GetNote(noteId, sharedUserId)
if note.NoteId != "" {
return db.Has(db.ShareNotebooks, bson.M{"NotebookId": note.NotebookId,
"UserId": bson.ObjectIdHex(sharedUserId),
"ToUserId": bson.ObjectIdHex(myUserId),
})
}
return false
}
// 得到共享的笔记内容
// 首先要判断这个note是否我被共享了
func (this *ShareService) GetShareNoteContent(noteId, myUserId, sharedUserId string) (noteContent info.NoteContent) {
noteContent = info.NoteContent{}
// 是否单独共享了该notebook
// 或者, 其notebook共享了我
if this.hasSharedNote(noteId, myUserId) || this.hasSharedNotebook(noteId, myUserId, sharedUserId) {
db.Get(db.NoteContents, noteId, &noteContent)
} else {
}
return
}
// 查看note的分享信息
// 分享给了哪些用户和权限
// ShareNotes表 userId = me, noteId = ...
// 还要查看该note的notebookId分享的信息
func (this *ShareService) ListNoteShareUserInfo(noteId, userId string) []info.ShareUserInfo {
// 得到shareNote信息, 得到所有的ToUserId
shareNotes := []info.ShareNote{}
db.ListByQLimit(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId)}, &shareNotes, 100)
if len(shareNotes) == 0 {
return nil
}
shareNotesMap := make(map[bson.ObjectId]info.ShareNote, len(shareNotes))
for _, each := range shareNotes {
shareNotesMap[each.ToUserId] = each
}
toUserIds := make([]bson.ObjectId, len(shareNotes))
for i, eachShareNote := range shareNotes {
toUserIds[i] = eachShareNote.ToUserId
}
note := noteService.GetNote(noteId, userId)
if note.NoteId == "" {
return nil
}
// 查看其notebook的shareNotebooks信息
shareNotebooks := []info.ShareNotebook{}
db.ListByQ(db.ShareNotebooks,
bson.M{"NotebookId": note.NotebookId, "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.M{"$in": toUserIds}},
&shareNotebooks)
shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, len(shareNotebooks))
for _, each := range shareNotebooks {
shareNotebooksMap[each.ToUserId] = each
}
// 得到用户信息
userInfos := userService.ListUserInfosByUserIds(toUserIds)
if len(userInfos) == 0 {
return nil
}
shareUserInfos := make([]info.ShareUserInfo, len(userInfos))
for i, userInfo := range userInfos {
_, hasNotebook := shareNotebooksMap[userInfo.UserId]
shareUserInfos[i] = info.ShareUserInfo{ToUserId: userInfo.UserId,
Email: userInfo.Email,
Perm: shareNotesMap[userInfo.UserId].Perm,
NotebookHasShared: hasNotebook,
}
}
return shareUserInfos
}
// 得到notebook的share信息
// TODO 这里必须要分页, 最多取100个用户; 限制
func (this *ShareService) ListNotebookShareUserInfo(notebookId, userId string) []info.ShareUserInfo {
// notebook的shareNotebooks信息
shareNotebooks := []info.ShareNotebook{}
db.ListByQLimit(db.ShareNotebooks,
bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId)},
&shareNotebooks, 100)
if len(shareNotebooks) == 0 {
return nil
}
// 得到用户信息
toUserIds := make([]bson.ObjectId, len(shareNotebooks))
for i, each := range shareNotebooks {
toUserIds[i] = each.ToUserId
}
userInfos := userService.ListUserInfosByUserIds(toUserIds)
if len(userInfos) == 0 {
return nil
}
shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, len(shareNotebooks))
for _, each := range shareNotebooks {
shareNotebooksMap[each.ToUserId] = each
}
shareUserInfos := make([]info.ShareUserInfo, len(userInfos))
for i, userInfo := range userInfos {
shareUserInfos[i] = info.ShareUserInfo{ToUserId: userInfo.UserId,
Email: userInfo.Email,
Perm: shareNotebooksMap[userInfo.UserId].Perm,
}
}
return shareUserInfos
}
//----------------
// 改变note share权限
func (this *ShareService) UpdateShareNotePerm(noteId string, perm int, userId, toUserId string) bool {
return db.UpdateByQField(db.ShareNotes,
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)},
"Perm",
perm,
)
}
func (this *ShareService) UpdateShareNotebookPerm(notebookId string, perm int, userId, toUserId string) bool {
return db.UpdateByQField(db.ShareNotebooks,
bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)},
"Perm",
perm,
)
}
//---------------
// 删除share note
func (this *ShareService) DeleteShareNote(noteId string, userId, toUserId string) bool {
return db.DeleteAll(db.ShareNotes,
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)})
}
// 删除笔记时要删除该noteId的所有...
func (this *ShareService) DeleteShareNoteAll(noteId string, userId string) bool {
return db.DeleteAll(db.ShareNotes,
bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId)})
}
// 删除share notebook
func (this *ShareService) DeleteShareNotebook(notebookId string, userId, toUserId string) bool {
return db.DeleteAll(db.ShareNotebooks,
bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)})
}
// 删除userId分享给toUserId的所有
func (this *ShareService) DeleteUserShareNoteAndNotebook(userId, toUserId string) bool {
query := bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(toUserId)}
db.DeleteAll(db.ShareNotebooks, query);
db.DeleteAll(db.ShareNotes, query);
db.DeleteAll(db.HasShareNotes, query);
return true
}
+21
View File
@@ -0,0 +1,21 @@
package service
import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db"
// . "github.com/leanote/leanote/app/lea"
"labix.org/v2/mgo/bson"
// "time"
// "sort"
)
type SuggestionService struct {
}
// 得到某博客具体信息
func (this *SuggestionService) AddSuggestion(suggestion info.Suggestion) bool {
if suggestion.Id == "" {
suggestion.Id = bson.NewObjectId()
}
return db.Insert(db.Suggestions, suggestion)
}
+39
View File
@@ -0,0 +1,39 @@
package service
import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db"
. "github.com/leanote/leanote/app/lea"
"labix.org/v2/mgo/bson"
// "time"
)
/*
每添加,更新note时, 都将tag添加到tags表中
*/
type TagService struct {
}
func (this *TagService) GetTags(userId string) []string {
tag := info.Tag{}
db.Get(db.Tags, userId, &tag)
LogJ(tag)
return tag.Tags
}
func (this *TagService) AddTagsI(userId string, tags interface{}) bool {
if ts, ok2 := tags.([]string); ok2 {
return this.AddTags(userId, ts)
}
return false
}
func (this *TagService) AddTags(userId string, tags []string) bool {
for _, tag := range tags {
if !db.Upsert(db.Tags,
bson.M{"_id": bson.ObjectIdHex(userId)},
bson.M{"$addToSet": bson.M{"Tags": tag}}) {
return false
}
}
return true
}
+72
View File
@@ -0,0 +1,72 @@
package service
import (
"labix.org/v2/mgo/bson"
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"time"
)
// token
// 找回密码
// 修改密码
type TokenService struct {
}
// 生成token
func (this *TokenService) NewToken(userId string, email string, tokenType int) string {
token := info.Token{UserId: bson.ObjectIdHex(userId), Token: NewGuidWith(email), CreatedTime: time.Now(), Email: email, Type: tokenType}
if db.Upsert(db.Tokens, bson.M{"_id": token.UserId}, token) {
return token.Token
}
return ""
}
// 删除token
func (this *TokenService) DeleteToken(userId string, tokenType int) bool {
return db.Delete(db.Tokens, bson.M{"_id": bson.ObjectIdHex(userId), "Type": tokenType})
}
func (this *TokenService) GetOverHours(tokenType int) float64 {
if tokenType == info.TokenPwd {
return info.PwdOverHours
} else if tokenType == info.TokenUpdateEmail {
return info.UpdateEmailOverHours
} else {
return info.ActiveEmailOverHours
}
}
// 验证token, 是否存在, 过时?
func (this *TokenService) VerifyToken(token string, tokenType int) (ok bool, msg string, tokenInfo info.Token) {
overHours = this.GetOverHours(tokenType)
ok = false
if token == "" {
msg = "不存在"
return
}
db.GetByQ(db.Tokens, bson.M{"Token": token}, &tokenInfo)
if tokenInfo.UserId == "" {
msg = "不存在"
return
}
// 验证是否过时
now := time.Now()
duration := now.Sub(tokenInfo.CreatedTime)
if duration.Hours() > overHours {
msg = "过期"
return
}
ok = true
return
}
+65
View File
@@ -0,0 +1,65 @@
package service
import (
"labix.org/v2/mgo/bson"
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
)
// 回收站
// 可以移到noteSerice中
// 不能删除notebook, 如果其下有notes!
// 这样回收站里只有note
// 删除笔记后(或删除笔记本)后入回收站
// 把note, notebook设个标记即可!
// 已经在trash里的notebook, note不能是共享!, 所以要删除共享
type TrashService struct {
}
//---------------------
// 删除note
// 应该放在回收站里
// 有trashService
func (this *TrashService) DeleteNote(noteId, userId string) bool {
// 首先删除其共享
if shareService.DeleteShareNoteAll(noteId, userId) {
// 更新note isTrash = true
return db.UpdateByIdAndUserId(db.Notes, noteId, userId, bson.M{"$set": bson.M{"IsTrash": true}})
}
return false
}
// 删除别人共享给我的笔记
// 先判断我是否有权限, 笔记是否是我创建的
func (this *TrashService) DeleteSharedNote(noteId, userId, myUserId string) bool {
note := noteService.GetNote(noteId, userId)
if shareService.HasUpdatePerm(userId, myUserId, noteId) && note.CreatedUserId.Hex() == myUserId {
return db.UpdateByIdAndUserId(db.Notes, noteId, userId, bson.M{"$set": bson.M{"IsTrash": true}})
}
return false
}
// recover
func (this *TrashService) recoverNote(noteId, notebookId, userId string) bool {
re := db.UpdateByIdAndUserId(db.Notes, noteId, userId,
bson.M{"$set": bson.M{"IsTrash": false,
"NotebookId": bson.ObjectIdHex(notebookId)}})
return re;
}
// 删除trash
func (this *TrashService) DeleteTrash(noteId, userId string) bool {
return db.DeleteByIdAndUserId(db.Notes, noteId, userId)
}
// 列出note, 排序规则, 还有分页
// CreatedTime, UpdatedTime, title 来排序
func (this *TrashService) ListNotes(userId string,
pageNumber, pageSize int, sortField string, isAsc bool) (notes []info.Note) {
_, notes = noteService.ListNotes(userId, "", true, pageNumber, pageSize, sortField, isAsc, false)
return
}
+294
View File
@@ -0,0 +1,294 @@
package service
import (
"github.com/leanote/leanote/app/info"
"github.com/leanote/leanote/app/db"
. "github.com/leanote/leanote/app/lea"
"labix.org/v2/mgo/bson"
"time"
"strings"
"fmt"
)
type UserService struct {
}
// 添加用户
func (this *UserService) AddUser(user info.User) bool {
if user.UserId == "" {
user.UserId = bson.NewObjectId()
}
user.CreatedTime = time.Now()
if user.Email != "" {
user.Email = strings.ToLower(user.Email)
// 发送验证邮箱
go func() {
this.RegisterSendActiveEmail(user.UserId.Hex(), user.Email)
}();
}
return db.Insert(db.Users, user)
}
// 通过email得到userId
func (this *UserService) GetUserId(email string) string {
email = strings.ToLower(email)
user := info.User{}
db.GetByQ(db.Users, bson.M{"Email": email}, &user)
return user.UserId.Hex()
}
// 是否存在该用户 email
func (this *UserService) IsExistsUser(email string) bool {
if this.GetUserId(email) == "" {
return false
}
return true
}
// 是否存在该用户 username
func (this *UserService) IsExistsUserByUsername(username string) bool {
return db.Count(db.Users, bson.M{"Username": username}) >= 1
}
// 得到用户信息, userId, username, email
func (this *UserService) GetUserInfoByAny(idEmailUsername string) info.User {
if IsObjectId(idEmailUsername) {
return this.GetUserInfo(idEmailUsername)
}
if strings.Contains(idEmailUsername, "@") {
return this.GetUserInfoByEmail(idEmailUsername)
}
return this.GetUserInfoByUsername(idEmailUsername)
}
// 得到用户信息 userId
func (this *UserService) GetUserInfo(userId string) info.User {
user := info.User{}
db.Get(db.Users, userId, &user)
return user
}
// 得到用户信息 email
func (this *UserService) GetUserInfoByEmail(email string) info.User {
user := info.User{}
db.GetByQ(db.Users, bson.M{"Email": email}, &user)
return user
}
// 得到用户信息 username
func (this *UserService) GetUserInfoByUsername(username string) info.User {
user := info.User{}
db.GetByQ(db.Users, bson.M{"Username": username}, &user)
return user
}
func (this *UserService) GetUserInfoByThirdUserId(thirdUserId string) info.User {
user := info.User{}
db.GetByQ(db.Users, bson.M{"ThirdUserId": thirdUserId}, &user)
return user
}
func (this *UserService) ListUserInfosByUserIds(userIds []bson.ObjectId) []info.User {
users := []info.User{}
db.ListByQ(db.Users, bson.M{"_id": bson.M{"$in": userIds}}, &users)
return users
}
// 通过ids得到users, 按id的顺序组织users
func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.User {
users := []info.User{}
db.ListByQ(db.Users, bson.M{"_id": bson.M{"$in": userIds}}, &users);
usersMap := map[bson.ObjectId]info.User{}
for _, user := range users {
usersMap[user.UserId] = user
}
users2 := []info.User{};
for _, userId := range userIds {
if user, ok := usersMap[userId]; ok {
users2 = append(users2, user)
}
}
return users2
}
// 使用email(username), pwd得到用户信息
func (this *UserService) LoginGetUserInfo(emailOrUsername, md5Pwd string) info.User {
emailOrUsername = strings.ToLower(emailOrUsername)
user := info.User{}
if strings.Contains(emailOrUsername, "@") {
db.GetByQ(db.Users, bson.M{"Email": emailOrUsername, "Pwd": md5Pwd}, &user)
} else {
db.GetByQ(db.Users, bson.M{"Username": emailOrUsername, "Pwd": md5Pwd}, &user)
}
return user
}
// 更新username
func (this *UserService) UpdateUsername(userId, username string) (bool, string) {
if userId == "" || username == "" {
return false, "用户已存在"
}
usernameRaw := username // 原先的, 可能是同一个, 但有大小写
username = strings.ToLower(username)
// 先判断是否存在
userIdO := bson.ObjectIdHex(userId)
if db.Has(db.Users, bson.M{"Username": username, "_id": bson.M{"$ne": userIdO}}) {
return false, "用户已存在"
}
ok := db.UpdateByQMap(db.Users, bson.M{"_id": userIdO}, bson.M{"Username": username, "UsernameRaw": usernameRaw})
return ok, ""
}
//----------------------
// 已经登录了的用户修改密码
func (this *UserService) UpdatePwd(userId, oldPwd, pwd string) (bool, string) {
userInfo := this.GetUserInfo(userId)
if userInfo.Pwd != Md5(oldPwd) {
return false, "旧密码错误"
}
ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", Md5(pwd))
return ok, ""
}
// 修改主题
func (this *UserService) UpdateTheme(userId, theme string) (bool) {
ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Theme", theme)
return ok
}
//---------------
// 修改email
// 发送激活邮件
// AddUser调用
// 可以使用一个goroutine
func (this *UserService) RegisterSendActiveEmail(userId string, email string) bool {
token := tokenService.NewToken(userId, email, info.TokenActiveEmail)
if token == "" {
return false
}
// 发送邮件
url := "http://leanote.com/user/activeEmail?token=" + token
body := fmt.Sprintf("请点击链接验证邮箱: <a href='%v'>%v</a>. %v小时后过期.", url, url, tokenService.GetOverHours(info.TokenActiveEmail));
if !SendEmail(email, "leanote-验证邮箱", "验证邮箱", body) {
return false
}
// 发送给我 life@leanote.com
SendEmail("life@leanote.com", "新增用户", "新增用户", "用户名" + email);
return true
}
// 修改邮箱
func (this *UserService) UpdateEmailSendActiveEmail(userId, email string) (ok bool, msg string) {
// 先验证该email是否被注册了
if userService.IsExistsUser(email) {
ok = false
msg = "该邮箱已注册"
return
}
token := tokenService.NewToken(userId, email, info.TokenUpdateEmail)
if token == "" {
return
}
// 发送邮件
url := "http://115.28.133.226/user/updateEmail?token=" + token
body := "邮箱验证后您的登录邮箱为: <b>" + email + "</b><br />";
body += fmt.Sprintf("请点击链接验证邮箱: <a href='%v'>%v</a>. %v小时后过期.", url, url, tokenService.GetOverHours(info.TokenUpdateEmail));
if !SendEmail(email, "leanote-验证邮箱", "验证邮箱", body) {
msg = "发送失败"
return
}
ok = true
return
}
// 注册后验证邮箱
func (this *UserService) ActiveEmail(token string) (ok bool, msg, email string) {
tokenInfo := info.Token{}
if ok, msg, tokenInfo = tokenService.VerifyToken(token, info.TokenActiveEmail); ok {
// 修改之后的邮箱
email = tokenInfo.Email
userInfo := this.GetUserInfoByEmail(email)
if userInfo.UserId == "" {
ok = false
msg = "不存在该用户"
return
}
// 修改之, 并将verified = true
ok = db.UpdateByQMap(db.Users, bson.M{"_id": userInfo.UserId}, bson.M{"Verified": true})
return
}
ok = false
msg = "该链接已过期"
return
}
// 修改邮箱
// 在此之前, 验证token是否过期
// 验证email是否有人注册了
func (this *UserService) UpdateEmail(token string) (ok bool, msg, email string) {
tokenInfo := info.Token{}
if ok, msg, tokenInfo = tokenService.VerifyToken(token, info.TokenUpdateEmail); ok {
// 修改之后的邮箱
email = tokenInfo.Email
// 先验证该email是否被注册了
if userService.IsExistsUser(email) {
ok = false
msg = "该邮箱已注册"
return
}
// 修改之, 并将verified = true
ok = db.UpdateByQMap(db.Users, bson.M{"_id": tokenInfo.UserId}, bson.M{"Email": email, "Verified": true})
return
}
ok = false
msg = "该链接已过期"
return
}
//---------
// 第三方添加账号
func (this *UserService) ThirdAddUser(userId, email, pwd string) (ok bool, msg string) {
// 判断email是否存在
if this.IsExistsUser(email) {
msg = "该用户已存在"
return
}
ok = db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, bson.M{"Email": email, "Pwd": Md5(pwd)})
return
}
//------------
// 偏好设置
// 宽度
func (this *UserService)UpdateColumnWidth(userId string, notebookWidth, noteListWidth int) bool {
return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, bson.M{"NotebookWidth": notebookWidth, "NoteListWidth": noteListWidth})
}
// 左侧是否隐藏
func (this *UserService)UpdateLeftIsMin(userId string, leftIsMin bool) bool {
return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, bson.M{"LeftIsMin": leftIsMin})
}
+20
View File
@@ -0,0 +1,20 @@
package service
import (
)
// service 通用方法
// 分页, 排序处理
func parsePageAndSort(pageNumber, pageSize int, sortField string, isAsc bool) (skipNum int, sortFieldR string) {
skipNum = (pageNumber - 1) * pageSize
if sortField == "" {
sortField = "UpdatedTime"
}
if !isAsc {
sortFieldR = "-" + sortField
} else {
sortFieldR = sortField
}
return
}
+31
View File
@@ -0,0 +1,31 @@
package service
import (
)
// init service, for share service bettween services
// 初始化, 实例service
// 为了共享service
var notebookService *NotebookService
var noteService *NoteService
var noteContentHistoryService *NoteContentHistoryService
var trashService *TrashService
var shareService *ShareService
var userService *UserService
var tagService *TagService
var blogService *BlogService
var tokenService *TokenService
func init() {
notebookService = &NotebookService{}
noteService = &NoteService{}
noteContentHistoryService = &NoteContentHistoryService{}
trashService = &TrashService{}
shareService = &ShareService{}
userService = &UserService{}
tagService = &TagService{}
blogService = &BlogService{}
tokenService = &TokenService{}
}