From 1f45666ec426838dd276ab98658bf4d65adc4cda Mon Sep 17 00:00:00 2001 From: life Date: Wed, 12 Nov 2014 17:32:03 +0800 Subject: [PATCH] beta2 ok --- app/controllers/BlogController.go | 409 ++++------- app/controllers/IndexController.go | 4 + app/controllers/PreviewController.go | 12 +- app/controllers/ShareController.go | 48 +- app/controllers/admin/AdminBlogController.go | 4 +- app/controllers/admin/AdminController.go | 1 + .../admin/AdminSettingController.go | 9 + .../admin/AdminUpgradeController.go | 6 +- .../member/MemberBlogController.go | 95 ++- .../member/MemberGroupController.go | 58 ++ app/controllers/member/init.go | 2 + app/info/BlogCustom.go | 2 + app/info/BlogInfo.go | 18 +- app/info/GroupInfo.go | 25 + app/info/NoteInfo.go | 14 +- app/info/NotebookInfo.go | 1 + app/info/ShareNotebookNoteInfo.go | 8 +- app/info/UserInfo.go | 4 +- app/info/common.go | 5 +- app/init.go | 7 +- app/service/AuthService.go | 5 +- app/service/BlogService.go | 657 ++++++++++++------ app/service/ConfigService.go | 9 + app/service/GroupService.go | 130 ++++ app/service/NoteImageService.go | 7 +- app/service/NoteService.go | 30 +- app/service/NotebookService.go | 12 + app/service/ShareService.go | 355 +++++++--- app/service/ThemeService.go | 30 + app/service/UpgradeService.go | 62 +- app/service/UserService.go | 26 +- app/service/init.go | 77 ++ app/views/admin/nav.html | 39 +- app/views/admin/setting/home_page.html | 49 ++ .../{openRegister.html => open_register.html} | 0 app/views/admin/upgrade/beta2.html | 47 ++ app/views/member/blog/cate.html | 18 +- app/views/member/blog/comment.html | 3 +- app/views/member/blog/list.html | 169 +++++ app/views/member/blog/page.html | 33 + app/views/member/blog/single.html | 18 +- app/views/member/blog/update_abstract.html | 127 ++++ app/views/member/group/index.html | 220 ++++++ app/views/member/nav.html | 22 +- app/views/note/note-dev.html | 2 +- .../share/note_notebook_share_user_infos.html | 126 +++- conf/routes-default | 21 +- messages/msg.en | 1 + messages/msg.zh | 1 + .../leanote_install_data/albums.bson | Bin 599 -> 0 bytes .../leanote_install_data/attachs.bson | Bin 16100 -> 0 bytes .../attachs.metadata.json | 1 - .../leanote_install_data/blog_comments.bson | Bin 15724 -> 0 bytes .../leanote_install_data/blog_likes.bson | Bin 1079 -> 0 bytes .../leanote_install_data/blog_singles.bson | Bin 0 -> 538 bytes ...tadata.json => blog_singles.metadata.json} | 2 +- .../leanote_install_data/configs.bson | Bin 21865 -> 0 bytes .../leanote_install_data/email_logs.bson | Bin 209 -> 0 bytes .../email_logs.metadata.json | 1 - .../leanote_install_data/files.bson | Bin 584 -> 0 bytes .../leanote_install_data/files.metadata.json | 1 - .../leanote_install_data/find_pwds.bson | Bin 348 -> 0 bytes .../find_pwds.metadata.json | 1 - .../leanote_install_data/group_users.bson | Bin 0 -> 84 bytes ...etadata.json => group_users.metadata.json} | 2 +- .../leanote_install_data/groups.bson | Bin 0 -> 102 bytes ...igs.metadata.json => groups.metadata.json} | 2 +- .../leanote_install_data/has_share_notes.bson | Bin 219 -> 0 bytes .../has_share_notes.metadata.json | 1 - .../leanote.ShareNotes.bson | 0 .../leanote.ShareNotes.metadata.json | 1 - .../leanote.has_share_notes.bson | 0 .../leanote.has_share_notes.metadata.json | 1 - .../note_content_histories.bson | Bin 11537 -> 0 bytes .../note_content_histories.metadata.json | 1 - .../leanote_install_data/note_contents.bson | Bin 6572 -> 0 bytes .../note_contents.metadata.json | 1 - .../leanote_install_data/note_images.bson | Bin 3339 -> 0 bytes .../note_images.metadata.json | 1 - .../leanote_install_data/notebooks.bson | Bin 1147 -> 0 bytes .../notebooks.metadata.json | 1 - .../leanote_install_data/notes.bson | Bin 1786 -> 0 bytes .../leanote_install_data/notes.metadata.json | 1 - .../leanote_install_data/reports.bson | Bin 915 -> 0 bytes .../reports.metadata.json | 1 - .../leanote_install_data/sessions.bson | Bin 2100 -> 0 bytes .../sessions.metadata.json | 1 - .../leanote_install_data/share_notebooks.bson | Bin 384 -> 0 bytes .../share_notebooks.metadata.json | 1 - .../leanote_install_data/share_notes.bson | Bin 345 -> 0 bytes .../share_notes.metadata.json | 1 - .../leanote_install_data/suggestions.bson | Bin 4219 -> 0 bytes .../suggestions.metadata.json | 1 - .../leanote_install_data/system.indexes.bson | Bin 2779 -> 0 bytes .../system.users.metadata.json | 1 - mongodb_backup/leanote_install_data/tags.bson | Bin 62 -> 0 bytes .../leanote_install_data/tags.metadata.json | 1 - .../leanote_install_data/themes.bson | Bin 0 -> 1587 bytes ...ums.metadata.json => themes.metadata.json} | 2 +- .../leanote_install_data/tokens.bson | Bin 872 -> 0 bytes .../leanote_install_data/tokens.metadata.json | 1 - .../leanote_install_data/user_blogs.bson | Bin 631 -> 0 bytes .../user_blogs.metadata.json | 1 - .../leanote_install_data/users.bson | Bin 569 -> 0 bytes .../leanote_install_data/users.metadata.json | 1 - public/blog/js/ck/common-min.js | 1 - public/blog/js/common.js | 6 +- public/blog/themes/README.html | 1 + public/blog/themes/default/header.html | 10 +- public/blog/themes/elegant/archive.html | 12 +- public/blog/themes/elegant/header.html | 4 +- public/blog/themes/elegant/index.html | 4 +- public/blog/themes/elegant/post.html | 4 +- public/blog/themes/elegant/search.html | 4 +- public/blog/themes/elegant/tag_posts.html | 4 +- public/blog/themes/nav_fixed/header.html | 10 +- public/member/css/member.css | 6 + public/member/css/member.less | 8 +- public/tinymce/plugins/leaui_image/plugin.js | 6 +- 119 files changed, 2463 insertions(+), 675 deletions(-) create mode 100644 app/controllers/member/MemberGroupController.go create mode 100644 app/info/GroupInfo.go create mode 100644 app/service/GroupService.go create mode 100644 app/views/admin/setting/home_page.html rename app/views/admin/setting/{openRegister.html => open_register.html} (100%) create mode 100644 app/views/admin/upgrade/beta2.html create mode 100644 app/views/member/blog/list.html create mode 100644 app/views/member/blog/page.html create mode 100644 app/views/member/blog/update_abstract.html create mode 100644 app/views/member/group/index.html delete mode 100644 mongodb_backup/leanote_install_data/albums.bson delete mode 100644 mongodb_backup/leanote_install_data/attachs.bson delete mode 100644 mongodb_backup/leanote_install_data/attachs.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/blog_comments.bson delete mode 100644 mongodb_backup/leanote_install_data/blog_likes.bson create mode 100644 mongodb_backup/leanote_install_data/blog_singles.bson rename mongodb_backup/leanote_install_data/{blog_likes.metadata.json => blog_singles.metadata.json} (59%) delete mode 100644 mongodb_backup/leanote_install_data/configs.bson delete mode 100644 mongodb_backup/leanote_install_data/email_logs.bson delete mode 100644 mongodb_backup/leanote_install_data/email_logs.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/files.bson delete mode 100644 mongodb_backup/leanote_install_data/files.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/find_pwds.bson delete mode 100644 mongodb_backup/leanote_install_data/find_pwds.metadata.json create mode 100644 mongodb_backup/leanote_install_data/group_users.bson rename mongodb_backup/leanote_install_data/{blog_comments.metadata.json => group_users.metadata.json} (59%) create mode 100644 mongodb_backup/leanote_install_data/groups.bson rename mongodb_backup/leanote_install_data/{configs.metadata.json => groups.metadata.json} (62%) delete mode 100644 mongodb_backup/leanote_install_data/has_share_notes.bson delete mode 100644 mongodb_backup/leanote_install_data/has_share_notes.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/leanote.ShareNotes.bson delete mode 100644 mongodb_backup/leanote_install_data/leanote.ShareNotes.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/leanote.has_share_notes.bson delete mode 100644 mongodb_backup/leanote_install_data/leanote.has_share_notes.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/note_content_histories.bson delete mode 100644 mongodb_backup/leanote_install_data/note_content_histories.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/note_contents.bson delete mode 100644 mongodb_backup/leanote_install_data/note_contents.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/note_images.bson delete mode 100644 mongodb_backup/leanote_install_data/note_images.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/notebooks.bson delete mode 100644 mongodb_backup/leanote_install_data/notebooks.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/notes.bson delete mode 100644 mongodb_backup/leanote_install_data/notes.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/reports.bson delete mode 100644 mongodb_backup/leanote_install_data/reports.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/sessions.bson delete mode 100644 mongodb_backup/leanote_install_data/sessions.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/share_notebooks.bson delete mode 100644 mongodb_backup/leanote_install_data/share_notebooks.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/share_notes.bson delete mode 100644 mongodb_backup/leanote_install_data/share_notes.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/suggestions.bson delete mode 100644 mongodb_backup/leanote_install_data/suggestions.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/system.indexes.bson delete mode 100644 mongodb_backup/leanote_install_data/system.users.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/tags.bson delete mode 100644 mongodb_backup/leanote_install_data/tags.metadata.json create mode 100644 mongodb_backup/leanote_install_data/themes.bson rename mongodb_backup/leanote_install_data/{albums.metadata.json => themes.metadata.json} (62%) delete mode 100644 mongodb_backup/leanote_install_data/tokens.bson delete mode 100644 mongodb_backup/leanote_install_data/tokens.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/user_blogs.bson delete mode 100644 mongodb_backup/leanote_install_data/user_blogs.metadata.json delete mode 100644 mongodb_backup/leanote_install_data/users.bson delete mode 100644 mongodb_backup/leanote_install_data/users.metadata.json delete mode 100644 public/blog/js/ck/common-min.js create mode 100644 public/blog/themes/README.html diff --git a/app/controllers/BlogController.go b/app/controllers/BlogController.go index d0a84f4..172b9d8 100644 --- a/app/controllers/BlogController.go +++ b/app/controllers/BlogController.go @@ -4,11 +4,11 @@ import ( "github.com/revel/revel" "strings" // "encoding/json" + "fmt" "github.com/leanote/leanote/app/info" . "github.com/leanote/leanote/app/lea" "github.com/leanote/leanote/app/lea/blog" "gopkg.in/mgo.v2/bson" - "fmt" // "github.com/leanote/leanote/app/types" // "io/ioutil" // "math" @@ -47,26 +47,25 @@ $.bootstrapCssUrl $.bootstrapJsUrl */ - func (c Blog) render(templateName string, themePath string) revel.Result { isPreview := false - if c.RenderArgs["isPreview"] != nil { + if c.RenderArgs["isPreview"] != nil { themePath2 := c.RenderArgs["themePath"] if themePath2 == nil { - return c.E404(); + return c.E404() } isPreview = true themePath = themePath2.(string) c.setPreviewUrl() } - return blog.RenderTemplate(templateName, c.RenderArgs, revel.BasePath + "/" + themePath, isPreview) + return blog.RenderTemplate(templateName, c.RenderArgs, revel.BasePath+"/"+themePath, isPreview) } // 404 func (c Blog) e404(themePath string) revel.Result { // 不知道是谁的404, 则用系统的404 if themePath == "" { - return c.E404(); + return c.E404() } return c.render("404.html", themePath) } @@ -101,24 +100,24 @@ func (c Blog) domain() (ok bool, userBlog info.UserBlog) { // 渲染模板之 func (c Blog) setPreviewUrl() { var indexUrl, postUrl, searchUrl, cateUrl, singleUrl, tagsUrl, archiveUrl string - + userId := c.GetUserId() themeId := c.Session["themeId"] theme := themeService.GetTheme(userId, themeId) - + siteUrl := configService.GetSiteUrl() blogUrl := siteUrl + "/preview" // blog.leanote.com userIdOrEmail := userId indexUrl = blogUrl + "/" + userIdOrEmail - cateUrl = blogUrl + "/cate" // /notebookId - - postUrl = blogUrl + "/post" // /xxxxx - searchUrl = blogUrl + "/search/" + userIdOrEmail // blog.leanote.com/search/userId - singleUrl = blogUrl + "/single" // blog.leanote.com/single/singleId + cateUrl = blogUrl + "/cate" // /notebookId + + postUrl = blogUrl + "/post" // /xxxxx + searchUrl = blogUrl + "/search/" + userIdOrEmail // blog.leanote.com/search/userId + singleUrl = blogUrl + "/single" // blog.leanote.com/single/singleId archiveUrl = blogUrl + "/archives/" + userIdOrEmail // blog.leanote.com/archive/userId - tagsUrl = blogUrl + "/tags/" + userIdOrEmail // blog.leanote.com/archive/userId - + tagsUrl = blogUrl + "/tags/" + userIdOrEmail // blog.leanote.com/archive/userId + c.RenderArgs["indexUrl"] = indexUrl c.RenderArgs["cateUrl"] = cateUrl c.RenderArgs["postUrl"] = postUrl @@ -127,7 +126,7 @@ func (c Blog) setPreviewUrl() { c.RenderArgs["archiveUrl"] = archiveUrl c.RenderArgs["archivesUrl"] = archiveUrl // 别名 c.RenderArgs["tagsUrl"] = tagsUrl - c.RenderArgs["tagPostsUrl"] = blogUrl + "/tag/" + userIdOrEmail + c.RenderArgs["tagPostsUrl"] = blogUrl + "/tag/" + userIdOrEmail c.RenderArgs["tagUrl"] = c.RenderArgs["tagPostsUrl"] // themeBaseUrl 本theme的路径url, 可以加载js, css, images之类的 @@ -137,89 +136,55 @@ func (c Blog) setPreviewUrl() { // 各种地址设置 func (c Blog) setUrl(userBlog info.UserBlog, userInfo info.User) { // 主页 http://leanote.com/blog/life or http://blog.leanote.com/life or http:// xxxx.leanote.com or aa.com - var indexUrl, postUrl, searchUrl, cateUrl, singleUrl, tagsUrl, archiveUrl, tagPostsUrl, staticUrl string host := c.Request.Request.Host - staticUrl = configService.GetUserUrl(strings.Split(host, ":")[0]) + var staticUrl = configService.GetUserUrl(strings.Split(host, ":")[0]) // staticUrl == host, 为保证同源!!! 只有host, http://leanote.com, http://blog/leanote.com // life.leanote.com, lealife.com siteUrl := configService.GetSiteUrl() - if userBlog.Domain != "" && configService.AllowCustomDomain() { - // ok - indexUrl = configService.GetUserUrl(userBlog.Domain) - cateUrl = indexUrl + "/cate" // /xxxxx - postUrl = indexUrl + "/post" // /xxxxx - searchUrl = indexUrl + "/search" // /xxxxx - singleUrl = indexUrl + "/single" - archiveUrl = indexUrl + "/archives" - tagsUrl = indexUrl + "/tags" - tagPostsUrl = indexUrl + "/tag" - } else if userBlog.SubDomain != "" { - indexUrl = configService.GetUserSubUrl(userBlog.SubDomain) - cateUrl = indexUrl + "/cate" // /xxxxx - postUrl = indexUrl + "/post" // /xxxxx - searchUrl = indexUrl + "/search" // /xxxxx - singleUrl = indexUrl + "/single" - archiveUrl = indexUrl + "/archives" - tagsUrl = indexUrl + "/tags" - tagPostsUrl = indexUrl + "/tag" - } else { - // ok - blogUrl := configService.GetBlogUrl() // blog.leanote.com - userIdOrEmail := "" - if userInfo.Username != "" { - userIdOrEmail = userInfo.Username - } else if userInfo.Email != "" { - userIdOrEmail = userInfo.Email - } else { - userIdOrEmail = userInfo.UserId.Hex() - } - indexUrl = blogUrl + "/" + userIdOrEmail - cateUrl = blogUrl + "/cate" // /notebookId - postUrl = blogUrl + "/post" // /xxxxx - searchUrl = blogUrl + "/search/" + userIdOrEmail // blog.leanote.com/search/userId - singleUrl = blogUrl + "/single" // blog.leanote.com/single/singleId - archiveUrl = blogUrl + "/archives/" + userIdOrEmail // blog.leanote.com/archive/userId - tagsUrl = blogUrl + "/tags/" + userIdOrEmail - tagPostsUrl = blogUrl + "/tag/" + userIdOrEmail // blog.leanote.com/archive/userId - } - + blogUrls := blogService.GetBlogUrls(&userBlog, &userInfo) // 分类 // 搜索 // 查看 c.RenderArgs["siteUrl"] = siteUrl - c.RenderArgs["indexUrl"] = indexUrl - c.RenderArgs["cateUrl"] = cateUrl - c.RenderArgs["postUrl"] = postUrl - c.RenderArgs["searchUrl"] = searchUrl - c.RenderArgs["singleUrl"] = singleUrl // 单页 - c.RenderArgs["archiveUrl"] = archiveUrl - c.RenderArgs["archivesUrl"] = archiveUrl // 别名 - c.RenderArgs["tagsUrl"] = tagsUrl - c.RenderArgs["tagPostsUrl"] = tagPostsUrl - c.RenderArgs["tagUrl"] = c.RenderArgs["tagPostsUrl"] // 别名 + c.RenderArgs["indexUrl"] = blogUrls.IndexUrl + c.RenderArgs["cateUrl"] = blogUrls.CateUrl + c.RenderArgs["postUrl"] = blogUrls.PostUrl + c.RenderArgs["searchUrl"] = blogUrls.SearchUrl + c.RenderArgs["singleUrl"] = blogUrls.SingleUrl // 单页 + c.RenderArgs["archiveUrl"] = blogUrls.ArchiveUrl + c.RenderArgs["archivesUrl"] = blogUrls.ArchiveUrl // 别名 + c.RenderArgs["tagsUrl"] = blogUrls.TagsUrl + c.RenderArgs["tagPostsUrl"] = blogUrls.TagPostsUrl + c.RenderArgs["tagUrl"] = blogUrls.TagPostsUrl // 别名 // themeBaseUrl 本theme的路径url, 可以加载js, css, images之类的 c.RenderArgs["themeBaseUrl"] = "/" + userBlog.ThemePath // 其它static js c.RenderArgs["jQueryUrl"] = siteUrl + "/js/jquery-1.9.0.min.js" - + c.RenderArgs["prettifyJsUrl"] = siteUrl + "/js/google-code-prettify/prettify.js" c.RenderArgs["prettifyCssUrl"] = siteUrl + "/js/google-code-prettify/prettify.css" - + c.RenderArgs["blogCommonJsUrl"] = siteUrl + "/public/blog/js/common.js" - + c.RenderArgs["shareCommentCssUrl"] = siteUrl + "/public/blog/css/share_comment.css" c.RenderArgs["shareCommentJsUrl"] = siteUrl + "/public/blog/js/share_comment.js" - + c.RenderArgs["fontAwesomeUrl"] = staticUrl + "/css/font-awesome-4.2.0/css/font-awesome.css" - + c.RenderArgs["bootstrapCssUrl"] = siteUrl + "/css/bootstrap.css" c.RenderArgs["bootstrapJsUrl"] = siteUrl + "/js/bootstrap-min.js" } // 笔记本分类 // cates = [{title:"xxx", cateId: "xxxx"}, {}] +func (c Blog) getCateUrlTitle(n *info.Notebook) string { + if n.UrlTitle != "" { + return n.UrlTitle + } + return n.NotebookId.Hex() +} func (c Blog) getCates(userBlog info.UserBlog) { notebooks := blogService.ListBlogNotebooks(userBlog.UserId.Hex()) notebooksMap := map[string]info.Notebook{} @@ -236,7 +201,7 @@ func (c Blog) getCates(userBlog info.UserBlog) { if cateIds != nil && len(cateIds) > 0 { for _, cateId := range cateIds { if n, ok := notebooksMap[cateId]; ok { - cates[i] = map[string]string{"Title": n.Title, "CateId": n.NotebookId.Hex()} + cates[i] = map[string]string{"Title": n.Title, "UrlTitle": c.getCateUrlTitle(&n), "CateId": n.NotebookId.Hex()} i++ has[cateId] = true } @@ -246,7 +211,7 @@ func (c Blog) getCates(userBlog info.UserBlog) { for _, n := range notebooks { id := n.NotebookId.Hex() if !has[id] { - cates[i] = map[string]string{"Title": n.Title, "CateId": id} + cates[i] = map[string]string{"Title": n.Title, "UrlTitle": c.getCateUrlTitle(&n), "CateId": id} i++ } } @@ -279,39 +244,15 @@ func (c Blog) setBlog(userBlog info.UserBlog, userInfo info.User) { "Logo": userBlog.Logo, "OpenComment": userBlog.CanComment, "CommentType": userBlog.CommentType, // leanote, or disqus - "DisqusId": userBlog.DisqusId, + "DisqusId": userBlog.DisqusId, "ThemeId": userBlog.ThemeId, "SubDomain": userBlog.SubDomain, "Domain": userBlog.Domain, } c.RenderArgs["blogInfo"] = blogInfo - /* - blogInfo := info.BlogInfoCustom{ - UserId: userBlog.UserId.Hex(), - Username: userInfo.Username, - UserLogo: userInfo.Logo, - Title: userBlog.Title, - SubTitle: userBlog.SubTitle, - Logo: userBlog.Logo, - OpenComment: userBlog.CanComment, - CommentType: userBlog.CommentType, // leanote, or disqus - ThemeId: userBlog.ThemeId, - SubDomain: userBlog.SubDomain, - Domain: userBlog.Domain, - } - */ } func (c Blog) setPaging(pageInfo info.Page) { - /* - // 这些分类信息用一个变量 - paging := map[string]interface{}{ // 分页信息 - "CurPage": pageInfo.CurPage, // 当前页 - "TotalPage": pageInfo.TotalPage, // 总页数 - "PerPageSize": pageInfo.PerPageSize, // 每一页的记录数 - "Count": pageInfo.Count, // 总记录数 - } - */ c.RenderArgs["paging"] = pageInfo } @@ -323,13 +264,13 @@ func (c Blog) blogCommon(userId string, userBlog info.UserBlog, userInfo info.Us return false, userBlog } } -// c.RenderArgs["userInfo"] = userInfo + // c.RenderArgs["userInfo"] = userInfo // 最新笔记 _, recentBlogs := blogService.ListBlogs(userId, "", 1, 5, userBlog.SortField, userBlog.IsAsc) - c.RenderArgs["recentPosts"] = c.fixBlogs(recentBlogs) - c.RenderArgs["latestPosts"] = c.RenderArgs["recentPosts"] - c.RenderArgs["tags"] = blogService.GetBlogTags(userId) + c.RenderArgs["recentPosts"] = blogService.FixBlogs(recentBlogs) + c.RenderArgs["latestPosts"] = c.RenderArgs["recentPosts"] + c.RenderArgs["tags"] = blogService.GetBlogTags(userId) // 语言, url地址 c.SetLocale() @@ -339,7 +280,7 @@ func (c Blog) blogCommon(userId string, userBlog info.UserBlog, userInfo info.Us userBlog = blogService.GetUserBlog(userId) } c.setBlog(userBlog, userInfo) -// c.RenderArgs["userBlog"] = userBlog + // c.RenderArgs["userBlog"] = userBlog // 分类导航 c.getCates(userBlog) @@ -352,42 +293,14 @@ func (c Blog) blogCommon(userId string, userBlog info.UserBlog, userInfo info.Us // 当前分类Id, 全设为"" c.RenderArgs["curCateId"] = "" c.RenderArgs["curSingleId"] = "" - + // 得到主题信息 themeInfo := themeService.GetThemeInfo(userBlog.ThemeId.Hex(), userBlog.Style) - LogJ(themeInfo) c.RenderArgs["themeInfo"] = themeInfo return true, userBlog } -// 修复博客, index, cate用到 -func (c Blog) fixBlog(blog info.BlogItem) info.Post { - blog2 := info.Post{ - NoteId: blog.NoteId.Hex(), - Title: blog.Title, - CreatedTime: blog.CreatedTime, - UpdatedTime: blog.UpdatedTime, - PublicTime: blog.PublicTime, - Desc: blog.Desc, - Abstract: blog.Abstract, - Content: blog.Content, - Tags: blog.Tags, - CommentNum: blog.CommentNum, - ReadNum: blog.ReadNum, - LikeNum: blog.LikeNum, - IsMarkdown: blog.IsMarkdown, - } - return blog2 -} -func (c Blog) fixBlogs(blogs []info.BlogItem) []info.Post { - blogs2 := make([]info.Post, len(blogs)) - for i, blog := range blogs { - blogs2[i] = c.fixBlog(blog) - } - return blogs2 -} - // 404 func (c Blog) E(userIdOrEmail, tag string) revel.Result { ok, userBlog := c.domain() @@ -403,8 +316,8 @@ func (c Blog) E(userIdOrEmail, tag string) revel.Result { userInfo = userService.GetUserInfoByAny(userIdOrEmail) } userId = userInfo.UserId.Hex() - _, userBlog = c.blogCommon(userId, userBlog, userInfo); - + _, userBlog = c.blogCommon(userId, userBlog, userInfo) + return c.e404(userBlog.ThemePath) } @@ -413,10 +326,10 @@ func (c Blog) Tags(userIdOrEmail string) (re revel.Result) { hasDomain, userBlog := c.domain() defer func() { if err := recover(); err != nil { - re = c.e404(userBlog.ThemePath); + re = c.e404(userBlog.ThemePath) } }() - + userId := "" if hasDomain { userId = userBlog.UserId.Hex() @@ -448,10 +361,10 @@ func (c Blog) Tag(userIdOrEmail, tag string) (re revel.Result) { hasDomain, userBlog := c.domain() defer func() { if err := recover(); err != nil { - re = c.e404(userBlog.ThemePath); + re = c.e404(userBlog.ThemePath) } }() - + userId := "" if hasDomain { userId = userBlog.UserId.Hex() @@ -465,23 +378,23 @@ func (c Blog) Tag(userIdOrEmail, tag string) (re revel.Result) { userInfo = userService.GetUserInfoByAny(userIdOrEmail) } userId = userInfo.UserId.Hex() - + var ok = false if ok, userBlog = c.blogCommon(userId, userBlog, userInfo); !ok { return c.e404(userBlog.ThemePath) // 404 TODO 使用用户的404 } - + if hasDomain && tag == "" { tag = userIdOrEmail } - + c.RenderArgs["curIsTagPosts"] = true c.RenderArgs["curTag"] = tag page := c.GetPage() pageInfo, blogs := blogService.SearchBlogByTags([]string{tag}, userId, page, userBlog.PerPageSize, userBlog.SortField, userBlog.IsAsc) c.setPaging(pageInfo) - c.RenderArgs["posts"] = c.fixBlogs(blogs) + c.RenderArgs["posts"] = blogService.FixBlogs(blogs) tagPostsUrl := c.RenderArgs["tagPostsUrl"].(string) c.RenderArgs["pagingBaseUrl"] = tagPostsUrl + "/" + tag @@ -496,7 +409,7 @@ func (c Blog) Archives(userIdOrEmail string, cateId string, year, month int) (re defer func() { if err := recover(); err != nil { fmt.Println(err) - re = c.e404(userBlog.ThemePath); + re = c.e404(userBlog.ThemePath) } }() userId := "" @@ -532,59 +445,52 @@ func (c Blog) Archives(userIdOrEmail string, cateId string, year, month int) (re } c.RenderArgs["curYear"] = year c.RenderArgs["curMonth"] = month - return c.render("archive.html", userBlog.ThemePath) } // 进入某个用户的博客 -// TODO 可以配置, 排序和数目 var blogPageSize = 5 var searchBlogPageSize = 30 - // 分类 /cate/xxxxxxxx?notebookId=1212 -func (c Blog) Cate(notebookId string) (re revel.Result) { +func (c Blog) Cate(userIdOrEmail string, notebookId string) (re revel.Result) { // 自定义域名 hasDomain, userBlog := c.domain() defer func() { if err := recover(); err != nil { - re = c.e404(userBlog.ThemePath); + fmt.Println(err) + re = c.e404(userBlog.ThemePath) } }() - - if notebookId == "" { - return c.e404(userBlog.ThemePath); - } - userId := "" - if hasDomain { - userId = userBlog.UserId.Hex() - } + userId, userInfo := c.userIdOrEmail(hasDomain, userBlog, userIdOrEmail) + notebookId2 := notebookId var notebook info.Notebook - notebook = notebookService.GetNotebookById(notebookId) + if userId == "" { // 证明没有userIdOrEmail, 只有singleId, 那么直接查 + notebook = notebookService.GetNotebookById(notebookId) + userId = notebook.UserId.Hex() + } else { + notebook = notebookService.GetNotebookByUserIdAndUrlTitle(userId, notebookId) + notebookId2 = notebook.NotebookId.Hex() + } + var ok = false + if ok, userBlog = c.blogCommon(userId, userBlog, userInfo); !ok { + return c.e404(userBlog.ThemePath) // 404 TODO 使用用户的404 + } if !notebook.IsBlog { return c.e404("") } - if userId != "" && userId != notebook.UserId.Hex() { - return c.e404("") - } - userId = notebook.UserId.Hex() - - var ok = false - if ok, userBlog = c.blogCommon(userId, userBlog, info.User{}); !ok { - return c.e404(userBlog.ThemePath) - } // 分页的话, 需要分页信息, totalPage, curPage page := c.GetPage() - pageInfo, blogs := blogService.ListBlogs(userId, notebookId, page, userBlog.PerPageSize, userBlog.SortField, userBlog.IsAsc) - blogs2 := c.fixBlogs(blogs) + pageInfo, blogs := blogService.ListBlogs(userId, notebookId2, page, userBlog.PerPageSize, userBlog.SortField, userBlog.IsAsc) + blogs2 := blogService.FixBlogs(blogs) c.RenderArgs["posts"] = blogs2 c.setPaging(pageInfo) c.RenderArgs["curCateTitle"] = notebook.Title - c.RenderArgs["curCateId"] = notebookId + c.RenderArgs["curCateId"] = notebookId2 cateUrl := c.RenderArgs["cateUrl"].(string) c.RenderArgs["pagingBaseUrl"] = cateUrl + "/" + notebookId c.RenderArgs["curIsCate"] = true @@ -592,31 +498,37 @@ func (c Blog) Cate(notebookId string) (re revel.Result) { return c.render("cate.html", userBlog.ThemePath) } +func (c Blog) userIdOrEmail(hasDomain bool, userBlog info.UserBlog, userIdOrEmail string) (userId string, userInfo info.User) { + userId = "" + if hasDomain { + userId = userBlog.UserId.Hex() + } + if userId != "" { + userInfo = userService.GetUserInfoByAny(userId) + } else { + if userIdOrEmail != "" { + userInfo = userService.GetUserInfoByAny(userIdOrEmail) + } else { + return + } + } + userId = userInfo.UserId.Hex() + return +} + func (c Blog) Index(userIdOrEmail string) (re revel.Result) { // 自定义域名 hasDomain, userBlog := c.domain() defer func() { if err := recover(); err != nil { - re = c.e404(userBlog.ThemePath); + re = c.e404(userBlog.ThemePath) } }() - userId := "" - if hasDomain { - userId = userBlog.UserId.Hex() - } - - // 用户id为空, 转至博客平台 + // 用户id为空, 则是admin用户的博客 if userIdOrEmail == "" { userIdOrEmail = configService.GetAdminUsername() } - var userInfo info.User - if userId != "" { - userInfo = userService.GetUserInfoByAny(userId) - } else { - userInfo = userService.GetUserInfoByAny(userIdOrEmail) - } - userId = userInfo.UserId.Hex() - + userId, userInfo := c.userIdOrEmail(hasDomain, userBlog, userIdOrEmail) var ok = false if ok, userBlog = c.blogCommon(userId, userBlog, userInfo); !ok { return c.e404(userBlog.ThemePath) // 404 TODO 使用用户的404 @@ -625,7 +537,7 @@ func (c Blog) Index(userIdOrEmail string) (re revel.Result) { // 分页的话, 需要分页信息, totalPage, curPage page := c.GetPage() pageInfo, blogs := blogService.ListBlogs(userId, "", page, userBlog.PerPageSize, userBlog.SortField, userBlog.IsAsc) - blogs2 := c.fixBlogs(blogs) + blogs2 := blogService.FixBlogs(blogs) c.RenderArgs["posts"] = blogs2 c.setPaging(pageInfo) @@ -636,66 +548,36 @@ func (c Blog) Index(userIdOrEmail string) (re revel.Result) { return c.render("index.html", userBlog.ThemePath) } -// 详情 -// 为了上一篇, 下一篇 -func (c Blog) fixNote(note info.Note) map[string]interface{} { - if note.NoteId == "" { - return nil - } - return map[string]interface{}{ - "NoteId": note.NoteId.Hex(), - "Title": note.Title, - "CreatedTime": note.CreatedTime, - "UpdatedTime": note.UpdatedTime, - "PublicTime": note.PublicTime, - "Desc": note.Desc, - "Tags": note.Tags, - "CommentNum": note.CommentNum, - "ReadNum": note.ReadNum, - "LikeNum": note.LikeNum, - "IsMarkdown": note.IsMarkdown, - } -} - -func (c Blog) Post(noteId string) (re revel.Result) { +func (c Blog) Post(userIdOrEmail, noteId string) (re revel.Result) { // 自定义域名 hasDomain, userBlog := c.domain() defer func() { if err := recover(); err != nil { Log(err) - re = c.e404(userBlog.ThemePath); + re = c.e404(userBlog.ThemePath) } }() - userId := "" - if hasDomain { - userId = userBlog.UserId.Hex() + + userId, userInfo := c.userIdOrEmail(hasDomain, userBlog, userIdOrEmail) + var blogInfo info.BlogItem + if userId == "" { // 证明没有userIdOrEmail, 只有singleId, 那么直接查 + blogInfo = blogService.GetBlog(noteId) + userId = blogInfo.UserId.Hex() + } else { + blogInfo = blogService.GetBlogByIdAndUrlTitle(userId, noteId) + } + var ok = false + if ok, userBlog = c.blogCommon(userId, userBlog, userInfo); !ok { + return c.e404(userBlog.ThemePath) // 404 TODO 使用用户的404 + } + if blogInfo.NoteId == "" { + return c.e404(userBlog.ThemePath) // 404 TODO 使用用户的404 } - blogInfo := blogService.GetBlog(noteId) - userInfo := userService.GetUserInfo(blogInfo.UserId.Hex()) - if userId != "" && userInfo.UserId.Hex() != userId { - panic("error") - } - - userId = userInfo.UserId.Hex() - _, userBlog = c.blogCommon(userId, userBlog, info.User{}) - - c.RenderArgs["post"] = c.fixBlog(blogInfo) + c.RenderArgs["post"] = blogService.FixBlog(blogInfo) // c.RenderArgs["userInfo"] = userInfo c.RenderArgs["curIsPost"] = true - // 得到访问者id - /* - visitUserId := c.GetUserId() - if visitUserId != "" { - visitUserInfo := userService.GetUserInfo(visitUserId) - c.RenderArgs["visitUserInfoJson"] = c.Json(visitUserInfo) - c.RenderArgs["visitUserInfo"] = visitUserInfo - } else { - c.RenderArgs["visitUserInfoJson"] = "{}" - } - */ - // 上一篇, 下一篇 var baseTime interface{} if userBlog.SortField == "PublicTime" { @@ -708,44 +590,46 @@ func (c Blog) Post(noteId string) (re revel.Result) { baseTime = blogInfo.Title } - preNote, nextNote := blogService.PreNextBlog(userId, userBlog.SortField, userBlog.IsAsc, baseTime) - c.RenderArgs["prePost"] = c.fixNote(preNote) - c.RenderArgs["nextPost"] = c.fixNote(nextNote) - Log("---------") + prePost, nextPost := blogService.PreNextBlog(userId, userBlog.SortField, userBlog.IsAsc, baseTime) + c.RenderArgs["prePost"] = prePost + c.RenderArgs["nextPost"] = nextPost return c.render("post.html", userBlog.ThemePath) } -func (c Blog) Single(singleId string) (re revel.Result) { +func (c Blog) Single(userIdOrEmail, singleId string) (re revel.Result) { // 自定义域名 hasDomain, userBlog := c.domain() defer func() { if err := recover(); err != nil { - re = c.e404(userBlog.ThemePath); + re = c.e404(userBlog.ThemePath) } }() - - userId := "" - if hasDomain { - userId = userBlog.UserId.Hex() - } - single := blogService.GetSingle(singleId) - userInfo := userService.GetUserInfo(single.UserId.Hex()) - if userId != "" && userInfo.UserId.Hex() != userId { - return c.e404(userBlog.ThemePath) + userId, userInfo := c.userIdOrEmail(hasDomain, userBlog, userIdOrEmail) + var single info.BlogSingle + if userId == "" { // 证明没有userIdOrEmail, 只有singleId, 那么直接查 + single = blogService.GetSingle(singleId) + userId = single.UserId.Hex() + } else { + single = blogService.GetSingleByUserIdAndUrlTitle(userId, singleId) + } + var ok = false + if ok, userBlog = c.blogCommon(userId, userBlog, userInfo); !ok { + return c.e404(userBlog.ThemePath) // 404 TODO 使用用户的404 + } + if single.SingleId == "" { + panic("") } - - userId = userInfo.UserId.Hex() - _, userBlog = c.blogCommon(userId, userBlog, info.User{}) c.RenderArgs["single"] = map[string]interface{}{ "SingleId": single.SingleId.Hex(), "Title": single.Title, + "UrlTitle": single.UrlTitle, "Content": single.Content, "CreatedTime": single.CreatedTime, "UpdatedTime": single.UpdatedTime, } - c.RenderArgs["curSingleId"] = singleId + c.RenderArgs["curSingleId"] = single.SingleId.Hex() c.RenderArgs["curIsSingle"] = true return c.render("single.html", userBlog.ThemePath) @@ -757,7 +641,7 @@ func (c Blog) Search(userIdOrEmail, keywords string) (re revel.Result) { hasDomain, userBlog := c.domain() defer func() { if err := recover(); err != nil { - re = c.e404(userBlog.ThemePath); + re = c.e404(userBlog.ThemePath) } }() userId := "" @@ -771,7 +655,7 @@ func (c Blog) Search(userIdOrEmail, keywords string) (re revel.Result) { } else { userInfo = userService.GetUserInfoByAny(userIdOrEmail) } -// c.RenderArgs["userInfo"] = userInfo + // c.RenderArgs["userInfo"] = userInfo userId = userInfo.UserId.Hex() var ok = false if ok, userBlog = c.blogCommon(userId, userBlog, userInfo); !ok { @@ -782,7 +666,7 @@ func (c Blog) Search(userIdOrEmail, keywords string) (re revel.Result) { pageInfo, blogs := blogService.SearchBlog(keywords, userId, page, userBlog.PerPageSize, userBlog.SortField, userBlog.IsAsc) c.setPaging(pageInfo) - c.RenderArgs["posts"] = c.fixBlogs(blogs) + c.RenderArgs["posts"] = blogService.FixBlogs(blogs) c.RenderArgs["keywords"] = keywords searchUrl, _ := c.RenderArgs["searchUrl"].(string) c.RenderArgs["pagingBaseUrl"] = searchUrl + "?keywords=" + keywords @@ -808,7 +692,7 @@ func (c Blog) GetPostStat(noteId string) revel.Result { re.Ok = true statInfo := blogService.GetBlogStat(noteId) re.Item = statInfo - return c.RenderJson(re); + return c.RenderJson(re) } // jsonP @@ -819,7 +703,7 @@ func (c Blog) GetLikes(noteId string, callback string) revel.Result { userId := c.GetUserId() result := map[string]interface{}{} isILikeIt := false - if userId != "" { + if userId != "" { isILikeIt = blogService.IsILikeIt(noteId, userId) result["visitUserInfo"] = userService.GetUserAndBlog(userId) } @@ -841,11 +725,11 @@ func (c Blog) GetLikesAndComments(noteId, callback string) revel.Result { // 我也点过? isILikeIt := false - if userId != "" { + if userId != "" { isILikeIt = blogService.IsILikeIt(noteId, userId) result["visitUserInfo"] = userService.GetUserAndBlog(userId) } - + // 点赞用户列表 likedUsers, hasMoreLikedUser := blogService.ListLikedUsers(noteId, false) // 评论 @@ -892,18 +776,21 @@ func (c Blog) GetComments(noteId string) revel.Result { return c.RenderJson(re) } + // jsonp func (c Blog) DeleteComment(noteId, commentId string, callback string) revel.Result { re := info.NewRe() re.Ok = blogService.DeleteComment(noteId, commentId, c.GetUserId()) return c.RenderJsonP(callback, re) } + // jsonp func (c Blog) CommentPost(noteId, content, toCommentId string, callback string) revel.Result { re := info.NewRe() re.Ok, re.Item = blogService.Comment(noteId, toCommentId, c.GetUserId(), content) return c.RenderJsonP(callback, re) } + // jsonp func (c Blog) LikeComment(commentId string, callback string) revel.Result { re := info.NewRe() diff --git a/app/controllers/IndexController.go b/app/controllers/IndexController.go index b6a86a6..bc4b86d 100644 --- a/app/controllers/IndexController.go +++ b/app/controllers/IndexController.go @@ -14,6 +14,10 @@ type Index struct { // leanote展示页, 没有登录的, 或已登录明确要进该页的 func (c Index) Index() revel.Result { + if configService.HomePageIsAdminsBlog(){ + blog := Blog{c.BaseController} + return blog.Index(configService.GetAdminUsername()); + } c.SetUserInfo() c.RenderArgs["title"] = "leanote" c.RenderArgs["openRegister"] = configService.GlobalStringConfigs["openRegister"] diff --git a/app/controllers/PreviewController.go b/app/controllers/PreviewController.go index c049f56..03cfca9 100644 --- a/app/controllers/PreviewController.go +++ b/app/controllers/PreviewController.go @@ -71,25 +71,25 @@ func (c Preview) Archives(userIdOrEmail string, notebookId string, year, month i return c.Blog.Archives(c.GetUserId(), notebookId, year, month) // return blog.RenderTemplate("archive.html", c.RenderArgs, c.getPreviewThemeAbsolutePath("")) } -func (c Preview) Cate(notebookId string) revel.Result { +func (c Preview) Cate(userIdOrEmail, notebookId string) revel.Result { if !c.getPreviewThemeAbsolutePath("") { return c.E404() } - return c.Blog.Cate(notebookId) + return c.Blog.Cate(userIdOrEmail, notebookId) // return blog.RenderTemplate("cate.html", c.RenderArgs, c.getPreviewThemeAbsolutePath("")) } -func (c Preview) Post(noteId string) revel.Result { +func (c Preview) Post(userIdOrEmail, noteId string) revel.Result { if !c.getPreviewThemeAbsolutePath("") { return c.E404() } - return c.Blog.Post(noteId) + return c.Blog.Post(userIdOrEmail, noteId) // return blog.RenderTemplate("view.html", c.RenderArgs, c.getPreviewThemeAbsolutePath("")) } -func (c Preview) Single(singleId string) revel.Result { +func (c Preview) Single(userIdOrEmail, singleId string) revel.Result { if !c.getPreviewThemeAbsolutePath("") { return c.E404() } - return c.Blog.Single(singleId) + return c.Blog.Single(userIdOrEmail, singleId) // return blog.RenderTemplate("single.html", c.RenderArgs, c.getPreviewThemeAbsolutePath("")) } func (c Preview) Search(userIdOrEmail, keywords string) revel.Result { diff --git a/app/controllers/ShareController.go b/app/controllers/ShareController.go index 15dc17c..9630b0b 100644 --- a/app/controllers/ShareController.go +++ b/app/controllers/ShareController.go @@ -4,7 +4,7 @@ import ( "github.com/revel/revel" // "encoding/json" // "gopkg.in/mgo.v2/bson" -// . "github.com/leanote/leanote/app/lea" + . "github.com/leanote/leanote/app/lea" "github.com/leanote/leanote/app/info" // "github.com/leanote/leanote/app/types" // "io/ioutil" @@ -87,6 +87,8 @@ func (c Share) ListNoteShareUserInfo(noteId string) revel.Result { noteShareUserInfos := shareService.ListNoteShareUserInfo(noteId, c.GetUserId()) c.RenderArgs["noteOrNotebookShareUserInfos"] = noteShareUserInfos + c.RenderArgs["noteOrNotebookShareGroupInfos"] = shareService.GetNoteShareGroups(noteId, c.GetUserId()) + c.RenderArgs["isNote"] = true c.RenderArgs["noteOrNotebookId"] = note.NoteId.Hex(); c.RenderArgs["title"] = note.Title @@ -99,6 +101,9 @@ func (c Share) ListNotebookShareUserInfo(notebookId string) revel.Result { notebookShareUserInfos := shareService.ListNotebookShareUserInfo(notebookId, c.GetUserId()) c.RenderArgs["noteOrNotebookShareUserInfos"] = notebookShareUserInfos + c.RenderArgs["noteOrNotebookShareGroupInfos"] = shareService.GetNotebookShareGroups(notebookId, c.GetUserId()) + LogJ(c.RenderArgs["noteOrNotebookShareGroupInfos"]) + c.RenderArgs["isNote"] = false c.RenderArgs["noteOrNotebookId"] = notebook.NotebookId.Hex(); c.RenderArgs["title"] = notebook.Title @@ -139,4 +144,45 @@ func (c Share) DeleteShareNotebookBySharedUser(notebookId string, fromUserId str // 删除fromUserId分享给我的所有note, notebook func (c Share) DeleteUserShareNoteAndNotebook(fromUserId string) revel.Result { return c.RenderJson(shareService.DeleteUserShareNoteAndNotebook(fromUserId, c.GetUserId())); +} + +//------------- +// 用户组 + + +// 将笔记分享给分组 +func (c Share) AddShareNoteGroup(noteId, groupId string, perm int) revel.Result { + re := info.NewRe() + re.Ok = shareService.AddShareNoteGroup(c.GetUserId(), noteId, groupId, perm); + return c.RenderJson(re); +} +// 删除 +func (c Share) DeleteShareNoteGroup(noteId, groupId string) revel.Result { + re := info.NewRe() + re.Ok = shareService.DeleteShareNoteGroup(c.GetUserId(), noteId, groupId); + return c.RenderJson(re); +} +// 更新, 也是一样, 先删后加 +func (c Share) UpdateShareNoteGroupPerm(noteId, groupId string, perm int) revel.Result { + return c.AddShareNoteGroup(noteId, groupId, perm) +} + + +//------ + +// 将笔记分享给分组 +func (c Share) AddShareNotebookGroup(notebookId, groupId string, perm int) revel.Result { + re := info.NewRe() + re.Ok = shareService.AddShareNotebookGroup(c.GetUserId(), notebookId, groupId, perm); + return c.RenderJson(re); +} +// 删除 +func (c Share) DeleteShareNotebookGroup(notebookId, groupId string) revel.Result { + re := info.NewRe() + re.Ok = shareService.DeleteShareNotebookGroup(c.GetUserId(), notebookId, groupId); + return c.RenderJson(re); +} +// 更新, 也是一样, 先删后加 +func (c Share) UpdateShareNotebookGroupPerm(notebookId, groupId string, perm int) revel.Result { + return c.AddShareNotebookGroup(notebookId, groupId, perm) } \ No newline at end of file diff --git a/app/controllers/admin/AdminBlogController.go b/app/controllers/admin/AdminBlogController.go index 9843938..ca8a48d 100644 --- a/app/controllers/admin/AdminBlogController.go +++ b/app/controllers/admin/AdminBlogController.go @@ -16,7 +16,7 @@ type AdminBlog struct { func (c AdminBlog) Index(sorter, keywords string) revel.Result { pageNumber := c.GetPage() sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "userId", "isRecommed", "createdTime"}); - pageInfo, blogs := blogService.ListAllBlogs("", keywords, false, pageNumber, userPageSize, sorterField, isAsc); + pageInfo, blogs := blogService.ListAllBlogs("", "", keywords, false, pageNumber, userPageSize, sorterField, isAsc); c.RenderArgs["pageInfo"] = pageInfo c.RenderArgs["blogs"] = blogs c.RenderArgs["keywords"] = keywords @@ -27,4 +27,4 @@ func (c AdminBlog) SetRecommend(noteId string, recommend bool) revel.Result { re := info.NewRe() re.Ok = blogService.SetRecommend(noteId, recommend); return c.RenderJson(re) -} \ No newline at end of file +} diff --git a/app/controllers/admin/AdminController.go b/app/controllers/admin/AdminController.go index dad63d1..c3215a5 100644 --- a/app/controllers/admin/AdminController.go +++ b/app/controllers/admin/AdminController.go @@ -30,6 +30,7 @@ func (c Admin) T(t string) revel.Result { c.RenderArgs["arr"] = configService.GlobalArrayConfigs c.RenderArgs["map"] = configService.GlobalMapConfigs c.RenderArgs["arrMap"] = configService.GlobalArrMapConfigs + c.RenderArgs["version"] = configService.GetVersion() return c.RenderTemplate("admin/" + t + ".html") } diff --git a/app/controllers/admin/AdminSettingController.go b/app/controllers/admin/AdminSettingController.go index f36e892..8a4ce51 100644 --- a/app/controllers/admin/AdminSettingController.go +++ b/app/controllers/admin/AdminSettingController.go @@ -111,6 +111,15 @@ func (c AdminSetting) OpenRegister(openRegister string) revel.Result { return c.RenderJson(re) } +func (c AdminSetting) HomePage(homePage string) revel.Result { + re := info.NewRe() + if homePage == "0" { + homePage = "" + } + re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "homePage", homePage) + return c.RenderJson(re) +} + func (c AdminSetting) Mongodb(mongodumpPath, mongorestorePath string) revel.Result { re := info.NewRe() re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "mongodumpPath", mongodumpPath) diff --git a/app/controllers/admin/AdminUpgradeController.go b/app/controllers/admin/AdminUpgradeController.go index 8580acf..3835d68 100644 --- a/app/controllers/admin/AdminUpgradeController.go +++ b/app/controllers/admin/AdminUpgradeController.go @@ -17,8 +17,8 @@ func (c AdminUpgrade) UpgradeBlog() revel.Result { return nil; } -func (c AdminUpgrade) UpgradeBetaToSelfBlog() revel.Result { +func (c AdminUpgrade) UpgradeBetaToBeta2() revel.Result { re := info.NewRe() - re.Ok, re.Msg = upgradeService.UpgradeBetaToSelfBlog(c.GetUserId()) + re.Ok, re.Msg = upgradeService.UpgradeBetaToBeta2(c.GetUserId()) return c.RenderJson(re) -} +} \ No newline at end of file diff --git a/app/controllers/member/MemberBlogController.go b/app/controllers/member/MemberBlogController.go index 9dca66c..daa75b5 100644 --- a/app/controllers/member/MemberBlogController.go +++ b/app/controllers/member/MemberBlogController.go @@ -8,10 +8,11 @@ import ( "io/ioutil" "time" "fmt" + "strings" // "github.com/leanote/leanote/app/lea/blog" ) -// admin 首页 +// 博客管理 type MemberBlog struct { MemberBaseController @@ -33,6 +34,82 @@ func (c MemberBlog) common() info.UserBlog { return userBlog } + +// 得到sorterField 和 isAsc +// okSorter = ['email', 'username'] +func (c MemberBlog) getSorter(sorterField string, isAsc bool, okSorter []string) (string, bool){ + sorter := "" + c.Params.Bind(&sorter, "sorter") + if sorter == "" { + return sorterField, isAsc; + } + + // sorter形式 email-up, email-down + s2 := strings.Split(sorter, "-") + if len(s2) != 2 { + return sorterField, isAsc; + } + + // 必须是可用的sorter + if okSorter != nil && len(okSorter) > 0 { + if !InArray(okSorter, s2[0]) { + return sorterField, isAsc; + } + } + + sorterField = strings.Title(s2[0]) + if s2[1] == "up" { + isAsc = true + } else { + isAsc = false + } + c.RenderArgs["sorter"] = sorter + return sorterField, isAsc; +} + +// 博客列表 +var userPageSize = 15 +func (c MemberBlog) Index(sorter, keywords string) revel.Result { + c.RenderArgs["title"] = "Posts" + pageNumber := c.GetPage() + sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "urlTitle", "updatedTime", "publicTime", "createdTime"}); + pageInfo, blogs := blogService.ListAllBlogs(c.GetUserId(), "", keywords, false, pageNumber, userPageSize, sorterField, isAsc); + c.RenderArgs["pageInfo"] = pageInfo + c.RenderArgs["blogs"] = blogs + c.RenderArgs["keywords"] = keywords + + userAndBlog := userService.GetUserAndBlog(c.GetUserId()) + c.RenderArgs["userAndBlog"] = userAndBlog + + return c.RenderTemplate("member/blog/list.html"); +} + +// 修改笔记的urlTitle +func (c MemberBlog) UpdateBlogUrlTitle(noteId, urlTitle string) revel.Result { + re := info.NewRe() + re.Ok, re.Item = blogService.UpateBlogUrlTitle(c.GetUserId(), noteId, urlTitle) + return c.RenderJson(re) +} + + +// 修改笔记的urlTitle +func (c MemberBlog) UpdateBlogAbstract(noteId string) revel.Result { + c.RenderArgs["title"] = "Update Post Abstract" + note := noteService.GetNoteAndContent(noteId, c.GetUserId()); + if !note.Note.IsBlog { + return c.E404(); + } + c.RenderArgs["note"] = note + c.RenderArgs["noteId"] = noteId + return c.RenderTemplate("member/blog/update_abstract.html"); +} +func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string) revel.Result { + + re := info.NewRe() + re.Ok = blogService.UpateBlogAbstract(c.GetUserId(), noteId, imgSrc, desc, abstract) + return c.RenderJson(re) +} + // 基本信息设置 func (c MemberBlog) Base() revel.Result { c.common() @@ -101,6 +178,12 @@ func (c MemberBlog) UpateCateIds(cateIds []string) revel.Result { return c.RenderJson(re) } +func (c MemberBlog) UpdateCateUrlTitle(cateId, urlTitle string) revel.Result { + re := info.NewRe() + re.Ok, re.Item = blogService.UpateCateUrlTitle(c.GetUserId(), cateId, urlTitle) + return c.RenderJson(re) +} + // 保存之, 包含增加与保存 func (c MemberBlog) DoAddOrUpdateSingle(singleId, title, content string) revel.Result { re := info.NewRe() @@ -127,6 +210,14 @@ func (c MemberBlog) DeleteSingle(singleId string) revel.Result { re.Ok = blogService.DeleteSingle(c.GetUserId(), singleId) return c.RenderJson(re) } + +// 修改页面标题 +func (c MemberBlog) UpdateSingleUrlTitle(singleId, urlTitle string) revel.Result { + re := info.NewRe() + re.Ok, re.Item = blogService.UpdateSingleUrlTitle(c.GetUserId(), singleId, urlTitle) + return c.RenderJson(re) +} + func (c MemberBlog) Single() revel.Result { c.common() c.RenderArgs["title"] = "Cate" @@ -425,4 +516,4 @@ func (c MemberBlog) SetUserBlogPaging(perPageSize int, sortField string, isAsc b re := info.NewRe() re.Ok, re.Msg = blogService.UpdateUserBlogPaging(c.GetUserId(), perPageSize, sortField, isAsc) return c.RenderRe(re) -} \ No newline at end of file +} diff --git a/app/controllers/member/MemberGroupController.go b/app/controllers/member/MemberGroupController.go new file mode 100644 index 0000000..815857d --- /dev/null +++ b/app/controllers/member/MemberGroupController.go @@ -0,0 +1,58 @@ +package member + +import ( + "github.com/revel/revel" + "github.com/leanote/leanote/app/info" +) + +// 分组管理 +type MemberGroup struct { + MemberBaseController +} + +// 首页, 显示所有分组和用户 +func (c MemberGroup) Index() revel.Result { + c.SetUserInfo() + c.SetLocale() + c.RenderArgs["title"] = "My Group" + c.RenderArgs["groups"] = groupService.GetGroupsAndUsers(c.GetUserId()) + return c.RenderTemplate("member/group/index.html"); +} + +// 添加分组 +func (c MemberGroup) AddGroup(title string) revel.Result { + re := info.NewRe() + re.Ok, re.Item = groupService.AddGroup(c.GetUserId(), title) + return c.RenderJson(re) +} + +func (c MemberGroup) UpdateGroupTitle(groupId, title string) revel.Result { + re := info.NewRe() + re.Ok = groupService.UpdateGroupTitle(c.GetUserId(), groupId, title) + return c.RenderJson(re) +} + +func (c MemberGroup) DeleteGroup(groupId string) revel.Result { + re := info.NewRe() + re.Ok, re.Msg = groupService.DeleteGroup(c.GetUserId(), groupId) + return c.RenderJson(re) +} + +// 添加用户 +func (c MemberGroup) AddUser(groupId, email string) revel.Result { + re := info.NewRe() + userInfo := userService.GetUserInfoByAny(email) + if userInfo.UserId == "" { + re.Msg = "userNotExists" + } else { + re.Ok, re.Msg = groupService.AddUser(c.GetUserId(), groupId, userInfo.UserId.Hex()) + re.Item = userInfo + } + return c.RenderRe(re) +} + +func (c MemberGroup) DeleteUser(groupId, userId string) revel.Result { + re := info.NewRe() + re.Ok, re.Msg = groupService.DeleteUser(c.GetUserId(), groupId, userId) + return c.RenderRe(re) +} diff --git a/app/controllers/member/init.go b/app/controllers/member/init.go index 2737265..d891db2 100644 --- a/app/controllers/member/init.go +++ b/app/controllers/member/init.go @@ -9,6 +9,7 @@ import ( ) var userService *service.UserService +var groupService *service.GroupService var noteService *service.NoteService var trashService *service.TrashService var notebookService *service.NotebookService @@ -106,6 +107,7 @@ func InitService() { trashService = service.TrashS shareService = service.ShareS userService = service.UserS + groupService = service.GroupS tagService = service.TagS blogService = service.BlogS tokenService = service.TokenS diff --git a/app/info/BlogCustom.go b/app/info/BlogCustom.go index 0da02b8..c309c21 100644 --- a/app/info/BlogCustom.go +++ b/app/info/BlogCustom.go @@ -23,6 +23,8 @@ type BlogInfoCustom struct { type Post struct { NoteId string Title string + UrlTitle string + ImgSrc string CreatedTime time.Time UpdatedTime time.Time PublicTime time.Time diff --git a/app/info/BlogInfo.go b/app/info/BlogInfo.go index 68eaef3..24dafae 100644 --- a/app/info/BlogInfo.go +++ b/app/info/BlogInfo.go @@ -74,9 +74,10 @@ type BlogStat struct { // 单页 type BlogSingle struct { - SingleId bson.ObjectId `bson:"_id"` + SingleId bson.ObjectId `bson:"_id,omitempty"` UserId bson.ObjectId `UserId` Title string `Title` + UrlTitle string `UrlTitle` // 2014/11/11 Content string `Content` UpdatedTime time.Time `UpdatedTime` CreatedTime time.Time `CreatedTime` @@ -87,7 +88,7 @@ type BlogSingle struct { // 点赞记录 type BlogLike struct { - LikeId bson.ObjectId `bson:"_id"` + LikeId bson.ObjectId `bson:"_id,omitempty"` NoteId bson.ObjectId `NoteId` UserId bson.ObjectId `UserId` CreatedTime time.Time `CreatedTime` @@ -95,7 +96,7 @@ type BlogLike struct { // 评论 type BlogComment struct { - CommentId bson.ObjectId `bson:"_id"` + CommentId bson.ObjectId `bson:"_id,omitempty"` NoteId bson.ObjectId `NoteId` UserId bson.ObjectId `UserId` // UserId回复ToUserId @@ -114,3 +115,14 @@ type BlogCommentPublic struct { BlogComment IsILikeIt bool } + +type BlogUrls struct { + IndexUrl string + CateUrl string + SearchUrl string + SingleUrl string + PostUrl string + ArchiveUrl string + TagsUrl string + TagPostsUrl string +} diff --git a/app/info/GroupInfo.go b/app/info/GroupInfo.go new file mode 100644 index 0000000..e75b352 --- /dev/null +++ b/app/info/GroupInfo.go @@ -0,0 +1,25 @@ +package info + +import ( + "gopkg.in/mgo.v2/bson" + "time" +) + +// 分组 +type Group struct { + GroupId bson.ObjectId `bson:"_id"` // 谁的 + UserId bson.ObjectId `UserId` // 所有者Id + Title string `Title` // 标题 + UserCount int `UserCount` // 用户数 + CreatedTime time.Time `CreatedTime` + + Users []User `Users,omitempty` // 分组下的用户, 不保存, 仅查看 +} + +// 分组好友 +type GroupUser struct { + GroupUserId bson.ObjectId `bson:"_id"` // 谁的 + GroupId bson.ObjectId `GroupId` // 分组 + UserId bson.ObjectId `UserId` // 用户 + CreatedTime time.Time `CreatedTime` +} diff --git a/app/info/NoteInfo.go b/app/info/NoteInfo.go index e8560e0..a1bce49 100644 --- a/app/info/NoteInfo.go +++ b/app/info/NoteInfo.go @@ -20,9 +20,11 @@ type Note struct { IsTrash bool `IsTrash` // 是否是trash, 默认是false - IsBlog bool `IsBlog,omitempty` // 是否设置成了blog 2013/12/29 新加 - IsRecommend bool `IsRecommend,omitempty` // 是否为推荐博客 2014/9/24新加 - IsTop bool `IsTop,omitempty` // blog是否置顶 + IsBlog bool `IsBlog,omitempty` // 是否设置成了blog 2013/12/29 新加 + UrlTitle string `UrlTitle,omitempty` // 博客的url标题, 为了更友好的url, 在UserId, UrlName下唯一 + IsRecommend bool `IsRecommend,omitempty` // 是否为推荐博客 2014/9/24新加 + IsTop bool `IsTop,omitempty` // blog是否置顶 + HasSelfDefined bool `HasSelfDefined` // 是否已经自定义博客图片, desc, abstract // 2014/9/28 添加评论社交功能 ReadNum int `ReadNum,omitempty` // 阅读次数 2014/9/28 @@ -35,9 +37,9 @@ type Note struct { CreatedTime time.Time `CreatedTime` UpdatedTime time.Time `UpdatedTime` - RecommendTime time.Time `RecommendTime,omitempty` // 推荐时间 - PublicTime time.Time `PublicTime,omitempty` // 发表时间, 公开为博客则设置 - UpdatedUserId bson.ObjectId `bson:"UpdatedUserId"` // 如果共享了, 并可写, 那么可能是其它他修改了 + RecommendTime time.Time `RecommendTime,omitempty` // 推荐时间 + PublicTime time.Time `PublicTime,omitempty` // 发表时间, 公开为博客则设置 + UpdatedUserId bson.ObjectId `bson:"UpdatedUserId"` // 如果共享了, 并可写, 那么可能是其它他修改了 } // 内容 diff --git a/app/info/NotebookInfo.go b/app/info/NotebookInfo.go index 8275c9f..8d0db19 100644 --- a/app/info/NotebookInfo.go +++ b/app/info/NotebookInfo.go @@ -13,6 +13,7 @@ type Notebook struct { ParentNotebookId bson.ObjectId `bson:"ParentNotebookId,omitempty"` // 上级 Seq int `Seq` // 排序 Title string `Title` // 标题 + UrlTitle string `UrlTitle` // Url标题 2014/11.11加 NumberNotes int `NumberNotes` // 笔记数 IsTrash bool `IsTrash,omitempty` // 是否是trash, 默认是false IsBlog bool `IsBlog,omitempty` // 是否是Blog 2013/12/29 新加 diff --git a/app/info/ShareNotebookNoteInfo.go b/app/info/ShareNotebookNoteInfo.go index dfea67b..401b720 100644 --- a/app/info/ShareNotebookNoteInfo.go +++ b/app/info/ShareNotebookNoteInfo.go @@ -76,7 +76,9 @@ type SharingNotebookAndNotes struct { type ShareNotebook struct { ShareNotebookId bson.ObjectId `bson:"_id,omitempty"` // 必须要设置bson:"_id" 不然mgo不会认为是主键 UserId bson.ObjectId `bson:"UserId"` - ToUserId bson.ObjectId `bson:"ToUserId"` + ToUserId bson.ObjectId `bson:"ToUserId,omitempty"` + ToGroupId bson.ObjectId `bson:"ToGroupId,omitempty"` // 分享给的用户组 + ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息 NotebookId bson.ObjectId `bson:"NotebookId"` Seq int `bson:"Seq"` // 排序 Perm int `bson:"Perm"` // 权限, 其下所有notes 0只读, 1可修改 @@ -134,7 +136,9 @@ type ShareNotebooksByUser struct { type ShareNote struct { ShareNoteId bson.ObjectId `bson:"_id,omitempty"` // 必须要设置bson:"_id" 不然mgo不会认为是主键 UserId bson.ObjectId `bson:"UserId"` - ToUserId bson.ObjectId `bson:"ToUserId"` + ToUserId bson.ObjectId `bson:"ToUserId,omitempty"` + ToGroupId bson.ObjectId `bson:"ToGroupId,omitempty"` // 分享给的用户组 + ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息 NoteId bson.ObjectId `bson:"NoteId"` Perm int `bson:"Perm"` // 权限, 0只读, 1可修改 CreatedTime time.Time `CreatedTime` diff --git a/app/info/UserInfo.go b/app/info/UserInfo.go index 8a406d5..7d4e49d 100644 --- a/app/info/UserInfo.go +++ b/app/info/UserInfo.go @@ -74,5 +74,7 @@ type UserAndBlog struct { Logo string `Logo` BlogTitle string `BlogTitle` // 博客标题 BlogLogo string `BlogLogo` // 博客Logo - BlogUrl string `BlogUrl` // 博客链接 + BlogUrl string `BlogUrl` // 博客链接, 主页 + + BlogUrls // 各个页面 } diff --git a/app/info/common.go b/app/info/common.go index 3ea4521..25ef0e0 100644 --- a/app/info/common.go +++ b/app/info/common.go @@ -9,6 +9,7 @@ import ( type Page struct { CurPage int // 当前页码 TotalPage int // 总页 + PerPageSize int Count int // 总记录数 List interface{} } @@ -18,5 +19,5 @@ func NewPage(page, perPageSize, count int, list interface{}) Page { if count > 0 { totalPage = int(math.Ceil(float64(count) / float64(perPageSize))) } - return Page{page, totalPage, count, list} -} \ No newline at end of file + return Page{page, totalPage, perPageSize, count, list} +} diff --git a/app/init.go b/app/init.go index f491511..a0cb922 100644 --- a/app/init.go +++ b/app/init.go @@ -20,6 +20,7 @@ import ( "strconv" "time" "encoding/json" + "net/url" ) func init() { @@ -78,6 +79,10 @@ func init() { } return str } + revel.TemplateFuncs["decodeUrlValue"] = func(i string) string { + v, _ := url.ParseQuery("a=" + i) + return v.Get("a") + } revel.TemplateFuncs["json"] = func(i interface{}) string { b, _ := json.Marshal(i) return string(b) @@ -318,4 +323,4 @@ func init() { member.InitService() service.ConfigS.InitGlobalConfigs() }) -} \ No newline at end of file +} diff --git a/app/service/AuthService.go b/app/service/AuthService.go index 1d4e66a..6e4fd24 100644 --- a/app/service/AuthService.go +++ b/app/service/AuthService.go @@ -35,7 +35,7 @@ func (this *AuthService) Login(emailOrUsername, pwd string) info.User { func (this *AuthService) Register(email, pwd string) (bool, string) { // 用户是否已存在 if userService.IsExistsUser(email) { - return false, email + " 已被注册" + return false, "userHasBeenRegistered-" + email } user := info.User{UserId: bson.NewObjectId(), Email: email, Username: email, Pwd: Md5(pwd)} return this.register(user) @@ -90,7 +90,10 @@ func (this *AuthService) register(user info.User) (bool, string) { Title: user.Username + " 's Blog", SubTitle: "love leanote!", AboutMe: "Hello, I am (^_^)", + CanComment: true, }) + // 添加一个单页面 + blogService.AddOrUpdateSingle(user.UserId.Hex(), "", "About Me", "Hello, I am (^_^)") } return true, "" diff --git a/app/service/BlogService.go b/app/service/BlogService.go index 33a2105..789a519 100644 --- a/app/service/BlogService.go +++ b/app/service/BlogService.go @@ -1,16 +1,15 @@ package service import ( - "github.com/leanote/leanote/app/info" "github.com/leanote/leanote/app/db" + "github.com/leanote/leanote/app/info" . "github.com/leanote/leanote/app/lea" -// "github.com/leanote/leanote/app/lea/netutil" "gopkg.in/mgo.v2/bson" -// "time" -// "sort" + // "time" + // "sort" + "strconv" "strings" "time" - "strconv" ) // blog @@ -39,20 +38,33 @@ func (this *BlogService) GetBlogStat(noteId string) (stat info.BlogStat) { stat = info.BlogStat{note.NoteId, note.ReadNum, note.LikeNum, note.CommentNum} return } + +// 通过id或urlTitle得到博客 +func (this *BlogService) GetBlogByIdAndUrlTitle(userId string, noteIdOrUrlTitle string) (blog info.BlogItem) { + if IsObjectId(noteIdOrUrlTitle) { + return this.GetBlog(noteIdOrUrlTitle) + } + note := info.Note{} + db.GetByQ(db.Notes, bson.M{"UserId": bson.ObjectIdHex(userId), "UrlTitle": encodeValue(noteIdOrUrlTitle), "IsBlog": true, "IsTrash": false}, ¬e) + return this.GetBlogItem(note) +} + // 得到某博客具体信息 func (this *BlogService) GetBlog(noteId string) (blog info.BlogItem) { note := noteService.GetBlogNote(noteId) - + return this.GetBlogItem(note) +} +func (this *BlogService) GetBlogItem(note info.Note) (blog info.BlogItem) { if note.NoteId == "" || !note.IsBlog { return } - + // 内容 noteContent := noteService.GetNoteContent(note.NoteId.Hex(), note.UserId.Hex()) - + // 组装成blogItem - blog = info.BlogItem{note, noteContent.Abstract, noteContent.Content, false, info.User{}} - + blog = info.BlogItem{note, noteContent.Abstract, noteContent.Content, false, info.User{}} + return } @@ -66,18 +78,18 @@ func (this *BlogService) ListBlogNotebooks(userId string) []info.Notebook { // 博客列表 // userId 表示谁的blog func (this *BlogService) ListBlogs(userId, notebookId string, page, pageSize int, sortField string, isAsc bool) (info.Page, []info.BlogItem) { - count, notes := noteService.ListNotes(userId, notebookId, false, page, pageSize, sortField, isAsc, true); - - if(notes == nil || len(notes) == 0) { + count, notes := noteService.ListNotes(userId, notebookId, false, page, pageSize, sortField, isAsc, true) + + if notes == nil || len(notes) == 0 { return info.Page{}, 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] @@ -85,7 +97,7 @@ func (this *BlogService) ListBlogs(userId, notebookId string, page, pageSize int for _, noteContent := range noteContents { noteContentsMap[noteContent.NoteId] = noteContent } - + // 组装成blogItem // 按照notes的顺序 blogs := make([]info.BlogItem, len(noteIds)) @@ -99,9 +111,9 @@ func (this *BlogService) ListBlogs(userId, notebookId string, page, pageSize int } blogs[i] = info.BlogItem{note, abstract, content, hasMore, info.User{}} } - + pageInfo := info.NewPage(page, pageSize, count, nil) - + return pageInfo, blogs } @@ -111,25 +123,26 @@ func (this *BlogService) ListBlogs(userId, notebookId string, page, pageSize int {Tag:xxx, Count: 32} ] */ -func (this *BlogService) GetBlogTags(userId string) ([]info.TagCount) { +func (this *BlogService) GetBlogTags(userId string) []info.TagCount { // 得到所有博客 tagCounts := []info.TagCount{} query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsBlog": true} db.TagCounts.Find(query).Sort("-Count").All(&tagCounts) return tagCounts } + // 重新计算博客的标签 -// 在设置设置/取消为博客时调用 -func (this *BlogService) ReCountBlogTags(userId string) (bool) { +// 在设置设置/取消为博客时调用 +func (this *BlogService) ReCountBlogTags(userId string) bool { // 得到所有博客 notes := []info.Note{} userIdO := bson.ObjectIdHex(userId) query := bson.M{"UserId": userIdO, "IsTrash": false, "IsBlog": true} db.ListByQWithFields(db.Notes, query, []string{"Tags"}, ¬es) - - db.DeleteAll(db.TagCounts, bson.M{"UserId": userIdO, "IsBlog": true}); - if(notes == nil || len(notes) == 0) { - return true + + db.DeleteAll(db.TagCounts, bson.M{"UserId": userIdO, "IsBlog": true}) + if notes == nil || len(notes) == 0 { + return true } // 统计所有的Tags和数目 tagsCount := map[string]int{} @@ -145,11 +158,12 @@ func (this *BlogService) ReCountBlogTags(userId string) (bool) { } // 一个个插入 for tag, count := range tagsCount { - db.Insert(db.TagCounts, + db.Insert(db.TagCounts, info.TagCount{UserId: userIdO, IsBlog: true, Tag: tag, Count: count}) } return true } + // 归档博客 /* 数据: 按年汇总 @@ -157,14 +171,14 @@ func (this *BlogService) ReCountBlogTags(userId string) (bool) { archive1, archive2, ] -archive的数据类型是 +archive的数据类型是 { Year: 2014 Posts: [] } */ -func (this *BlogService) ListBlogsArchive(userId, notebookId string, year, month int, sortField string, isAsc bool) ([]info.Archive) { -// _, notes := noteService.ListNotes(userId, notebookId, false, 1, 99999, sortField, isAsc, true); +func (this *BlogService) ListBlogsArchive(userId, notebookId string, year, month int, sortField string, isAsc bool) []info.Archive { + // _, notes := noteService.ListNotes(userId, notebookId, false, 1, 99999, sortField, isAsc, true); q := bson.M{"UserId": bson.ObjectIdHex(userId), "IsBlog": true, "IsTrash": false} if notebookId != "" { q["NotebookId"] = bson.ObjectIdHex(notebookId) @@ -192,18 +206,18 @@ func (this *BlogService) ListBlogsArchive(userId, notebookId string, year, month q["PublicTime"] = bson.M{"$gte": leftT, "$lt": rightT} } } - + sorter := sortField if !isAsc { sorter = "-" + sortField } notes := []info.Note{} db.Notes.Find(q).Sort(sorter).All(¬es) - - if(notes == nil || len(notes) == 0) { + + if notes == nil || len(notes) == 0 { return nil } - + arcs := []info.Archive{} // 按年汇总 arcsMap := map[int]info.Archive{} @@ -225,41 +239,31 @@ func (this *BlogService) ListBlogsArchive(userId, notebookId string, year, month if everYear == 0 { everYear = year } - + if everYear != year { yearArc := arcsMap[everYear] yearArc.MonthAchives = arcsMonth arcs = append(arcs, yearArc) everYear = year - + // 新的一年 arcsMonth = []info.ArchiveMonth{} } - + if arcT, ok := arcsMap[year]; ok { arc = arcT } else { arc = info.Archive{Year: year, Posts: []*info.Post{}} } - p := &info.Post{ - NoteId: note.NoteId.Hex(), - Title: note.Title, - CreatedTime: note.CreatedTime, - UpdatedTime: note.UpdatedTime, - PublicTime: note.PublicTime, - Desc: note.Desc, - Tags: note.Tags, - CommentNum: note.CommentNum, - ReadNum: note.ReadNum, - LikeNum: note.LikeNum, - IsMarkdown: note.IsMarkdown, - } - arc.Posts = append(arc.Posts, p); + + pt := this.FixNote(note) + p := &pt + arc.Posts = append(arc.Posts, p) arcsMap[year] = arc - + // month lm := len(arcsMonth) - if(lm == 0 || arcsMonth[lm-1].Month != month) { + if lm == 0 || arcsMonth[lm-1].Month != month { arcsMonth = append(arcsMonth, info.ArchiveMonth{month, []*info.Post{p}}) } else { arcsMonth[lm-1].Posts = append(arcsMonth[lm-1].Posts, p) @@ -271,7 +275,7 @@ func (this *BlogService) ListBlogsArchive(userId, notebookId string, year, month yearArc.MonthAchives = arcsMonth arcs = append(arcs, yearArc) } - + return arcs } @@ -279,39 +283,39 @@ func (this *BlogService) ListBlogsArchive(userId, notebookId string, year, month func (this *BlogService) SearchBlogByTags(tags []string, userId string, pageNumber, pageSize int, sortField string, isAsc bool) (pageInfo info.Page, blogs []info.BlogItem) { notes := []info.Note{} skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc) - + // 不是trash的 - query := bson.M{"UserId": bson.ObjectIdHex(userId), - "IsTrash": false, - "IsBlog": true, - "Tags": bson.M{"$all": tags}} - - q := db.Notes.Find(query); - + query := bson.M{"UserId": bson.ObjectIdHex(userId), + "IsTrash": false, + "IsBlog": true, + "Tags": bson.M{"$all": tags}} + + q := db.Notes.Find(query) + // 总记录数 count, _ := q.Count() if count == 0 { return } - + q.Sort(sortFieldR). Skip(skipNum). Limit(pageSize). All(¬es) - + blogs = this.notes2BlogItems(notes) pageInfo = info.NewPage(pageNumber, pageSize, count, nil) - + return } -func (this *BlogService) notes2BlogItems(notes []info.Note) []info.BlogItem{ +func (this *BlogService) notes2BlogItems(notes []info.Note) []info.BlogItem { // 得到content, 并且每个都要substring noteIds := make([]bson.ObjectId, len(notes)) for i, note := range notes { noteIds[i] = note.NoteId } - + // 直接得到noteContents表的abstract // 这里可能是乱序的 noteContents := noteService.ListNoteContentByNoteIds(noteIds) // 返回[info.NoteContent] @@ -319,7 +323,7 @@ func (this *BlogService) notes2BlogItems(notes []info.Note) []info.BlogItem{ for _, noteContent := range noteContents { noteContentsMap[noteContent.NoteId] = noteContent } - + // 组装成blogItem // 按照notes的顺序 blogs := make([]info.BlogItem, len(noteIds)) @@ -335,12 +339,12 @@ func (this *BlogService) notes2BlogItems(notes []info.Note) []info.BlogItem{ return blogs } func (this *BlogService) SearchBlog(key, userId string, page, pageSize int, sortField string, isAsc bool) (info.Page, []info.BlogItem) { - count, notes := noteService.SearchNote(key, userId, page, pageSize, sortField, isAsc, true); - - if(notes == nil || len(notes) == 0) { + count, notes := noteService.SearchNote(key, userId, page, pageSize, sortField, isAsc, true) + + if notes == nil || len(notes) == 0 { return info.Page{}, nil } - + blogs := this.notes2BlogItems(notes) pageInfo := info.NewPage(page, pageSize, count, nil) return pageInfo, blogs @@ -349,18 +353,18 @@ func (this *BlogService) SearchBlog(key, userId string, page, pageSize int, sort // 上一篇文章, 下一篇文章 // sorterField, baseTime是基准, sorterField=PublicTime, title // isAsc是用户自定义的排序方式 -func (this *BlogService) PreNextBlog(userId string, sorterField string, isAsc bool, baseTime interface{}) (info.Note, info.Note) { +func (this *BlogService) PreNextBlog(userId string, sorterField string, isAsc bool, baseTime interface{}) (info.Post, info.Post) { userIdO := bson.ObjectIdHex(userId) - + var sortFieldT1, sortFieldT2 bson.M var sortFieldR1, sortFieldR2 string if !isAsc { // 降序 /* -------- pre ------ now ---- next --- + ------- pre + ----- now + --- next + -- */ // 上一篇时间要比它大, 找最小的 sortFieldT1 = bson.M{"$gt": baseTime} @@ -370,12 +374,12 @@ func (this *BlogService) PreNextBlog(userId string, sorterField string, isAsc bo sortFieldR2 = "-" + sorterField } else { // 升序 -/* ---- pre ------ now -------- next ---------- -*/ + /* + --- pre + ----- now + ------- next + --------- + */ // 上一篇要比它小, 找最大的 sortFieldT1 = bson.M{"$lt": baseTime} sortFieldR1 = "-" + sorterField @@ -383,68 +387,71 @@ func (this *BlogService) PreNextBlog(userId string, sorterField string, isAsc bo sortFieldT2 = bson.M{"$gt": baseTime} sortFieldR2 = sorterField } - + // 上一篇, 比基时间要小, 但是是最后一篇, 所以是降序 note := info.Note{} - query := bson.M{"UserId": userIdO, "IsTrash": false, "IsBlog": true, + query := bson.M{"UserId": userIdO, "IsTrash": false, "IsBlog": true, sorterField: sortFieldT1, } - q := db.Notes.Find(query); + q := db.Notes.Find(query) q.Sort(sortFieldR1).Limit(1).One(¬e) // 下一篇, 比基时间要大, 但是是第一篇, 所以是升序 note2 := info.Note{} query[sorterField] = sortFieldT2 -// Log(isAsc) -// LogJ(query) -// Log(sortFieldR2) - q = db.Notes.Find(query); + // Log(isAsc) + // LogJ(query) + // Log(sortFieldR2) + q = db.Notes.Find(query) q.Sort(sortFieldR2).Limit(1).One(¬e2) - - return note, note2 + + return this.FixNote(note), this.FixNote(note2) } //------- // p // 平台 lea+ // 博客列表 -func (this *BlogService) ListAllBlogs(tag string, keywords string, isRecommend bool, page, pageSize int, sorterField string, isAsc bool) (info.Page, []info.BlogItem) { +func (this *BlogService) ListAllBlogs(userId, tag string, keywords string, isRecommend bool, page, pageSize int, sorterField string, isAsc bool) (info.Page, []info.BlogItem) { pageInfo := info.Page{CurPage: page} notes := []info.Note{} - + skipNum, sortFieldR := parsePageAndSort(page, pageSize, sorterField, isAsc) - + // 不是trash的 - query := bson.M{"IsTrash": false, "IsBlog": true, "Title": bson.M{"$ne":"欢迎来到leanote!"}} + query := bson.M{"IsTrash": false, "IsBlog": true, "Title": bson.M{"$ne": "欢迎来到leanote!"}} if tag != "" { query["Tags"] = bson.M{"$in": []string{tag}} } + if userId != "" { + query["UserId"] = bson.ObjectIdHex(userId) + } // 不是demo的博客 demoUserId := configService.GetGlobalStringConfig("demoUserId") - if demoUserId != "" { + if userId == "" && demoUserId != "" { query["UserId"] = bson.M{"$ne": bson.ObjectIdHex(demoUserId)} } - + if isRecommend { query["IsRecommend"] = isRecommend } if keywords != "" { query["Title"] = bson.M{"$regex": bson.RegEx{".*?" + keywords + ".*", "i"}} } - q := db.Notes.Find(query); - + q := db.Notes.Find(query) + // 总记录数 count, _ := q.Count() - + q.Sort(sortFieldR). Skip(skipNum). Limit(pageSize). All(¬es) - - if(notes == nil || len(notes) == 0) { + + if notes == nil || len(notes) == 0 { return pageInfo, nil } - + // 得到content, 并且每个都要substring noteIds := make([]bson.ObjectId, len(notes)) userIds := make([]bson.ObjectId, len(notes)) @@ -452,21 +459,21 @@ func (this *BlogService) ListAllBlogs(tag string, keywords string, isRecommend b noteIds[i] = note.NoteId userIds[i] = note.UserId } - + // 可以不要的 // 直接得到noteContents表的abstract // 这里可能是乱序的 /* - noteContents := noteService.ListNoteAbstractsByNoteIds(noteIds) // 返回[info.NoteContent] - noteContentsMap := make(map[bson.ObjectId]info.NoteContent, len(noteContents)) - for _, noteContent := range noteContents { - noteContentsMap[noteContent.NoteId] = noteContent - } + noteContents := noteService.ListNoteAbstractsByNoteIds(noteIds) // 返回[info.NoteContent] + noteContentsMap := make(map[bson.ObjectId]info.NoteContent, len(noteContents)) + for _, noteContent := range noteContents { + noteContentsMap[noteContent.NoteId] = noteContent + } */ - + // 得到用户信息 userMap := userService.MapUserInfoAndBlogInfosByUserIds(userIds) - + // 组装成blogItem // 按照notes的顺序 blogs := make([]info.BlogItem, len(noteIds)) @@ -474,18 +481,17 @@ func (this *BlogService) ListAllBlogs(tag string, keywords string, isRecommend b hasMore := true var content string /* - if noteContent, ok := noteContentsMap[note.NoteId]; ok { - content = noteContent.Abstract - } + if noteContent, ok := noteContentsMap[note.NoteId]; ok { + content = noteContent.Abstract + } */ blogs[i] = info.BlogItem{note, "", content, hasMore, userMap[note.UserId]} } pageInfo = info.NewPage(page, pageSize, count, nil) - + return pageInfo, blogs } - //------------------------ // 博客设置 func (this *BlogService) fixUserBlog(userBlog *info.UserBlog) { @@ -494,14 +500,14 @@ func (this *BlogService) fixUserBlog(userBlog *info.UserBlog) { userBlog.Logo = strings.Trim(userBlog.Logo, "/") userBlog.Logo = configService.GetSiteUrl() + "/" + userBlog.Logo } - + if userBlog.SortField == "" { userBlog.SortField = "PublicTime" } if userBlog.PerPageSize <= 0 { userBlog.PerPageSize = 10 } - + // themePath if userBlog.Style == "" { userBlog.Style = defaultStyle @@ -523,6 +529,7 @@ func (this *BlogService) GetUserBlog(userId string) info.UserBlog { func (this *BlogService) UpdateUserBlog(userBlog info.UserBlog) bool { return db.Upsert(db.UserBlogs, bson.M{"_id": userBlog.UserId}, userBlog) } + // 修改之UserBlogBase func (this *BlogService) UpdateUserBlogBase(userId string, userBlog info.UserBlogBase) bool { ok := db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, userBlog) @@ -534,12 +541,13 @@ func (this *BlogService) UpdateUserBlogComment(userId string, userBlog info.User func (this *BlogService) UpdateUserBlogStyle(userId string, userBlog info.UserBlogStyle) bool { return db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, userBlog) } -// 分页与排序 + +// 分页与排序 func (this *BlogService) UpdateUserBlogPaging(userId string, perPageSize int, sortField string, isAsc bool) (ok bool, msg string) { if ok, msg = Vds(map[string]string{"perPageSize": strconv.Itoa(perPageSize), "sortField": sortField}); !ok { return } - ok = db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, + ok = db.UpdateByQMap(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, bson.M{"PerPageSize": perPageSize, "SortField": sortField, "IsAsc": isAsc}) return } @@ -577,23 +585,23 @@ func (this *BlogService) ListLikedUsers(noteId string, isAll bool) ([]info.UserA // 默认前5 pageSize := 5 skipNum, sortFieldR := parsePageAndSort(1, pageSize, "CreatedTime", false) - + likes := []info.BlogLike{} query := bson.M{"NoteId": bson.ObjectIdHex(noteId)} - q := db.BlogLikes.Find(query); - + q := db.BlogLikes.Find(query) + // 总记录数 count, _ := q.Count() if count == 0 { return nil, false } - + if isAll { q.Sort(sortFieldR).Skip(skipNum).Limit(pageSize).All(&likes) } else { q.Sort(sortFieldR).All(&likes) } - + // 得到所有userIds userIds := make([]bson.ObjectId, len(likes)) for i, like := range likes { @@ -601,12 +609,12 @@ func (this *BlogService) ListLikedUsers(noteId string, isAll bool) ([]info.UserA } // 得到用户信息 userMap := userService.MapUserAndBlogByUserIds(userIds) - - users := make([]info.UserAndBlog, len(likes)); + + users := make([]info.UserAndBlog, len(likes)) for i, like := range likes { users[i] = userMap[like.UserId.Hex()] } - + return users, count > pageSize } @@ -635,14 +643,14 @@ func (this *BlogService) LikeBlog(noteId, userId string) (ok bool, isLike bool) ok = false isLike = false if noteId == "" || userId == "" { - return + return } // 判断是否点过赞, 如果点过那么取消点赞 note := noteService.GetNoteById(noteId) - if !note.IsBlog /*|| note.UserId.Hex() == userId */{ - return + if !note.IsBlog /*|| note.UserId.Hex() == userId */ { + return } - + noteIdO := bson.ObjectIdHex(noteId) userIdO := bson.ObjectIdHex(userId) var n int @@ -658,7 +666,7 @@ func (this *BlogService) LikeBlog(noteId, userId string) (ok bool, isLike bool) isLike = false } ok = db.Update(db.Notes, bson.M{"_id": noteIdO}, bson.M{"$inc": bson.M{"LikeNum": n}}) - + return } @@ -670,16 +678,16 @@ func (this *BlogService) Comment(noteId, toCommentId, userId, content string) (b if content == "" { return false, comment } - + note := noteService.GetNoteById(noteId) if !note.IsBlog { return false, comment } - comment = info.BlogComment{CommentId: bson.NewObjectId(), - NoteId: bson.ObjectIdHex(noteId), - UserId: bson.ObjectIdHex(userId), - Content: content, + comment = info.BlogComment{CommentId: bson.NewObjectId(), + NoteId: bson.ObjectIdHex(noteId), + UserId: bson.ObjectIdHex(userId), + Content: content, CreatedTime: time.Now(), } var comment2 = info.BlogComment{} @@ -698,44 +706,44 @@ func (this *BlogService) Comment(noteId, toCommentId, userId, content string) (b // 评论+1 db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"CommentNum": 1}}) } - + if userId != note.UserId.Hex() || toCommentId != "" { go func() { - this.sendEmail(note, comment2, userId, content); + this.sendEmail(note, comment2, userId, content) }() } - + return ok, comment } // 发送email func (this *BlogService) sendEmail(note info.Note, comment info.BlogComment, userId, content string) { - emailService.SendCommentEmail(note, comment, userId, content); + emailService.SendCommentEmail(note, comment, userId, content) /* - toUserId := note.UserId.Hex() - // title := "评论提醒" - - // 表示回复回复的内容, 那么发送给之前回复的 - if comment.CommentId != "" { - toUserId = comment.UserId.Hex() - } - toUserInfo := userService.GetUserInfo(toUserId) - sendUserInfo := userService.GetUserInfo(userId) - - subject := note.Title + " 收到 " + sendUserInfo.Username + " 的评论"; - if comment.CommentId != "" { - subject = "您在 " + note.Title + " 发表的评论收到 " + sendUserInfo.Username; - if userId == note.UserId.Hex() { - subject += "(作者)"; - } - subject += " 的评论"; - } + toUserId := note.UserId.Hex() + // title := "评论提醒" - body := "{header}评论内容:
" + content + "
"; - href := "http://"+ configService.GetBlogDomain() + "/view/" + note.NoteId.Hex() - body += "
博客链接: " + href + "{footer}"; - - emailService.SendEmail(toUserInfo.Email, subject, body) + // 表示回复回复的内容, 那么发送给之前回复的 + if comment.CommentId != "" { + toUserId = comment.UserId.Hex() + } + toUserInfo := userService.GetUserInfo(toUserId) + sendUserInfo := userService.GetUserInfo(userId) + + subject := note.Title + " 收到 " + sendUserInfo.Username + " 的评论"; + if comment.CommentId != "" { + subject = "您在 " + note.Title + " 发表的评论收到 " + sendUserInfo.Username; + if userId == note.UserId.Hex() { + subject += "(作者)"; + } + subject += " 的评论"; + } + + body := "{header}评论内容:
" + content + "
"; + href := "http://"+ configService.GetBlogDomain() + "/view/" + note.NoteId.Hex() + body += "
博客链接: " + href + "{footer}"; + + emailService.SendEmail(toUserInfo.Email, subject, body) */ } @@ -746,22 +754,22 @@ func (this *BlogService) DeleteComment(noteId, commentId, userId string) bool { if !note.IsBlog { return false } - + comment := info.BlogComment{} db.Get(db.BlogComments, commentId, &comment) - + if comment.CommentId == "" { return false } - + if userId == configService.GetAdminUserId() || note.UserId.Hex() == userId || comment.UserId.Hex() == userId { - if db.Delete(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}) { + if db.Delete(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}) { // 评论-1 db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"CommentNum": -1}}) return true - } + } } - + return false } @@ -771,33 +779,33 @@ func (this *BlogService) LikeComment(commentId, userId string) (ok bool, isILike isILike = false num = 0 comment := info.BlogComment{} - + db.Get(db.BlogComments, commentId, &comment) - + var n int if comment.LikeUserIds != nil && len(comment.LikeUserIds) > 0 && InArray(comment.LikeUserIds, userId) { n = -1 // 从点赞名单删除 - db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, - bson.M{"$pull": bson.M{"LikeUserIds": userId}}) + db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, + bson.M{"$pull": bson.M{"LikeUserIds": userId}}) isILike = false } else { n = 1 // 添加之 - db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, + db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, bson.M{"$push": bson.M{"LikeUserIds": userId}}) isILike = true } - + if comment.LikeUserIds == nil { num = 0 } else { num = len(comment.LikeUserIds) + n } - - ok = db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, - bson.M{"$set": bson.M{"LikeNum": num}}) - + + ok = db.Update(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}, + bson.M{"$set": bson.M{"LikeNum": num}}) + return } @@ -806,22 +814,22 @@ func (this *BlogService) LikeComment(commentId, userId string) (ok bool, isILike // 还要获取用户信息 func (this *BlogService) ListComments(userId, noteId string, page, pageSize int) (info.Page, []info.BlogCommentPublic, map[string]info.UserAndBlog) { pageInfo := info.Page{CurPage: page} - + comments2 := []info.BlogComment{} - + skipNum, sortFieldR := parsePageAndSort(page, pageSize, "CreatedTime", false) - + query := bson.M{"NoteId": bson.ObjectIdHex(noteId)} - q := db.BlogComments.Find(query); - + q := db.BlogComments.Find(query) + // 总记录数 count, _ := q.Count() q.Sort(sortFieldR).Skip(skipNum).Limit(pageSize).All(&comments2) - - if(len(comments2) == 0) { + + if len(comments2) == 0 { return pageInfo, nil, nil } - + comments := make([]info.BlogCommentPublic, len(comments2)) // 我是否点过赞呢? for i, comment := range comments2 { @@ -830,9 +838,9 @@ func (this *BlogService) ListComments(userId, noteId string, page, pageSize int) comments[i].IsILikeIt = true } } - - note := noteService.GetNoteById(noteId); - + + note := noteService.GetNoteById(noteId) + // 得到用户信息 userIdsMap := map[bson.ObjectId]bool{note.UserId: true} for _, comment := range comments { @@ -847,25 +855,25 @@ func (this *BlogService) ListComments(userId, noteId string, page, pageSize int) userIds[i] = userId i++ } - + // 得到用户信息 userMap := userService.MapUserAndBlogByUserIds(userIds) pageInfo = info.NewPage(page, pageSize, count, nil) - + return pageInfo, comments, userMap } // 举报 -func (this *BlogService) Report(noteId, commentId, reason, userId string) (bool) { +func (this *BlogService) Report(noteId, commentId, reason, userId string) bool { note := noteService.GetNoteById(noteId) if !note.IsBlog { return false } - report := info.Report{ReportId: bson.NewObjectId(), - NoteId: bson.ObjectIdHex(noteId), - UserId: bson.ObjectIdHex(userId), - Reason: reason, + report := info.Report{ReportId: bson.NewObjectId(), + NoteId: bson.ObjectIdHex(noteId), + UserId: bson.ObjectIdHex(userId), + Reason: reason, CreatedTime: time.Now(), } if commentId != "" { @@ -878,14 +886,62 @@ func (this *BlogService) Report(noteId, commentId, reason, userId string) (bool) // 分类排序 // CateIds -func (this *BlogService) UpateCateIds(userId string, cateIds[] string) bool { +func (this *BlogService) UpateCateIds(userId string, cateIds []string) bool { return db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "CateIds", cateIds) } +// 修改笔记本urlTitle +func (this *BlogService) UpateCateUrlTitle(userId string, cateId, urlTitle string) (ok bool, url string) { + url = urlTitle + /* + // 先清空 + ok = db.UpdateByIdAndUserIdMap(db.Notebooks, cateId, userId, bson.M{ + "UrlTitle": "", + }) + */ + url = GetUrTitle(userId, urlTitle, "notebook") + ok = db.UpdateByIdAndUserIdMap(db.Notebooks, cateId, userId, bson.M{ + "UrlTitle": url, + }) + // 返回给前端的是decode + url = decodeValue(url) + return +} + +// 修改笔记urlTitle +func (this *BlogService) UpateBlogUrlTitle(userId string, noteId, urlTitle string) (ok bool, url string) { + url = urlTitle + // 先清空 + ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{ + "UrlTitle": "", + }) + url = GetUrTitle(userId, urlTitle, "note") + ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{ + "UrlTitle": url, + }) + // 返回给前端的是decode + url = decodeValue(url) + return +} + +// 修改博客的图片, 描述, 摘要 +func (this *BlogService) UpateBlogAbstract(userId string, noteId, imgSrc, desc, abstract string) (ok bool) { + ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{ + "ImgSrc": imgSrc, + "Desc": desc, + "HasSelfDefined": true, + }) + ok = db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId, bson.M{ + "Abstract": abstract, + }) + return ok +} + // 单页 func (this *BlogService) GetSingles(userId string) []map[string]string { userBlog := this.GetUserBlog(userId) singles := userBlog.Singles + LogJ(singles) return singles } func (this *BlogService) GetSingle(singleId string) info.BlogSingle { @@ -893,8 +949,17 @@ func (this *BlogService) GetSingle(singleId string) info.BlogSingle { db.Get(db.BlogSingles, singleId, &page) return page } +func (this *BlogService) GetSingleByUserIdAndUrlTitle(userId, singleIdOrUrlTitle string) info.BlogSingle { + page := info.BlogSingle{} + if IsObjectId(singleIdOrUrlTitle) { + db.Get(db.BlogSingles, singleIdOrUrlTitle, &page) + } else { + db.GetByQ(db.BlogSingles, bson.M{"UserId": bson.ObjectIdHex(userId), "UrlTitle": encodeValue(singleIdOrUrlTitle)}, &page) + } + return page +} -func (this *BlogService) updateBlogSingles(userId string, isDelete bool, isAdd bool, singleId, title string) (ok bool) { +func (this *BlogService) updateBlogSingles(userId string, isDelete bool, isAdd bool, singleId, title, urlTitle string) (ok bool) { userBlog := this.GetUserBlog(userId) singles := userBlog.Singles if singles == nil { @@ -904,7 +969,7 @@ func (this *BlogService) updateBlogSingles(userId string, isDelete bool, isAdd b i := 0 for _, p := range singles { if p["SingleId"] == singleId { - break; + break } i++ } @@ -914,14 +979,20 @@ func (this *BlogService) updateBlogSingles(userId string, isDelete bool, isAdd b } else { // 找到了, 如果是删除, 则删除 if isDelete { - singles = append(singles[:i], singles[i+1:]...) + singles = append(singles[:i], singles[i+1:]...) } else { - singles[i]["Title"] = title + // 是更新 + if title != "" { + singles[i]["Title"] = title + } + if urlTitle != "" { + singles[i]["UrlTitle"] = urlTitle + } } } } else { // 是添加, 直接添加到最后 - singles = append(singles, map[string]string{"SingleId": singleId, "Title": title}) + singles = append(singles, map[string]string{"SingleId": singleId, "Title": title, "UrlTitle": urlTitle}) } return db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "Singles", singles) } @@ -931,36 +1002,64 @@ func (this *BlogService) DeleteSingle(userId, singleId string) (ok bool) { ok = db.DeleteByIdAndUserId(db.BlogSingles, singleId, userId) if ok { // 还要修改UserBlog中的Singles - this.updateBlogSingles(userId, true, false, singleId, "") + this.updateBlogSingles(userId, true, false, singleId, "", "") } return } + +// 修改urlTitle +func (this *BlogService) UpdateSingleUrlTitle(userId, singleId, urlTitle string) (ok bool, url string) { + url = urlTitle + /* + // 先清空 + ok = db.UpdateByIdAndUserIdMap(db.BlogSingles, singleId, userId, bson.M{ + "UrlTitle": "", + }) + */ + url = GetUrTitle(userId, urlTitle, "single") + ok = db.UpdateByIdAndUserIdMap(db.BlogSingles, singleId, userId, bson.M{ + "UrlTitle": url, + }) + if ok { + // 还要修改UserBlog中的Singles + this.updateBlogSingles(userId, false, false, singleId, "", url) + } + // 返回给前端的是decode + url = decodeValue(url) + return +} + // 更新或添加 func (this *BlogService) AddOrUpdateSingle(userId, singleId, title, content string) (ok bool) { ok = false if singleId != "" { ok = db.UpdateByIdAndUserIdMap(db.BlogSingles, singleId, userId, bson.M{ - "Title": title, - "Content": content, + "Title": title, + "Content": content, "UpdatedTime": time.Now(), }) if ok { // 还要修改UserBlog中的Singles - this.updateBlogSingles(userId, false, false, singleId, title) + this.updateBlogSingles(userId, false, false, singleId, title, "") } - return + return } // 添加 - page := info.BlogSingle{SingleId: bson.NewObjectId(), UserId: bson.ObjectIdHex(userId), Title: title, Content: content, + page := info.BlogSingle{ + SingleId: bson.NewObjectId(), + UserId: bson.ObjectIdHex(userId), + Title: title, + Content: content, + UrlTitle: GetUrTitle(userId, title, "single"), CreatedTime: time.Now(), } page.UpdatedTime = page.CreatedTime ok = db.Insert(db.BlogSingles, page) - + // 还要修改UserBlog中的Singles - this.updateBlogSingles(userId, false, true, page.SingleId.Hex(), title) - - return + this.updateBlogSingles(userId, false, true, page.SingleId.Hex(), title, page.UrlTitle) + + return } // 重新排序 @@ -973,26 +1072,142 @@ func (this *BlogService) SortSingles(userId string, singleIds []string) (ok bool if singles == nil || len(singles) == 0 { return } - + singlesMap := map[string]map[string]string{} for _, page := range singles { singlesMap[page["SingleId"]] = page } - + singles2 := make([]map[string]string, len(singles)) for i, singleId := range singleIds { singles2[i] = singlesMap[singleId] } - + return db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "Singles", singles2) } // 得到用户的博客url -func (this *BlogService) GetUserBlogUrl(userBlog *info.UserBlog) (string) { +func (this *BlogService) GetUserBlogUrl(userBlog *info.UserBlog, username string) string { if userBlog.Domain != "" && configService.AllowCustomDomain() { return configService.GetUserUrl(userBlog.Domain) } else if userBlog.SubDomain != "" { return configService.GetUserSubUrl(userBlog.SubDomain) } - return configService.GetBlogUrl() + "/" + userBlog.UserId.Hex() + if username == "" { + username = userBlog.UserId.Hex() + } + return configService.GetBlogUrl() + "/" + username +} + +// 得到所有url +func (this *BlogService) GetBlogUrls(userBlog *info.UserBlog, userInfo *info.User) info.BlogUrls { + var indexUrl, postUrl, searchUrl, cateUrl, singleUrl, tagsUrl, archiveUrl, tagPostsUrl string + if userBlog.Domain != "" && configService.AllowCustomDomain() { // http://demo.com + // ok + indexUrl = configService.GetUserUrl(userBlog.Domain) + cateUrl = indexUrl + "/cate" // /xxxxx + postUrl = indexUrl + "/post" // /xxxxx + searchUrl = indexUrl + "/search" // /xxxxx + singleUrl = indexUrl + "/single" + archiveUrl = indexUrl + "/archives" + tagsUrl = indexUrl + "/tags" + tagPostsUrl = indexUrl + "/tag" + } else if userBlog.SubDomain != "" { // demo.leanote.com + indexUrl = configService.GetUserSubUrl(userBlog.SubDomain) + cateUrl = indexUrl + "/cate" // /xxxxx + postUrl = indexUrl + "/post" // /xxxxx + searchUrl = indexUrl + "/search" // /xxxxx + singleUrl = indexUrl + "/single" + archiveUrl = indexUrl + "/archives" + tagsUrl = indexUrl + "/tags" + tagPostsUrl = indexUrl + "/tag" + } else { + // ok + blogUrl := configService.GetBlogUrl() // blog.leanote.com + userIdOrEmail := "" + if userInfo.Username != "" { + userIdOrEmail = userInfo.Username + } else if userInfo.Email != "" { + userIdOrEmail = userInfo.Email + } else { + userIdOrEmail = userInfo.UserId.Hex() + } + indexUrl = blogUrl + "/" + userIdOrEmail + cateUrl = blogUrl + "/cate/" + userIdOrEmail // /username/notebookId + postUrl = blogUrl + "/post/" + userIdOrEmail // /username/xxxxx + searchUrl = blogUrl + "/search/" + userIdOrEmail // blog.leanote.com/search/username + singleUrl = blogUrl + "/single/" + userIdOrEmail // blog.leanote.com/single/username/singleId + archiveUrl = blogUrl + "/archives/" + userIdOrEmail // blog.leanote.com/archive/username + tagsUrl = blogUrl + "/tags/" + userIdOrEmail + tagPostsUrl = blogUrl + "/tag/" + userIdOrEmail // blog.leanote.com/archive/username + } + + return info.BlogUrls{ + IndexUrl: indexUrl, + CateUrl: cateUrl, + SearchUrl: searchUrl, + SingleUrl: singleUrl, + PostUrl: postUrl, + ArchiveUrl: archiveUrl, + TagsUrl: tagsUrl, + TagPostsUrl: tagPostsUrl, + } +} + +// 转成post +func (this *BlogService) FixBlogs(blogs []info.BlogItem) []info.Post { + blogs2 := make([]info.Post, len(blogs)) + for i, blog := range blogs { + blogs2[i] = this.FixBlog(blog) + } + return blogs2 +} +func (this *BlogService) FixBlog(blog info.BlogItem) info.Post { + urlTitle := blog.UrlTitle + if urlTitle == "" { + urlTitle = blog.NoteId.Hex() + } + blog2 := info.Post{ + NoteId: blog.NoteId.Hex(), + Title: blog.Title, + UrlTitle: urlTitle, + ImgSrc: blog.ImgSrc, + CreatedTime: blog.CreatedTime, + UpdatedTime: blog.UpdatedTime, + PublicTime: blog.PublicTime, + Desc: blog.Desc, + Abstract: blog.Abstract, + Content: blog.Content, + Tags: blog.Tags, + CommentNum: blog.CommentNum, + ReadNum: blog.ReadNum, + LikeNum: blog.LikeNum, + IsMarkdown: blog.IsMarkdown, + } + return blog2 +} + +func (this *BlogService) FixNote(note info.Note) info.Post { + if note.NoteId == "" { + return info.Post{} + } + urlTitle := note.UrlTitle + if urlTitle == "" { + urlTitle = note.NoteId.Hex() + } + return info.Post{ + NoteId: note.NoteId.Hex(), + Title: note.Title, + ImgSrc: note.ImgSrc, + UrlTitle: urlTitle, + CreatedTime: note.CreatedTime, + UpdatedTime: note.UpdatedTime, + PublicTime: note.PublicTime, + Desc: note.Desc, + Tags: note.Tags, + CommentNum: note.CommentNum, + ReadNum: note.ReadNum, + LikeNum: note.LikeNum, + IsMarkdown: note.IsMarkdown, + } } diff --git a/app/service/ConfigService.go b/app/service/ConfigService.go index 5d1c4e6..422190d 100644 --- a/app/service/ConfigService.go +++ b/app/service/ConfigService.go @@ -573,3 +573,12 @@ func (this *ConfigService) GetGlobalConfigForUser() map[string]interface{} { } return config } + +// 主页是否是管理员的博客页 +func (this *ConfigService) HomePageIsAdminsBlog() bool { + return this.GetGlobalStringConfig("homePage") == "" +} + +func (this *ConfigService) GetVersion() string { + return "1.0-beta2" +} diff --git a/app/service/GroupService.go b/app/service/GroupService.go new file mode 100644 index 0000000..3dfc273 --- /dev/null +++ b/app/service/GroupService.go @@ -0,0 +1,130 @@ +package service + +import ( + "github.com/leanote/leanote/app/info" + "github.com/leanote/leanote/app/db" +// . "github.com/leanote/leanote/app/lea" + "gopkg.in/mgo.v2/bson" + "time" +// "strings" +) + +// 用户组, 用户组用户管理 + +type GroupService struct { +} + +// 添加分组 +func (this *GroupService) AddGroup(userId, title string) (bool, info.Group) { + group := info.Group { + GroupId: bson.NewObjectId(), + UserId: bson.ObjectIdHex(userId), + Title: title, + CreatedTime: time.Now(), + } + return db.Insert(db.Groups, group), group +} +// 删除分组 +// 判断是否有好友 +func (this *GroupService) DeleteGroup(userId, groupId string) (ok bool, msg string) { + if db.Has(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}) { + return false, "hasUsers" + } + return db.DeleteByIdAndUserId(db.Groups, groupId, userId), "" + + // TODO 删除分组后, 在shareNote, shareNotebook中也要删除 +} +// 修改group标题 +func (this *GroupService) UpdateGroupTitle(userId, groupId, title string) (ok bool) { + return db.UpdateByIdAndUserIdField(db.Groups, groupId, userId, "Title", title) +} + +// 得到用户的所有分组(包括下的所有用户) +func (this *GroupService) GetGroupsAndUsers(userId string) ([]info.Group) { + // 得到分组s + groups := []info.Group{} + db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups) + // 得到其下的用户 + for i, group := range groups { + group.Users = this.GetUsers(group.GroupId.Hex()) + groups[i] = group + } + return groups +} +// 仅仅得到所有分组 +func (this *GroupService) GetGroups(userId string) ([]info.Group) { + // 得到分组s + groups := []info.Group{} + db.ListByQ(db.Groups, bson.M{"UserId": bson.ObjectIdHex(userId)}, &groups) + return groups +} +// 得到分组, shareService用 +func (this *GroupService) GetGroup(userId, groupId string) (info.Group) { + // 得到分组s + group := info.Group{} + db.GetByIdAndUserId(db.Groups, groupId, userId, &group) + return group +} + +// 得到某分组下的用户 +func (this *GroupService) GetUsers(groupId string) ([]info.User) { + // 得到UserIds + groupUsers := []info.GroupUser{} + db.ListByQWithFields(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}, []string{"UserId"}, &groupUsers) + if len(groupUsers) == 0 { + return nil + } + userIds := make([]bson.ObjectId, len(groupUsers)) + for i, each := range groupUsers { + userIds[i] = each.UserId + } + // 得到userInfos + return userService.ListUserInfosByUserIds(userIds) +} + +// 得到我所属的所有分组ids +func (this *GroupService) GetBelongToGroupIds(userId string) ([]bson.ObjectId) { + // 得到UserIds + groupUsers := []info.GroupUser{} + db.ListByQWithFields(db.GroupUsers, bson.M{"UserId": bson.ObjectIdHex(userId)}, []string{"GroupId"}, &groupUsers) + if len(groupUsers) == 0 { + return nil + } + groupIds := make([]bson.ObjectId, len(groupUsers)) + for i, each := range groupUsers { + groupIds[i] = each.GroupId + } + return groupIds +} + +func (this *GroupService) isMyGroup(ownUserId, groupId string) (ok bool) { + return db.Has(db.Groups, bson.M{"_id": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(ownUserId)}) +} +// 为group添加用户 +// 用户是否已存在? +func (this *GroupService) AddUser(ownUserId, groupId, userId string) (ok bool, msg string) { + // groupId是否是ownUserId的? + if !this.isMyGroup(ownUserId, groupId) { + return false, "forbidden" + } + + // 是否已存在 + if db.Has(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}) { + return false, "hasUsers" + } + + return db.Insert(db.GroupUsers, info.GroupUser{ + GroupUserId: bson.NewObjectId(), + GroupId: bson.ObjectIdHex(groupId), + UserId: bson.ObjectIdHex(userId), + CreatedTime: time.Now(), + }), "" +} +// 删除用户 +func (this *GroupService) DeleteUser(ownUserId, groupId, userId string) (ok bool, msg string) { + // groupId是否是ownUserId的? + if !this.isMyGroup(ownUserId, groupId) { + return false, "forbidden" + } + return db.Delete(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId), "UserId": bson.ObjectIdHex(userId)}), "" +} diff --git a/app/service/NoteImageService.go b/app/service/NoteImageService.go index 11dcf6d..5470889 100644 --- a/app/service/NoteImageService.go +++ b/app/service/NoteImageService.go @@ -32,7 +32,12 @@ func (this *NoteImageService) GetNoteIds(imageId string) ([]bson.ObjectId) { // 解析内容中的图片, 建立图片与note的关系 // // 图片必须是我的, 不然不添加 -func (this *NoteImageService) UpdateNoteImages(userId, noteId, content string) bool { +// imgSrc 防止博客修改了, 但内容删除了 +func (this *NoteImageService) UpdateNoteImages(userId, noteId, imgSrc, content string) bool { + // 让主图成为内容的一员 + if imgSrc != "" { + content = "" + content + } reg, _ := regexp.Compile("outputImage\\?fileId=([a-z0-9A-Z]{24})") find := reg.FindAllStringSubmatch(content, -1) // 查找所有的 diff --git a/app/service/NoteService.go b/app/service/NoteService.go index 9ca994c..a169abe 100644 --- a/app/service/NoteService.go +++ b/app/service/NoteService.go @@ -120,6 +120,7 @@ func (this *NoteService) ListNoteContentByNoteIds(noteIds []bson.ObjectId) (note // 添加笔记 // 首先要判断Notebook是否是Blog, 是的话设为blog // [ok] + func (this *NoteService) AddNote(note info.Note) info.Note { if(note.NoteId.Hex() == "") { noteId := bson.NewObjectId(); @@ -129,6 +130,7 @@ func (this *NoteService) AddNote(note info.Note) info.Note { note.UpdatedTime = note.CreatedTime note.IsTrash = false note.UpdatedUserId = note.UserId + note.UrlTitle = GetUrTitle(note.UserId.Hex(), note.Title, "note") // 设为blog notebookId := note.NotebookId.Hex() @@ -169,7 +171,7 @@ func (this *NoteService) AddNoteContent(noteContent info.NoteContent) info.NoteC db.Insert(db.NoteContents, noteContent) // 更新笔记图片 - noteImageService.UpdateNoteImages(noteContent.UserId.Hex(), noteContent.NoteId.Hex(), noteContent.Content) + noteImageService.UpdateNoteImages(noteContent.UserId.Hex(), noteContent.NoteId.Hex(), "", noteContent.Content) return noteContent; } @@ -205,7 +207,6 @@ func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.Note } // 修改笔记 -// [ok] TODO perm还没测 func (this *NoteService) UpdateNote(userId, updatedUserId, noteId string, needUpdate bson.M) bool { // updatedUserId 要修改userId的note, 此时需要判断是否有修改权限 if userId != updatedUserId { @@ -217,6 +218,13 @@ func (this *NoteService) UpdateNote(userId, updatedUserId, noteId string, needUp } } + // 是否已自定义 + note := this.GetNoteById(noteId) + if note.IsBlog && note.HasSelfDefined { + delete(needUpdate, "ImgSrc") + delete(needUpdate, "Desc") + } + needUpdate["UpdatedUserId"] = bson.ObjectIdHex(updatedUserId); needUpdate["UpdatedTime"] = time.Now(); @@ -260,12 +268,18 @@ func (this *NoteService) UpdateNoteContent(userId, updatedUserId, noteId, conten } } - if db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId, - bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId), + data := bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId), "Content": content, "Abstract": abstract, - "UpdatedTime": time.Now()}) { - + "UpdatedTime": time.Now()} + + // 是否已自定义 + note := this.GetNoteById(noteId) + if note.IsBlog && note.HasSelfDefined { + delete(data, "Abstract") + } + + if db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId, data) { // 这里, 添加历史记录 noteContentHistoryService.AddHistory(noteId, userId, info.EachHistory{UpdatedUserId: bson.ObjectIdHex(updatedUserId), Content: content, @@ -273,7 +287,7 @@ func (this *NoteService) UpdateNoteContent(userId, updatedUserId, noteId, conten }) // 更新笔记图片 - noteImageService.UpdateNoteImages(userId, noteId, content) + noteImageService.UpdateNoteImages(userId, noteId, note.ImgSrc, content) return true } @@ -306,6 +320,8 @@ func (this *NoteService) ToBlog(userId, noteId string, isBlog, isTop bool) bool noteUpdate["IsTop"] = isTop if isBlog { noteUpdate["PublicTime"] = time.Now() + } else { + noteUpdate["HasSelfDefined"] = false } ok := db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, noteUpdate) // 重新计算tags diff --git a/app/service/NotebookService.go b/app/service/NotebookService.go index a64b16e..686f82a 100644 --- a/app/service/NotebookService.go +++ b/app/service/NotebookService.go @@ -101,6 +101,15 @@ func (this *NotebookService) GetNotebookById(notebookId string) info.Notebook { db.Get(db.Notebooks, notebookId, ¬ebook) return notebook } +func (this *NotebookService) GetNotebookByUserIdAndUrlTitle(userId, notebookIdOrUrlTitle string) info.Notebook { + notebook := info.Notebook{} + if IsObjectId(notebookIdOrUrlTitle) { + db.Get(db.Notebooks, notebookIdOrUrlTitle, ¬ebook) + } else { + db.GetByQ(db.Notebooks, bson.M{"UserId": bson.ObjectIdHex(userId), "UrlTitle": encodeValue(notebookIdOrUrlTitle)}, ¬ebook) + } + return notebook +} // 得到用户下所有的notebook // 排序好之后返回 @@ -133,6 +142,7 @@ func (this *NotebookService) GetNotebooksByNotebookIds(notebookIds []bson.Object // 添加 // [ok] func (this *NotebookService) AddNotebook(notebook info.Notebook) bool { + notebook.UrlTitle = GetUrTitle(notebook.UserId.Hex(), notebook.Title, "notebook") err := db.Notebooks.Insert(notebook) if err != nil { panic(err) @@ -180,6 +190,8 @@ func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (boo data := bson.M{"IsBlog": isBlog} if isBlog { data["PublicTime"] = time.Now() + } else { + data["HasSelfDefined"] = false } db.UpdateByQMap(db.Notes, q, data) diff --git a/app/service/ShareService.go b/app/service/ShareService.go index ebad5b0..40219b3 100644 --- a/app/service/ShareService.go +++ b/app/service/ShareService.go @@ -13,7 +13,10 @@ import ( type ShareService struct { } -//----------------- +//----------------------------------- +// 返回shareNotebooks, sharedUserInfos +// info.ShareNotebooksByUser, []info.User + // 总体来说, 这个方法比较麻烦, 速度未知. 以后按以下方案来缓存用户基础数据 // 以后建个用户的基本数据表, 放所有notebook, sharedNotebook的缓存!! @@ -27,23 +30,48 @@ type ShareService struct { // 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 + +// 谁共享给了我的Query +func (this *ShareService) getOrQ(userId string) bson.M { + // 得到我参与的组织 + groupIds := groupService.GetBelongToGroupIds(userId) + q := bson.M{} + if len(groupIds) > 0 { + orQ := []bson.M{ + bson.M{"ToUserId": bson.ObjectIdHex(userId)}, + bson.M{"ToGroupId": bson.M{"$in": groupIds}}, + } + // 不是trash的 + q["$or"] = orQ + } else { + q["ToUserId"] = bson.ObjectIdHex(userId); } + return q +} + +func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksByUser, []info.User) { + // 得到共享给我的用户s信息 + // 得到我参与的组织 + q := this.getOrQ(userId) + + // 不查hasShareNotes + // 直接查shareNotes, shareNotebooks表得到userId + userIds1 := []bson.ObjectId{} + db.Distinct(db.ShareNotes, q, "UserId", &userIds1) + + userIds2 := []bson.ObjectId{} + db.Distinct(db.ShareNotebooks, q, "UserId", &userIds1) + + userIds := append(userIds1, userIds2...) userInfos := userService.GetUserInfosOrderBySeq(userIds); //-------------------- // 得到他们共享给我的notebooks + // 这里可能会得到重复的记录 + // 权限: 笔记本分享给个人 > 笔记本分享给组织 shareNotebooks := []info.ShareNotebook{} - db.ShareNotebooks.Find(bson.M{"ToUserId": bson.ObjectIdHex(userId)}).All(&shareNotebooks) + db.ShareNotebooks.Find(q).Sort("-ToUserId").All(&shareNotebooks) // 按ToUserId降序排序, 那么有ToUserId的在前面 if len(shareNotebooks) == 0 { return nil, userInfos @@ -52,12 +80,15 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB shareNotebooksLen := len(shareNotebooks) // 找到了所有的notbookId, 那么找notebook表得到其详细信息 - notebookIds := make([]bson.ObjectId, shareNotebooksLen) + notebookIds := []bson.ObjectId{} shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, shareNotebooksLen) - for i, each := range shareNotebooks { - // 默认的是没有notebookId的 - notebookIds[i] = each.NotebookId - shareNotebooksMap[each.NotebookId] = each + for _, each := range shareNotebooks { + // 之后的就不要了, 只留权限高的 + if _, ok := shareNotebooksMap[each.NotebookId]; !ok { + // 默认的是没有notebookId的 + notebookIds = append(notebookIds, each.NotebookId) + shareNotebooksMap[each.NotebookId] = each + } } // 1, 2 @@ -127,9 +158,13 @@ func (this *ShareService) parseToSubShareNotebooks(subNotebooks *info.SubNoteboo func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, sharedUserId string, page, pageSize int, sortField string, isAsc bool) ([]info.ShareNoteWithPerm) { // 1 首先判断是否真的sharedUserId 共享了 notebookId 给 myUserId + q := this.getOrQ(myUserId) + q["NotebookId"] = bson.ObjectIdHex(notebookId); + q["UserId"] = bson.ObjectIdHex(sharedUserId); shareNotebook := info.ShareNotebook{} - db.GetByQ(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId), - "UserId": bson.ObjectIdHex(sharedUserId), "ToUserId": bson.ObjectIdHex(myUserId)}, &shareNotebook) + db.GetByQ(db.ShareNotebooks, + q, + &shareNotebook) if shareNotebook.NotebookId == "" { return nil @@ -146,7 +181,19 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share for i, note := range notes { noteIds[i] = note.NoteId } - notePerms := this.getNotesPerm(noteIds, myUserId, sharedUserId); + // 笔记的权限 + shareNotes := []info.ShareNote{} + delete(q, "NotebookId") + q["NoteId"] = bson.M{"$in": noteIds} + db.ShareNotes.Find(q).Sort("-ToUserId").All(&shareNotes) // 给个的权限>给组织的权限 + notePerms := map[bson.ObjectId]int{} + for _, each := range shareNotes { + if _, ok := notePerms[each.NoteId]; !ok { + notePerms[each.NoteId] = each.Perm + } + } + Log("笔记权限") + LogJ(notePerms); // 3.2 组合 notesWithPerm := make([]info.ShareNoteWithPerm, len(notes)) @@ -162,17 +209,21 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share } // 得到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 -} +//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 @@ -184,9 +235,12 @@ func (this *ShareService) ListShareNotes(myUserId, sharedUserId string, skipNum, _ := parsePageAndSort(pageNumber, pageSize, sortField, isAsc) shareNotes := []info.ShareNote{} + q := this.getOrQ(myUserId) + q["UserId"] = bson.ObjectIdHex(sharedUserId); + db.ShareNotes. - Find(bson.M{"UserId": bson.ObjectIdHex(sharedUserId), "ToUserId": bson.ObjectIdHex(myUserId)}). -// Sort(sortFieldR). + Find(q). + Sort("-ToUserId"). // 给个人的权限 > 给组织的权限 Skip(skipNum). Limit(pageSize). All(&shareNotes) @@ -200,15 +254,20 @@ func (this *ShareService) ListShareNotes(myUserId, sharedUserId string, noteIds[i] = each.NoteId } notes := noteService.ListNotesByNoteIds(noteIds) - notesMap := make(map[bson.ObjectId]info.Note, len(notes)) + notesMap := map[bson.ObjectId]info.Note{} 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} + notesWithPerm := []info.ShareNoteWithPerm{} + hasAdded := map[bson.ObjectId]bool{} // 防止重复, 只要前面权限高的 + for _, each := range shareNotes { + if !hasAdded[each.NoteId] { + // 待优化 + notesWithPerm = append(notesWithPerm, info.ShareNoteWithPerm{notesMap[each.NoteId], each.Perm}) + hasAdded[each.NoteId] = true + } } return notesWithPerm } @@ -286,19 +345,25 @@ func (this *ShareService) AddShareNote(noteId string, perm int, userId, email st return db.Insert(db.ShareNotes, shareNote), "", toUserId } + // updatedUserId是否有查看userId noteId的权限? +// userId是所有者 func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool { - if !db.Has(db.ShareNotes, - bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NoteId": bson.ObjectIdHex(noteId)}) { + q := this.getOrQ(updatedUserId) // (toUserId == "xxx" || ToGroupId in (1, 2,3)) + q["UserId"] = bson.ObjectIdHex(userId) + q["NoteId"] = bson.ObjectIdHex(noteId) + if !db.Has(db.ShareNotes, q) { // noteId的notebookId是否被共享了? notebookId := noteService.GetNotebookId(noteId) if notebookId.Hex() == "" { return false } + delete(q, "NoteId") + q["NotebookId"] = notebookId + // 判断notebook是否被共享 - if !db.Has(db.ShareNotebooks, - bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NotebookId": notebookId}) { + if !db.Has(db.ShareNotebooks, q) { return false } else { return true @@ -310,43 +375,44 @@ func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool // 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 + q := this.getOrQ(updatedUserId) // (toUserId == "xxx" || ToGroupId in (1, 2,3)) + q["UserId"] = bson.ObjectIdHex(userId) + q["NoteId"] = bson.ObjectIdHex(noteId) + + // note的权限 + shares := []info.ShareNote{} + db.ShareNotes.Find(q).Sort("-ToUserId").All(&shares) // 个人 > 组织 + for _, share := range shares { + return share.Perm == 1 // 第1个权限最大 } + + // notebook的权限 + notebookId := noteService.GetNotebookId(noteId) + if notebookId.Hex() == "" { + return false + } + + delete(q, "NoteId") + q["NotebookId"] = notebookId + shares2 := []info.ShareNotebook{} + db.ShareNotebooks.Find(q).Sort("-ToUserId").All(&shares2) // 个人 > 组织 + for _, share := range shares2 { + return share.Perm == 1 // 第1个权限最大 + } + return false } // 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 - } + q := this.getOrQ(updatedUserId) // (toUserId == "xxx" || ToGroupId in (1, 2,3)) + q["UserId"] = bson.ObjectIdHex(userId) + q["NotebookId"] = bson.ObjectIdHex(notebookId) + shares2 := []info.ShareNotebook{} + db.ShareNotebooks.Find(q).Sort("-ToUserId").All(&shares2) // 个人 > 组织 + for _, share := range shares2 { + return share.Perm == 1 // 第1个权限最大 + } + return false } // 共享note, notebook时使用 @@ -372,12 +438,16 @@ func (this *ShareService) HasSharedNotebook(noteId, myUserId, sharedUserId strin } // 得到共享的笔记内容 -// 首先要判断这个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) { +// Log(this.HasSharedNote(noteId, myUserId)) +// Log(this.HasSharedNotebook(noteId, myUserId, sharedUserId)) + Log(this.HasReadPerm(sharedUserId, myUserId, noteId)) + if this.HasReadPerm(sharedUserId, myUserId, noteId) { +// if this.HasSharedNote(noteId, myUserId) || this.HasSharedNotebook(noteId, myUserId, sharedUserId) { db.Get(db.NoteContents, noteId, ¬eContent) } else { } @@ -391,7 +461,15 @@ func (this *ShareService) GetShareNoteContent(noteId, myUserId, sharedUserId str 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) + db.ListByQLimit(db.ShareNotes, + bson.M{ + "NoteId": bson.ObjectIdHex(noteId), + "UserId": bson.ObjectIdHex(userId), + "ToGroupId": bson.M{"$exists": false}, + }, &shareNotes, 100) + +// Log("<<>>>>") +// Log(len(shareNotes)) if len(shareNotes) == 0 { return nil @@ -450,7 +528,11 @@ func (this *ShareService) ListNotebookShareUserInfo(notebookId, userId string) [ shareNotebooks := []info.ShareNotebook{} db.ListByQLimit(db.ShareNotebooks, - bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId)}, + bson.M{ + "NotebookId": bson.ObjectIdHex(notebookId), + "UserId": bson.ObjectIdHex(userId), + "ToGroupId": bson.M{"$exists": false}, + }, &shareNotebooks, 100) if len(shareNotebooks) == 0 { @@ -555,7 +637,7 @@ func (this *ShareService) HasUpdateNotePerm(noteId, userId string) bool { } } -// 用户userId是否有修改noteId的权限 +// 用户userId是否有查看noteId的权限 func (this *ShareService) HasReadNotePerm(noteId, userId string) bool { if noteId == "" || userId == "" { return false; @@ -576,4 +658,121 @@ func (this *ShareService) HasReadNotePerm(noteId, userId string) bool { } else { return false; } -} \ No newline at end of file +} + +//---------------- +// 用户分组 + +// 得到笔记分享给的groups +func (this *ShareService) GetNoteShareGroups(noteId, userId string) []info.ShareNote { + // 得到分组s + groups := groupService.GetGroups(userId) + + // 得到有分享的分组 + shares := []info.ShareNote{} + db.ListByQ(db.ShareNotes, + bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId), "ToGroupId": bson.M{"$exists":true}}, &shares) + mapShares := map[bson.ObjectId]info.ShareNote{} + for _, share := range shares { + mapShares[share.ToGroupId] = share + } + + // 所有的groups都有share, 但没有share的group没有shareId + shares2 := make([]info.ShareNote, len(groups)) + for i, group := range groups { + share, ok := mapShares[group.GroupId] + if !ok { + share = info.ShareNote{} + } + share.ToGroup = group; + shares2[i] = share + } + + return shares2 +} + +// 共享笔记给分组 +func (this *ShareService) AddShareNoteGroup(userId, noteId, groupId string, perm int) (bool) { + // 得到group, 是否是我的group + group := groupService.GetGroup(userId, groupId) + if group.GroupId == "" { + return false + } + + // 先删除之 + this.DeleteShareNoteGroup(userId, noteId, groupId) + + shareNote := info.ShareNote{NoteId: bson.ObjectIdHex(noteId), + UserId: bson.ObjectIdHex(userId), // 冗余字段 + ToGroupId: bson.ObjectIdHex(groupId), + Perm: perm, + CreatedTime: time.Now(), + } + return db.Insert(db.ShareNotes, shareNote) +} + +// 删除 +func (this *ShareService) DeleteShareNoteGroup(userId, noteId, groupId string) bool { + return db.Delete(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId), + "UserId": bson.ObjectIdHex(userId), + "ToGroupId": bson.ObjectIdHex(groupId), + }); +} + +//------- + +// 得到笔记本分享给的groups +func (this *ShareService) GetNotebookShareGroups(notebookId, userId string) []info.ShareNotebook { + // 得到分组s + groups := groupService.GetGroups(userId) + + // 得到有分享的分组 + shares := []info.ShareNotebook{} + db.ListByQ(db.ShareNotebooks, + bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId), "ToGroupId": bson.M{"$exists":true}}, &shares) + mapShares := map[bson.ObjectId]info.ShareNotebook{} + for _, share := range shares { + mapShares[share.ToGroupId] = share + } + LogJ(shares) + + // 所有的groups都有share, 但没有share的group没有shareId + shares2 := make([]info.ShareNotebook, len(groups)) + for i, group := range groups { + share, ok := mapShares[group.GroupId] + if !ok { + share = info.ShareNotebook{} + } + share.ToGroup = group; + shares2[i] = share + } + + return shares2 +} +// 共享笔记给分组 +func (this *ShareService) AddShareNotebookGroup(userId, notebookId, groupId string, perm int) (bool) { + // 得到group, 是否是我的group + group := groupService.GetGroup(userId, groupId) + if group.GroupId == "" { + return false + } + + // 先删除之 + this.DeleteShareNotebookGroup(userId, notebookId, groupId) + + shareNotebook := info.ShareNotebook{NotebookId: bson.ObjectIdHex(notebookId), + UserId: bson.ObjectIdHex(userId), // 冗余字段 + ToGroupId: bson.ObjectIdHex(groupId), + Perm: perm, + CreatedTime: time.Now(), + } + return db.Insert(db.ShareNotebooks, shareNotebook) +} + +// 删除 +func (this *ShareService) DeleteShareNotebookGroup(userId, notebookId, groupId string) bool { + return db.Delete(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId), + "UserId": bson.ObjectIdHex(userId), + "ToGroupId": bson.ObjectIdHex(groupId), + }); +} diff --git a/app/service/ThemeService.go b/app/service/ThemeService.go index e5b18fb..d1385ec 100644 --- a/app/service/ThemeService.go +++ b/app/service/ThemeService.go @@ -433,6 +433,36 @@ func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string) return } +// 升级用 +// public/ + +func (this *ThemeService) UpgradeThemeBeta2() (ok bool) { + adminUserId := configService.GetAdminUserId() + this.upgradeThemeBeta2(adminUserId, this.GetDefaultThemePath(defaultStyle), true) + this.upgradeThemeBeta2(adminUserId, this.GetDefaultThemePath(elegantStyle), false) + this.upgradeThemeBeta2(adminUserId, this.GetDefaultThemePath(fixedStyle), false) + return true +} +func (this *ThemeService) upgradeThemeBeta2(userId, targetPath string, isActive bool) (ok bool) { + // 解压成功, 那么新建之 + // 保存到数据库中 + theme, _ := this.getThemeConfig(revel.BasePath + "/" + targetPath) + if theme.Name == "" { + ok = false + return + } + themeIdO := bson.NewObjectId() + theme.ThemeId = themeIdO + theme.Path = targetPath // public + theme.CreatedTime = time.Now() + theme.UpdatedTime = theme.CreatedTime + theme.UserId = bson.ObjectIdHex(userId) + theme.IsActive = isActive + theme.IsDefault = true + ok = db.Insert(db.Themes, theme) + return ok +} + // 安装主题 // 得到该主题路径 func (this *ThemeService) InstallTheme(userId, themeId string) (ok bool) { diff --git a/app/service/UpgradeService.go b/app/service/UpgradeService.go index 117ea0b..740a14d 100644 --- a/app/service/UpgradeService.go +++ b/app/service/UpgradeService.go @@ -29,8 +29,15 @@ func (this *UpgradeService) UpgradeBlog() bool { } // 11-5自定义博客升级, 将aboutMe移至pages -func (this *UpgradeService) UpgradeBetaToSelfBlog(userId string) (ok bool, msg string) { - if configService.GetGlobalStringConfig("UpgradeBetaToSelfBlog") != "" { +/* +
  • Migrate "About me" to single(a single post)
  • +
  • Add some default themes to administrator
  • +
  • Generate "UrlTitle" for all notes. "UrlTitle" is a friendly url for post
  • +
  • Generate "UrlTitle" for all notebooks
  • +
  • Generate "UrlTitle" for all singles
  • +*/ +func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg string) { + if configService.GetGlobalStringConfig("UpgradeBetaToBeta2") != "" { return false, "已升级" } @@ -42,11 +49,58 @@ func (this *UpgradeService) UpgradeBetaToSelfBlog(userId string) (ok bool, msg s blogService.AddOrUpdateSingle(userBlog.UserId.Hex(), "", "About Me", userBlog.AboutMe) } - configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToSelfBlog", "ok") + + // 2. 默认主题, 给admin用户 + themeService.UpgradeThemeBeta2() + + // 3. UrlTitles + + // 3.1 note + notes := []info.Note{} + db.ListByQ(db.Notes, bson.M{}, ¬es) + for _, note := range notes { + data := bson.M{} + noteId := note.NoteId.Hex() + // PublicTime, RecommendTime = UpdatedTime + if note.IsBlog && note.PublicTime.Year() < 100 { + data["PublicTime"] = note.UpdatedTime + data["RecommendTime"] = note.UpdatedTime + Log("Time " + noteId) + } + data["UrlTitle"] = GetUrTitle(note.UserId.Hex(), note.Title, "note") + db.UpdateByIdAndUserIdMap2(db.Notes, note.NoteId, note.UserId, data) + Log(noteId) + } + + // 3.2 + Log("notebook") + notebooks := []info.Notebook{} + db.ListByQ(db.Notebooks, bson.M{}, ¬ebooks) + for _, notebook := range notebooks { + notebookId := notebook.NotebookId.Hex() + data := bson.M{} + data["UrlTitle"] = GetUrTitle(notebook.UserId.Hex(), notebook.Title, "notebook") + db.UpdateByIdAndUserIdMap2(db.Notebooks, notebook.NotebookId, notebook.UserId, data) + Log(notebookId) + } + + // 3.3 single + /* + singles := []info.BlogSingle{} + db.ListByQ(db.BlogSingles, bson.M{}, &singles) + for _, single := range singles { + singleId := single.SingleId.Hex() + blogService.UpdateSingleUrlTitle(single.UserId.Hex(), singleId, single.Title) + Log(singleId) + } + */ + + // 删除索引 + db.ShareNotes.DropIndex("UserId", "ToUserId", "NoteId") ok = true msg = "success" + configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToBeta2", "1") - // 2. 默认主题, 给admin用户 return } diff --git a/app/service/UserService.go b/app/service/UserService.go index 5a3461c..cea7c79 100644 --- a/app/service/UserService.go +++ b/app/service/UserService.go @@ -41,6 +41,13 @@ func (this *UserService) GetUserId(email string) string { return user.UserId.Hex() } +// 得到用户名 +func (this *UserService) GetUsername(userId string) string { + user := info.User{} + db.GetByQWithFields(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, []string{"Username"}, &user) + return user.Username +} + // 是否存在该用户 email func (this *UserService) IsExistsUser(email string) bool { if this.GetUserId(email) == "" { @@ -163,7 +170,7 @@ func (this *UserService) MapUserAndBlogByUserIds(userIds []bson.ObjectId) map[st Logo: user.Logo, BlogTitle: userBlog.Title, BlogLogo: userBlog.Logo, - BlogUrl: blogService.GetUserBlogUrl(&userBlog), + BlogUrl: blogService.GetUserBlogUrl(&userBlog, user.Username), } } return userAndBlogMap @@ -180,7 +187,8 @@ func (this *UserService) GetUserAndBlog(userId string) info.UserAndBlog { Logo: user.Logo, BlogTitle: userBlog.Title, BlogLogo: userBlog.Logo, - BlogUrl: blogService.GetUserBlogUrl(&userBlog), + BlogUrl: blogService.GetUserBlogUrl(&userBlog, user.Username), + BlogUrls: blogService.GetBlogUrls(&userBlog, &user), } } @@ -269,6 +277,20 @@ func (this *UserService) UpdateTheme(userId, theme string) (bool) { return ok } +// 帐户类型设置 +func (this *UserService) UpdateAccount(userId, accountType string, accountStartTime, accountEndTime time.Time, + maxImageNum, maxImageSize, maxAttachNum, maxAttachSize, maxPerAttachSize int) bool { + return db.UpdateByQI(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, info.UserAccount{ + AccountType: accountType, + AccountStartTime: accountStartTime, + AccountEndTime: accountEndTime, + MaxImageNum: maxImageNum, + MaxImageSize: maxImageSize, + MaxAttachNum: maxAttachNum, + MaxAttachSize: maxAttachSize, + MaxPerAttachSize: maxPerAttachSize, + }) +} //--------------- // 修改email diff --git a/app/service/init.go b/app/service/init.go index 2c7cb7e..a07e1de 100644 --- a/app/service/init.go +++ b/app/service/init.go @@ -1,6 +1,13 @@ package service import ( + "regexp" + "strings" + "net/url" + "strconv" + "gopkg.in/mgo.v2" + "github.com/leanote/leanote/app/db" + "gopkg.in/mgo.v2/bson" ) // init service, for share service bettween services @@ -13,6 +20,7 @@ var noteContentHistoryService, NoteContentHistoryS *NoteContentHistoryService var trashService, TrashS *TrashService var shareService, ShareS *ShareService var userService, UserS *UserService +var groupService, GroupS *GroupService var tagService, TagS *TagService var blogService, BlogS *BlogService var tokenService, TokenS *TokenService @@ -37,6 +45,7 @@ func InitService() { TrashS = &TrashService{} ShareS = &ShareService{} UserS = &UserService{} + GroupS = &GroupService{} TagS = &TagService{} BlogS = &BlogService{} TokenS = &TokenService{} @@ -59,6 +68,7 @@ func InitService() { trashService = TrashS shareService = ShareS userService = UserS + groupService = GroupS tagService = TagS blogService = BlogS tokenService = TokenS @@ -71,3 +81,70 @@ func InitService() { sessionService = SessionS themeService = ThemeS } + +//---------------- +// service 公用方法 + +// 将name=val的val进行encoding +func decodeValue(val string) string { + v, _ := url.ParseQuery("a=" + val) + return v.Get("a") +} + +func encodeValue(val string) string { + if val == "" { + return val + } + v := url.Values{} + v.Set("", val) + return v.Encode()[1:] +} +// 添加笔记时通过title得到urlTitle +func fixUrlTitle(urlTitle string) string { + if urlTitle != "" { + // 把特殊字段给替换掉 +// str := `life "%&()+,/:;<>=?@\|` + reg, _ := regexp.Compile("/|#|\\$|!|\\^|\\*|'| |\"|%|&|\\(|\\)|\\+|\\,|/|:|;|<|>|=|\\?|@|\\||\\\\") + urlTitle = reg.ReplaceAllString(urlTitle, "-") + urlTitle = strings.Trim(urlTitle, "-") // 左右单独的-去掉 + // 把空格替换成- +// urlTitle = strings.Replace(urlTitle, " ", "-", -1) + for strings.Index(urlTitle, "--") >= 0 { // 防止出现连续的-- + urlTitle = strings.Replace(urlTitle, "--", "-", -1) + } + return encodeValue(urlTitle) + } + return urlTitle +} + +func getUniqueUrlTitle(userId string, urlTitle string, types string, padding int) string { + urlTitle2 := urlTitle + if padding > 1 { + urlTitle2 = urlTitle + "-" + strconv.Itoa(padding) + } + userIdO := bson.ObjectIdHex(userId) + + var collection *mgo.Collection + if types == "note" { + collection = db.Notes + } else if types == "notebook" { + collection = db.Notebooks + } else if types == "single" { + collection = db.BlogSingles + } + for db.Has(collection, bson.M{"UserId": userIdO, "UrlTitle": urlTitle2}) { // 用户下唯一 + padding++ + urlTitle2 = urlTitle + "-" + strconv.Itoa(padding) + } + + return urlTitle2 +} +// types == note,notebook,single +func GetUrTitle(userId string, title string, types string) string { + urlTitle := strings.Trim(title, " ") + if urlTitle == "" { + urlTitle = "Untitled-" + userId + } + urlTitle = fixUrlTitle(urlTitle) + return getUniqueUrlTitle(userId, urlTitle, types, 1) +} diff --git a/app/views/admin/nav.html b/app/views/admin/nav.html index bda8028..11af6f4 100644 --- a/app/views/admin/nav.html +++ b/app/views/admin/nav.html @@ -128,10 +128,18 @@ - Setting + Configuration +
  • + + + + + + + + + + + + + + Upgrade + + + +
  • \ No newline at end of file diff --git a/app/views/admin/setting/home_page.html b/app/views/admin/setting/home_page.html new file mode 100644 index 0000000..f23eaaa --- /dev/null +++ b/app/views/admin/setting/home_page.html @@ -0,0 +1,49 @@ +{{template "admin/top.html" .}} +

    Home Page

    + +
    + +
    +
    +
    +
    + + +
    + + +
    +
    + +
    + +
    +
    +
    +
    + +
    + +{{template "admin/footer.html" .}} + + +{{template "admin/end.html" .}} \ No newline at end of file diff --git a/app/views/admin/setting/openRegister.html b/app/views/admin/setting/open_register.html similarity index 100% rename from app/views/admin/setting/openRegister.html rename to app/views/admin/setting/open_register.html diff --git a/app/views/admin/upgrade/beta2.html b/app/views/admin/upgrade/beta2.html new file mode 100644 index 0000000..8de190c --- /dev/null +++ b/app/views/admin/upgrade/beta2.html @@ -0,0 +1,47 @@ +{{template "admin/top.html" .}} +

    Upgrade v1.0-beta to v1.0-beta2

    + +
    + +
    +
    +
    +
    + Current Version: leanote v{{.version}} +
      +
    • Migrate "About me" to single(a single post)
    • +
    • Add some default themes to administrator
    • +
    • Generate "UrlTitle" for all notes. "UrlTitle" is a friendly url for post
    • +
    • Generate "UrlTitle" for all notebooks
    • +
    • Generate "UrlTitle" for all singles
    • +
    +
    +
    + +
    +
    +
    +
    + +
    + +{{template "admin/footer.html" .}} + + +{{template "admin/end.html" .}} \ No newline at end of file diff --git a/app/views/member/blog/cate.html b/app/views/member/blog/cate.html index 314f205..b391bd6 100644 --- a/app/views/member/blog/cate.html +++ b/app/views/member/blog/cate.html @@ -12,6 +12,9 @@ {{range .notebooks}}
  • +
    + 固定链接: /cate/ +
    {{.Title}}
  • {{end}} @@ -33,7 +36,7 @@ $(function() { $(".list-group-item").each(function() { ids.push($(this).data("id")); }); - ajaxPost("/member/blog/upateCateIds", {cateIds: ids}, function(re){ + ajaxPost("/member/blog/", {cateIds: ids}, function(re){ if(reIsOk(re)) { art.tips("Success"); } else { @@ -41,6 +44,19 @@ $(function() { } }); }); + + $(".url-title").change(function(){ + var $t = $(this); + var url = $t.val(); + var cateId = $t.data('id'); + ajaxPost("/member/blog/updateCateUrlTitle", {cateId: cateId, urlTitle: url}, function(re){ + if(reIsOk(re)) { + $t.val(re.Item); + } else { + art.alert(re.Msg || "error"); + } + }); + }); }); diff --git a/app/views/member/blog/comment.html b/app/views/member/blog/comment.html index 8a1c071..487ecf9 100644 --- a/app/views/member/blog/comment.html +++ b/app/views/member/blog/comment.html @@ -9,8 +9,7 @@
    - -
    +