init
This commit is contained in:
1 parent
fac05a7b6c
commit
476ade10e7
1085 files changed
+259628
No files matched your search
@@ -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
|
||||
}
|
||||
@@ -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}, ¬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}
|
||||
}
|
||||
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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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, ¬e)
|
||||
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}, ¬e)
|
||||
return
|
||||
}
|
||||
// 通过id, userId得到noteContent
|
||||
func (this *NoteService) GetNoteContent(noteContentId, userId string) (noteContent info.NoteContent) {
|
||||
noteContent = info.NoteContent{}
|
||||
db.GetByIdAndUserId(db.NoteContents, noteContentId, userId, ¬eContent)
|
||||
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(¬es)
|
||||
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(¬es)
|
||||
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(¬es)
|
||||
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(¬es)
|
||||
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"}, ¬es)
|
||||
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"}, ¬e);
|
||||
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(¬es)
|
||||
|
||||
// 如果 < 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(¬eContents)
|
||||
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(¬es)
|
||||
return
|
||||
}
|
||||
@@ -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, ¬ebook)
|
||||
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"}, ¬ebook);
|
||||
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"}, ¬es)
|
||||
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
|
||||
}
|
||||
@@ -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, ""
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
All services. Called by controller
|
||||
@@ -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, ¬eContent)
|
||||
} 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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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})
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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{}
|
||||
}
|
||||
Reference in new issue
Block a user