Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c26d25deab |
No files matched your search
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>leanote-public</name>
|
||||
<name>leanote2</name>
|
||||
<comment>leanote, your own cloud note!</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
"io"
|
||||
"fmt"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
)
|
||||
@@ -57,12 +56,8 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) {
|
||||
return re
|
||||
}
|
||||
// > 5M?
|
||||
maxFileSize := configService.GetUploadSize("uploadAttachSize");
|
||||
if maxFileSize <= 0 {
|
||||
maxFileSize = 1000
|
||||
}
|
||||
if(float64(len(data)) > maxFileSize * float64(1024*1024)) {
|
||||
resultMsg = fmt.Sprintf("附件大于%vM", maxFileSize)
|
||||
if(len(data) > 5 * 1024 * 1024) {
|
||||
resultMsg = "File is bigger than 5M"
|
||||
return re
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ func (c BaseController) SetLocale() string {
|
||||
lang = "en";
|
||||
}
|
||||
c.RenderArgs["locale"] = lang;
|
||||
c.RenderArgs["siteUrl"] = configService.GetSiteUrl();
|
||||
c.RenderArgs["siteUrl"] = siteUrl;
|
||||
|
||||
c.RenderArgs["blogUrl"] = configService.GetBlogUrl()
|
||||
c.RenderArgs["leaUrl"] = configService.GetLeaUrl()
|
||||
@@ -196,9 +196,6 @@ func (c BaseController) SetLocale() string {
|
||||
func (c BaseController) SetUserInfo() {
|
||||
userInfo := c.GetUserInfo()
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
if(userInfo.Username == configService.GetAdminUsername()) {
|
||||
c.RenderArgs["isAdmin"] = true
|
||||
}
|
||||
}
|
||||
|
||||
// life
|
||||
|
||||
+306
-646
File diff suppressed because it is too large.
Load diff
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@@ -22,7 +21,7 @@ type File struct {
|
||||
// 上传的是博客logo
|
||||
// TODO logo不要设置权限, 另外的目录
|
||||
func (c File) UploadBlogLogo() revel.Result {
|
||||
re := c.uploadImage("blogLogo", "");
|
||||
re := c.uploadImage("logo", "");
|
||||
|
||||
c.RenderArgs["fileUrlPath"] = re.Id
|
||||
c.RenderArgs["resultCode"] = re.Code
|
||||
@@ -101,7 +100,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
|
||||
}
|
||||
defer file.Close()
|
||||
// 生成上传路径
|
||||
if(from == "logo" || from == "blogLogo") {
|
||||
if(from == "logo") {
|
||||
fileUrlPath = "public/upload/" + c.GetUserId() + "/images/logo"
|
||||
} else {
|
||||
fileUrlPath = "files/" + c.GetUserId() + "/images"
|
||||
@@ -132,22 +131,10 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
|
||||
return re
|
||||
}
|
||||
|
||||
var maxFileSize float64
|
||||
if(from == "logo") {
|
||||
maxFileSize = configService.GetUploadSize("uploadAvatarSize");
|
||||
} else if from == "blogLogo" {
|
||||
maxFileSize = configService.GetUploadSize("uploadBlogLogoSize");
|
||||
} else {
|
||||
maxFileSize = configService.GetUploadSize("uploadImageSize");
|
||||
}
|
||||
if maxFileSize <= 0 {
|
||||
maxFileSize = 1000
|
||||
}
|
||||
|
||||
// > 2M?
|
||||
if(float64(len(data)) > maxFileSize * float64(1024*1024)) {
|
||||
if(len(data) > 5 * 1024 * 1024) {
|
||||
resultCode = 0
|
||||
resultMsg = fmt.Sprintf("图片大于%vM", maxFileSize)
|
||||
resultMsg = "图片大于2M"
|
||||
return re
|
||||
}
|
||||
|
||||
@@ -174,7 +161,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) {
|
||||
id := bson.NewObjectId();
|
||||
fileInfo.FileId = id
|
||||
fileId = id.Hex()
|
||||
if(from == "logo" || from == "blogLogo") {
|
||||
if(from == "logo") {
|
||||
fileId = "public/upload/" + c.GetUserId() + "/images/logo/" + filename
|
||||
}
|
||||
|
||||
@@ -316,7 +303,7 @@ func (c File) UploadImage(renderHtml string) revel.Result {
|
||||
|
||||
re := c.uploadImage("", "");
|
||||
|
||||
c.RenderArgs["fileUrlPath"] = configService.GetSiteUrl() + re.Id
|
||||
c.RenderArgs["fileUrlPath"] = siteUrl + re.Id
|
||||
c.RenderArgs["resultCode"] = re.Code
|
||||
c.RenderArgs["resultMsg"] = re.Msg
|
||||
|
||||
|
||||
@@ -12,16 +12,8 @@ type Index struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
func (c Index) Default() revel.Result {
|
||||
if configService.HomePageIsAdminsBlog(){
|
||||
blog := Blog{c.BaseController}
|
||||
return blog.Index(configService.GetAdminUsername());
|
||||
}
|
||||
return c.Index()
|
||||
}
|
||||
// leanote展示页, 没有登录的, 或已登录明确要进该页的
|
||||
func (c Index) Index() revel.Result {
|
||||
|
||||
c.SetUserInfo()
|
||||
c.RenderArgs["title"] = "leanote"
|
||||
c.RenderArgs["openRegister"] = configService.GlobalStringConfigs["openRegister"]
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "github.com/leanote/leanote/app/info"
|
||||
)
|
||||
|
||||
// 首页
|
||||
type Mobile struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
// leanote展示页, 没有登录的, 或已登录明确要进该页的
|
||||
func (c Mobile) Index() revel.Result {
|
||||
c.SetLocale()
|
||||
|
||||
userInfo := c.GetUserInfo()
|
||||
userId := userInfo.UserId.Hex()
|
||||
|
||||
// 没有登录
|
||||
if userId == "" {
|
||||
return c.RenderTemplate("mobile/login.html")
|
||||
}
|
||||
|
||||
/*
|
||||
// 已登录了, 那么得到所有信息
|
||||
notebooks := notebookService.GetNotebooks(userId)
|
||||
shareNotebooks, sharedUserInfos := shareService.GetShareNotebooks(userId)
|
||||
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
c.RenderArgs["userInfoJson"] = c.Json(userInfo)
|
||||
c.RenderArgs["notebooks"] = c.Json(notebooks)
|
||||
c.RenderArgs["shareNotebooks"] = c.Json(shareNotebooks)
|
||||
c.RenderArgs["sharedUserInfos"] = c.Json(sharedUserInfos)
|
||||
c.RenderArgs["tagsJson"] = c.Json(tagService.GetTags(c.GetUserId()))
|
||||
*/
|
||||
|
||||
return c.RenderTemplate("mobile/angular.html");
|
||||
}
|
||||
|
||||
func (c Mobile) Logout() revel.Result {
|
||||
c.ClearSession()
|
||||
return c.RenderTemplate("mobile/login.html");
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"os/exec"
|
||||
// "time"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
@@ -53,21 +52,19 @@ func (c Note) Index() revel.Result {
|
||||
}
|
||||
// 当然, 还需要得到第一个notes的content
|
||||
//...
|
||||
Log(configService.GetAdminUsername())
|
||||
c.RenderArgs["isAdmin"] = configService.GetAdminUsername() == userInfo.Username
|
||||
|
||||
c.RenderArgs["isAdmin"] = leanoteUserId == userInfo.Username
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
c.RenderArgs["notebooks"] = notebooks
|
||||
c.RenderArgs["shareNotebooks"] = shareNotebooks
|
||||
c.RenderArgs["sharedUserInfos"] = sharedUserInfos
|
||||
c.RenderArgs["userInfoJson"] = c.Json(userInfo)
|
||||
c.RenderArgs["notebooks"] = c.Json(notebooks)
|
||||
c.RenderArgs["shareNotebooks"] = c.Json(shareNotebooks)
|
||||
c.RenderArgs["sharedUserInfos"] = c.Json(sharedUserInfos)
|
||||
|
||||
c.RenderArgs["notes"] = notes
|
||||
c.RenderArgs["noteContentJson"] = noteContent
|
||||
c.RenderArgs["notes"] = c.Json(notes)
|
||||
c.RenderArgs["noteContentJson"] = c.Json(noteContent)
|
||||
c.RenderArgs["noteContent"] = noteContent.Content
|
||||
|
||||
c.RenderArgs["tags"] = tagService.GetTags(c.GetUserId())
|
||||
|
||||
c.RenderArgs["globalConfigs"] = configService.GetGlobalConfigForUser()
|
||||
c.RenderArgs["tagsJson"] = c.Json(tagService.GetTags(c.GetUserId()))
|
||||
|
||||
if isDev, _ := revel.Config.Bool("mode.dev"); isDev {
|
||||
return c.RenderTemplate("note/note-dev.html")
|
||||
@@ -124,7 +121,7 @@ func (c Note) UpdateNoteOrContent(noteOrContent NoteOrContent) revel.Result {
|
||||
// 新添加note
|
||||
if noteOrContent.IsNew {
|
||||
userId := c.GetObjectUserId();
|
||||
// myUserId := userId
|
||||
myUserId := userId
|
||||
// 为共享新建?
|
||||
if noteOrContent.FromUserId != "" {
|
||||
userId = bson.ObjectIdHex(noteOrContent.FromUserId)
|
||||
@@ -146,7 +143,7 @@ func (c Note) UpdateNoteOrContent(noteOrContent NoteOrContent) revel.Result {
|
||||
Content: noteOrContent.Content,
|
||||
Abstract: noteOrContent.Abstract};
|
||||
|
||||
note = noteService.AddNoteAndContentForController(note, noteContent, c.GetUserId())
|
||||
note = noteService.AddNoteAndContent(note, noteContent, myUserId)
|
||||
return c.RenderJson(note)
|
||||
}
|
||||
|
||||
@@ -299,7 +296,7 @@ func (c Note) Html2Image(noteId string) revel.Result {
|
||||
appKey, _ := revel.Config.String("app.secret")
|
||||
cookieDomain, _ := revel.Config.String("cookie.domain")
|
||||
// 生成之
|
||||
url := configService.GetSiteUrl() + "/note/toImage?noteId=" + noteId + "&appKey=" + appKey;
|
||||
url := siteUrl + "/note/toImage?noteId=" + noteId + "&appKey=" + appKey;
|
||||
// /Users/life/Documents/bin/phantomjs/bin/phantomjs /Users/life/Desktop/test/b.js
|
||||
binPath := configService.GetGlobalStringConfig("toImageBinPath")
|
||||
if binPath == "" {
|
||||
@@ -354,9 +351,3 @@ func (c Note) Html2Image(noteId string) revel.Result {
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
// 设置/取消Blog; 置顶
|
||||
func (c Note) SetNote2Blog(noteId string, isBlog, isTop bool) revel.Result {
|
||||
re := noteService.ToBlog(c.GetUserId(), noteId, isBlog, isTop)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
@@ -69,9 +69,3 @@ func (c Notebook) DragNotebooks(data string) revel.Result {
|
||||
|
||||
return c.RenderJson(notebookService.DragNotebooks(c.GetUserId(), info.CurNotebookId, info.ParentNotebookId, info.Siblings))
|
||||
}
|
||||
|
||||
// 设置notebook <-> blog
|
||||
func (c Notebook) SetNotebook2Blog(notebookId string, isBlog bool) revel.Result {
|
||||
re := notebookService.ToBlog(c.GetUserId(), notebookId, isBlog)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "strings"
|
||||
// "time"
|
||||
// "encoding/json"
|
||||
// "github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "github.com/leanote/leanote/app/lea/blog"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "github.com/leanote/leanote/app/types"
|
||||
// "io/ioutil"
|
||||
// "math"
|
||||
// "os"
|
||||
// "path"
|
||||
)
|
||||
|
||||
type Preview struct {
|
||||
Blog
|
||||
}
|
||||
|
||||
// 得到要预览的主题绝对路径
|
||||
func (c Preview) getPreviewThemeAbsolutePath(themeId string) bool {
|
||||
if themeId != "" {
|
||||
c.Session["themeId"] = themeId // 存到session中, 下次的url就不能带了
|
||||
} else {
|
||||
themeId = c.Session["themeId"] // 直接从session中获取
|
||||
}
|
||||
if themeId == "" {
|
||||
return false
|
||||
}
|
||||
theme := themeService.GetTheme(c.GetUserId(), themeId)
|
||||
|
||||
c.RenderArgs["isPreview"] = true
|
||||
c.RenderArgs["themePath"] = theme.Path
|
||||
if theme.Path == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c Preview) Index(userIdOrEmail string, themeId string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath(themeId) {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Index(c.GetUserId())
|
||||
// return blog.RenderTemplate("index.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(themeId))
|
||||
}
|
||||
|
||||
func (c Preview) Tag(userIdOrEmail, tag string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Tag(c.GetUserId(), tag)
|
||||
}
|
||||
func (c Preview) Tags(userIdOrEmail string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Tags(c.GetUserId())
|
||||
// if tag == "" {
|
||||
// return blog.RenderTemplate("tags.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
// }
|
||||
// return blog.RenderTemplate("tag_posts.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Archives(userIdOrEmail string, notebookId string, year, month int) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Archives(c.GetUserId(), notebookId, year, month)
|
||||
// return blog.RenderTemplate("archive.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Cate(userIdOrEmail, notebookId string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Cate(userIdOrEmail, notebookId)
|
||||
// return blog.RenderTemplate("cate.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Post(userIdOrEmail, noteId string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Post(userIdOrEmail, noteId)
|
||||
// return blog.RenderTemplate("view.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Single(userIdOrEmail, singleId string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Single(userIdOrEmail, singleId)
|
||||
// return blog.RenderTemplate("single.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
func (c Preview) Search(userIdOrEmail, keywords string) revel.Result {
|
||||
if !c.getPreviewThemeAbsolutePath("") {
|
||||
return c.E404()
|
||||
}
|
||||
return c.Blog.Search(c.GetUserId(), keywords)
|
||||
// return blog.RenderTemplate("search.html", c.RenderArgs, c.getPreviewThemeAbsolutePath(""))
|
||||
}
|
||||
@@ -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,8 +87,6 @@ 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
|
||||
@@ -101,9 +99,6 @@ 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
|
||||
@@ -145,44 +140,3 @@ func (c Share) DeleteShareNotebookBySharedUser(notebookId string, fromUserId str
|
||||
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)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -18,8 +18,8 @@ func (c Admin) Index() revel.Result {
|
||||
c.SetLocale()
|
||||
|
||||
c.RenderArgs["countUser"] = userService.CountUser()
|
||||
c.RenderArgs["countNote"] = noteService.CountNote("")
|
||||
c.RenderArgs["countBlog"] = noteService.CountBlog("")
|
||||
c.RenderArgs["countNote"] = noteService.CountNote()
|
||||
c.RenderArgs["countBlog"] = noteService.CountBlog()
|
||||
|
||||
return c.RenderTemplate("admin/index.html");
|
||||
}
|
||||
@@ -30,7 +30,6 @@ 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")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"strings"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// admin 首页
|
||||
@@ -111,15 +110,6 @@ 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)
|
||||
@@ -127,12 +117,3 @@ func (c AdminSetting) Mongodb(mongodumpPath, mongorestorePath string) revel.Resu
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
func (c AdminSetting) UploadSize(uploadImageSize, uploadAvatarSize, uploadBlogLogoSize, uploadAttachSize float64) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "uploadImageSize", fmt.Sprintf("%v", uploadImageSize))
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "uploadAvatarSize", fmt.Sprintf("%v", uploadAvatarSize))
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "uploadBlogLogoSize", fmt.Sprintf("%v", uploadBlogLogoSize))
|
||||
re.Ok = configService.UpdateGlobalStringConfig(c.GetUserId(), "uploadAttachSize", fmt.Sprintf("%v", uploadAttachSize))
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package admin
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
// "io/ioutil"
|
||||
)
|
||||
|
||||
@@ -16,9 +16,3 @@ func (c AdminUpgrade) UpgradeBlog() revel.Result {
|
||||
upgradeService.UpgradeBlog()
|
||||
return nil;
|
||||
}
|
||||
|
||||
func (c AdminUpgrade) UpgradeBetaToBeta2() revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok, re.Msg = upgradeService.UpgradeBetaToBeta2(c.GetUserId())
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
@@ -2,9 +2,7 @@ package admin
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "time"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
)
|
||||
|
||||
// admin 首页
|
||||
@@ -15,13 +13,10 @@ type AdminUser struct {
|
||||
|
||||
// admin 主页
|
||||
var userPageSize = 10
|
||||
func (c AdminUser) Index(sorter, keywords string, pageSize int) revel.Result {
|
||||
func (c AdminUser) Index(sorter, keywords string) revel.Result {
|
||||
pageNumber := c.GetPage()
|
||||
if userPageSize == 0 {
|
||||
pageSize = userPageSize
|
||||
}
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "username", "verified", "createdTime", "accountType"});
|
||||
pageInfo, users := userService.ListUsers(pageNumber, pageSize, sorterField, isAsc, keywords);
|
||||
sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"email", "username", "verified", "createdTime"});
|
||||
pageInfo, users := userService.ListUsers(pageNumber, userPageSize, sorterField, isAsc, keywords);
|
||||
c.RenderArgs["pageInfo"] = pageInfo
|
||||
c.RenderArgs["users"] = users
|
||||
c.RenderArgs["keywords"] = keywords
|
||||
@@ -31,36 +26,3 @@ func (c AdminUser) Index(sorter, keywords string, pageSize int) revel.Result {
|
||||
func (c AdminUser) Add() revel.Result {
|
||||
return c.RenderTemplate("admin/user/add.html");
|
||||
}
|
||||
|
||||
// 添加
|
||||
func (c AdminUser) Register(email, pwd string) revel.Result {
|
||||
re := info.NewRe();
|
||||
|
||||
if re.Ok, re.Msg = Vd("email", email); !re.Ok {
|
||||
return c.RenderRe(re);
|
||||
}
|
||||
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
|
||||
return c.RenderRe(re);
|
||||
}
|
||||
|
||||
// 注册
|
||||
re.Ok, re.Msg = authService.Register(email, pwd)
|
||||
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
// 修改帐户
|
||||
func (c AdminUser) ResetPwd(userId string) revel.Result {
|
||||
userInfo := userService.GetUserInfo(userId)
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
return c.RenderTemplate("admin/user/reset_pwd.html");
|
||||
}
|
||||
|
||||
func (c AdminUser) DoResetPwd(userId, pwd string) revel.Result {
|
||||
re := info.NewRe();
|
||||
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
|
||||
return c.RenderRe(re);
|
||||
}
|
||||
re.Ok, re.Msg = userService.ResetPwd(c.GetUserId(), userId, pwd)
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
@@ -28,6 +28,7 @@ var configService *service.ConfigService
|
||||
var emailService *service.EmailService
|
||||
var upgradeService *service.UpgradeService
|
||||
|
||||
var adminUsername = "admin"
|
||||
// 拦截器
|
||||
// 不需要拦截的url
|
||||
// Index 除了Note之外都不需要
|
||||
@@ -82,7 +83,7 @@ func AuthInterceptor(c *revel.Controller) revel.Result {
|
||||
|
||||
// 验证是否已登录
|
||||
// 必须是管理员
|
||||
if username, ok := c.Session["Username"]; ok && username == configService.GetAdminUsername() {
|
||||
if username, ok := c.Session["Username"]; ok && username == adminUsername {
|
||||
return nil // 已登录
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// "strconv"
|
||||
)
|
||||
|
||||
// 用户登录后生成一个token, 将这个token保存到session中
|
||||
// 以后每次的请求必须带这个token, 并从session中获取userId
|
||||
|
||||
// 用户登录/注销/找回密码
|
||||
|
||||
type ApiAuth struct {
|
||||
ApiBaseContrller
|
||||
}
|
||||
|
||||
// 为了demo和register
|
||||
func (c ApiAuth) doLogin(email, pwd string) revel.Result {
|
||||
sessionId := c.Session.Id()
|
||||
var msg = ""
|
||||
|
||||
userInfo := authService.Login(email, pwd)
|
||||
if userInfo.Email != "" {
|
||||
c.SetSession(userInfo)
|
||||
sessionService.ClearLoginTimes(sessionId)
|
||||
return c.RenderJson(info.Re{Ok: true})
|
||||
} else {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
}
|
||||
|
||||
return c.RenderJson(info.Re{Ok: false, Item: sessionService.LoginTimesIsOver(sessionId) , Msg: c.Message(msg)})
|
||||
}
|
||||
func (c ApiAuth) Login(email, pwd string, captcha string) revel.Result {
|
||||
sessionId := c.Session.Id()
|
||||
var msg = ""
|
||||
|
||||
// > 5次需要验证码, 直到登录成功
|
||||
if sessionService.LoginTimesIsOver(sessionId) && sessionService.GetCaptcha(sessionId) != captcha {
|
||||
msg = "captchaError"
|
||||
} else {
|
||||
userInfo := authService.Login(email, pwd)
|
||||
if userInfo.Email != "" {
|
||||
c.SetSession(userInfo)
|
||||
sessionService.ClearLoginTimes(sessionId)
|
||||
return c.RenderJson(info.Re{Ok: true})
|
||||
} else {
|
||||
// 登录错误, 则错误次数++
|
||||
msg = "wrongUsernameOrPassword"
|
||||
sessionService.IncrLoginTimes(sessionId)
|
||||
}
|
||||
}
|
||||
|
||||
return c.RenderJson(info.Re{Ok: false, Item: sessionService.LoginTimesIsOver(sessionId) , Msg: c.Message(msg)})
|
||||
}
|
||||
|
||||
// 注销
|
||||
func (c ApiAuth) Logout() revel.Result {
|
||||
sessionId := c.Session.Id()
|
||||
sessionService.Clear(sessionId)
|
||||
c.ClearSession()
|
||||
re := info.NewRe()
|
||||
re.Ok = true
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 体验一下
|
||||
func (c ApiAuth) Demo() revel.Result {
|
||||
c.doLogin(configService.GetGlobalStringConfig("demoUsername"), configService.GetGlobalStringConfig("demoPassword"))
|
||||
return c.Redirect("/note")
|
||||
}
|
||||
|
||||
//--------
|
||||
// 注册
|
||||
func (c ApiAuth) Register(from string) revel.Result {
|
||||
if !configService.IsOpenRegister() {
|
||||
return c.Redirect("/index")
|
||||
}
|
||||
c.SetLocale()
|
||||
c.RenderArgs["from"] = from
|
||||
|
||||
c.RenderArgs["title"] = c.Message("register")
|
||||
c.RenderArgs["subTitle"] = c.Message("register")
|
||||
return c.RenderTemplate("home/register.html")
|
||||
}
|
||||
func (c ApiAuth) DoRegister(email, pwd string) revel.Result {
|
||||
if !configService.IsOpenRegister() {
|
||||
return c.Redirect("/index")
|
||||
}
|
||||
|
||||
re := info.NewRe();
|
||||
|
||||
if re.Ok, re.Msg = Vd("email", email); !re.Ok {
|
||||
return c.RenderRe(re);
|
||||
}
|
||||
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
|
||||
return c.RenderRe(re);
|
||||
}
|
||||
|
||||
// 注册
|
||||
re.Ok, re.Msg = authService.Register(email, pwd)
|
||||
|
||||
// 注册成功, 则立即登录之
|
||||
if re.Ok {
|
||||
c.doLogin(email, pwd)
|
||||
}
|
||||
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
|
||||
//--------
|
||||
// 找回密码
|
||||
func (c ApiAuth) FindPassword() revel.Result {
|
||||
c.RenderArgs["title"] = c.Message("findPassword")
|
||||
c.RenderArgs["subTitle"] = c.Message("findPassword")
|
||||
return c.RenderTemplate("home/find_password.html")
|
||||
}
|
||||
func (c ApiAuth) DoFindPassword(email string) revel.Result {
|
||||
pwdService.FindPwd(email)
|
||||
re := info.NewRe()
|
||||
re.Ok = true
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
// 点击链接后, 先验证之
|
||||
func (c ApiAuth) FindPassword2(token string) revel.Result {
|
||||
c.RenderArgs["title"] = c.Message("findPassword")
|
||||
c.RenderArgs["subTitle"] = c.Message("findPassword")
|
||||
if token == "" {
|
||||
return c.RenderTemplate("find_password2_timeout.html")
|
||||
}
|
||||
ok, _, findPwd := tokenService.VerifyToken(token, info.TokenPwd);
|
||||
if !ok {
|
||||
return c.RenderTemplate("home/find_password2_timeout.html")
|
||||
}
|
||||
c.RenderArgs["findPwd"] = findPwd
|
||||
|
||||
c.RenderArgs["title"] = c.Message("updatePassword")
|
||||
c.RenderArgs["subTitle"] = c.Message("updatePassword")
|
||||
|
||||
return c.RenderTemplate("home/find_password2.html")
|
||||
}
|
||||
// 找回密码修改密码
|
||||
func (c ApiAuth) FindPasswordUpdate(token, pwd string) revel.Result {
|
||||
re := info.NewRe();
|
||||
|
||||
if re.Ok, re.Msg = Vd("password", pwd); !re.Ok {
|
||||
return c.RenderRe(re);
|
||||
}
|
||||
|
||||
// 修改之
|
||||
re.Ok, re.Msg = pwdService.UpdatePwd(token, pwd)
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
// "github.com/revel/revel"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "strconv"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
// 公用Controller, 其它Controller继承它
|
||||
type ApiBaseContrller struct {
|
||||
controllers.BaseController // 不能用*BaseController
|
||||
}
|
||||
@@ -11,12 +11,13 @@ import (
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "os"
|
||||
|
||||
// "path"
|
||||
// "strconv"
|
||||
)
|
||||
|
||||
type ApiUser struct {
|
||||
*revel.Controller
|
||||
ApiBaseContrller
|
||||
}
|
||||
|
||||
// 修改用户名, 需要重置session
|
||||
@@ -1,15 +1,14 @@
|
||||
package member
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
// "strings"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var userService *service.UserService
|
||||
var groupService *service.GroupService
|
||||
var noteService *service.NoteService
|
||||
var trashService *service.TrashService
|
||||
var notebookService *service.NotebookService
|
||||
@@ -27,8 +26,12 @@ var fileService *service.FileService
|
||||
var attachService *service.AttachService
|
||||
var configService *service.ConfigService
|
||||
var emailService *service.EmailService
|
||||
var upgradeService *service.UpgradeService
|
||||
var themeService *service.ThemeService
|
||||
var sessionService *service.SessionService
|
||||
|
||||
var pageSize = 1000
|
||||
var defaultSortField = "UpdatedTime"
|
||||
var leanoteUserId = "admin" // 不能更改
|
||||
var siteUrl = "http://leanote.com"
|
||||
|
||||
// 拦截器
|
||||
// 不需要拦截的url
|
||||
@@ -45,10 +48,15 @@ var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": tru
|
||||
"FindPasswordUpdate": true,
|
||||
"Suggestion": true,
|
||||
},
|
||||
"Note": map[string]bool{"ToImage": true},
|
||||
"Blog": map[string]bool{"Index": true,
|
||||
"View": true,
|
||||
"AboutMe": true,
|
||||
"SearchBlog": true,
|
||||
"Cate": true,
|
||||
"Search": true,
|
||||
"GetLikeAndComments": true,
|
||||
"IncReadNum": true,
|
||||
"ListComments": true,
|
||||
},
|
||||
// 用户的激活与修改邮箱都不需要登录, 通过链接地址
|
||||
"User": map[string]bool{"UpdateEmail": true,
|
||||
@@ -73,18 +81,16 @@ func needValidate(controller, method string) bool {
|
||||
}
|
||||
func AuthInterceptor(c *revel.Controller) revel.Result {
|
||||
// 全部变成首字大写
|
||||
/*
|
||||
var controller = strings.Title(c.Name)
|
||||
var method = strings.Title(c.MethodName)
|
||||
|
||||
// 是否需要验证?
|
||||
if !needValidate(controller, method) {
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
// 验证是否已登录
|
||||
// 必须是管理员
|
||||
if _, ok := c.Session["Username"]; ok {
|
||||
if userId, ok := c.Session["UserId"]; ok && userId != "" {
|
||||
return nil // 已登录
|
||||
}
|
||||
|
||||
@@ -107,7 +113,6 @@ func InitService() {
|
||||
trashService = service.TrashS
|
||||
shareService = service.ShareS
|
||||
userService = service.UserS
|
||||
groupService = service.GroupS
|
||||
tagService = service.TagS
|
||||
blogService = service.BlogS
|
||||
tokenService = service.TokenS
|
||||
@@ -120,14 +125,15 @@ func InitService() {
|
||||
authService = service.AuthS
|
||||
configService = service.ConfigS
|
||||
emailService = service.EmailS
|
||||
upgradeService = service.UpgradeS
|
||||
themeService = service.ThemeS
|
||||
sessionService = service.SessionS
|
||||
}
|
||||
|
||||
func init() {
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberIndex{})
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberUser{})
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberBlog{})
|
||||
// interceptors
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &ApiAuth{})
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &ApiUser{})
|
||||
|
||||
revel.OnAppStart(func() {
|
||||
siteUrl, _ = revel.Config.String("site.url")
|
||||
})
|
||||
}
|
||||
+5
-17
@@ -3,7 +3,6 @@ package controllers
|
||||
import (
|
||||
"github.com/leanote/leanote/app/service"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/lea/blog"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"strings"
|
||||
@@ -28,10 +27,11 @@ var attachService *service.AttachService
|
||||
var configService *service.ConfigService
|
||||
var emailService *service.EmailService
|
||||
var sessionService *service.SessionService
|
||||
var themeService *service.ThemeService
|
||||
|
||||
var pageSize = 1000
|
||||
var defaultSortField = "UpdatedTime"
|
||||
var leanoteUserId = "admin" // 不能更改
|
||||
var siteUrl = "http://leanote.com"
|
||||
|
||||
// 拦截器
|
||||
// 不需要拦截的url
|
||||
@@ -53,14 +53,10 @@ var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": tru
|
||||
"View": true,
|
||||
"AboutMe": true,
|
||||
"Cate": true,
|
||||
"ListCateLatest": true,
|
||||
"Search": true,
|
||||
"GetLikeAndComments": true,
|
||||
"IncReadNum": true,
|
||||
"ListComments": true,
|
||||
"Single": true,
|
||||
"Archive": true,
|
||||
"Tags": true,
|
||||
},
|
||||
// 用户的激活与修改邮箱都不需要登录, 通过链接地址
|
||||
"User": map[string]bool{"UpdateEmail": true,
|
||||
@@ -70,7 +66,6 @@ var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": tru
|
||||
"File": map[string]bool{"OutputImage": true, "OutputFile": true},
|
||||
"Attach": map[string]bool{"Download": true, "DownloadAll": true},
|
||||
}
|
||||
|
||||
func needValidate(controller, method string) bool {
|
||||
// 在里面
|
||||
if v, ok := commonUrl[controller]; ok {
|
||||
@@ -81,7 +76,7 @@ func needValidate(controller, method string) bool {
|
||||
return true
|
||||
} else {
|
||||
// controller不在这里的, 肯定要验证
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
func AuthInterceptor(c *revel.Controller) revel.Result {
|
||||
@@ -131,12 +126,6 @@ func InitService() {
|
||||
configService = service.ConfigS
|
||||
emailService = service.EmailS
|
||||
sessionService = service.SessionS
|
||||
themeService = service.ThemeS
|
||||
}
|
||||
|
||||
// 初始化博客模板
|
||||
// 博客模板不由revel的
|
||||
func initBlogTemplate() {
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -148,11 +137,10 @@ func init() {
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &User{})
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &File{})
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &Attach{})
|
||||
// revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &Blog{})
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &Blog{})
|
||||
revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &NoteContentHistory{})
|
||||
|
||||
revel.OnAppStart(func() {
|
||||
// 博客初始化模板
|
||||
blog.Init()
|
||||
siteUrl, _ = revel.Config.String("site.url")
|
||||
})
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package member
|
||||
|
||||
import (
|
||||
// "github.com/revel/revel"
|
||||
// "gopkg.in/mgo.v2/bson"
|
||||
// "encoding/json"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
// "io/ioutil"
|
||||
// "fmt"
|
||||
// "math"
|
||||
// "strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 公用Controller, 其它Controller继承它
|
||||
type MemberBaseController struct {
|
||||
controllers.BaseController // 不能用*BaseController
|
||||
}
|
||||
|
||||
// 得到sorterField 和 isAsc
|
||||
// okSorter = ['email', 'username']
|
||||
func (c MemberBaseController) 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;
|
||||
}
|
||||
|
||||
func (c MemberBaseController) updateConfig(keys []string) {
|
||||
userId := c.GetUserId()
|
||||
for _, key := range keys {
|
||||
v := c.Params.Values.Get(key)
|
||||
configService.UpdateGlobalStringConfig(userId, key, v)
|
||||
}
|
||||
}
|
||||
@@ -1,519 +0,0 @@
|
||||
package member
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
"fmt"
|
||||
"strings"
|
||||
// "github.com/leanote/leanote/app/lea/blog"
|
||||
)
|
||||
|
||||
// 博客管理
|
||||
|
||||
type MemberBlog struct {
|
||||
MemberBaseController
|
||||
}
|
||||
|
||||
func (c MemberBlog) common() info.UserBlog {
|
||||
userId := c.GetUserId()
|
||||
userInfo := userService.GetUserInfo(userId)
|
||||
c.RenderArgs["userInfo"] = userInfo
|
||||
|
||||
// 得到博客设置信息
|
||||
c.RenderArgs["allowCustomDomain"] = configService.GetGlobalStringConfig("allowCustomDomain")
|
||||
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
c.RenderArgs["userBlog"] = userBlog
|
||||
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
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()
|
||||
c.RenderArgs["title"] = "Blog Base Info"
|
||||
return c.RenderTemplate("member/blog/base.html");
|
||||
}
|
||||
func (c MemberBlog) Comment() revel.Result {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Comment"
|
||||
return c.RenderTemplate("member/blog/comment.html");
|
||||
}
|
||||
func (c MemberBlog) Domain() revel.Result {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Domain"
|
||||
return c.RenderTemplate("member/blog/domain.html");
|
||||
}
|
||||
|
||||
func (c MemberBlog) Paging() revel.Result {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Paging"
|
||||
return c.RenderTemplate("member/blog/paging.html");
|
||||
}
|
||||
|
||||
func (c MemberBlog) Cate() revel.Result {
|
||||
userBlog := c.common()
|
||||
c.RenderArgs["title"] = "Cate"
|
||||
|
||||
notebooks := blogService.ListBlogNotebooks(c.GetUserId())
|
||||
notebooksMap := map[string]info.Notebook{}
|
||||
for _, each := range notebooks {
|
||||
notebooksMap[each.NotebookId.Hex()] = each
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
notebooks2 := make([]info.Notebook, len(notebooks))
|
||||
|
||||
// 先要保证已有的是正确的排序
|
||||
cateIds := userBlog.CateIds
|
||||
has := map[string]bool{} // cateIds中有的
|
||||
if cateIds != nil && len(cateIds) > 0 {
|
||||
for _, cateId := range cateIds {
|
||||
if n, ok := notebooksMap[cateId]; ok {
|
||||
notebooks2[i] = n
|
||||
i++
|
||||
has[cateId] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// 之后
|
||||
for _, each := range notebooks {
|
||||
id := each.NotebookId.Hex()
|
||||
if !has[id] {
|
||||
notebooks2[i] = each
|
||||
i++
|
||||
}
|
||||
}
|
||||
c.RenderArgs["notebooks"] = notebooks2
|
||||
|
||||
return c.RenderTemplate("member/blog/cate.html");
|
||||
}
|
||||
|
||||
// 修改分类排序
|
||||
func (c MemberBlog) UpateCateIds(cateIds []string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = blogService.UpateCateIds(c.GetUserId(), cateIds)
|
||||
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()
|
||||
re.Ok = blogService.AddOrUpdateSingle(c.GetUserId(), singleId, title, content)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c MemberBlog) AddOrUpdateSingle(singleId string) revel.Result {
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Add Single"
|
||||
c.RenderArgs["singleId"] = singleId
|
||||
if singleId != "" {
|
||||
c.RenderArgs["single"] = blogService.GetSingle(singleId)
|
||||
}
|
||||
return c.RenderTemplate("member/blog/add_single.html");
|
||||
}
|
||||
func (c MemberBlog) SortSingles(singleIds []string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = blogService.SortSingles(c.GetUserId(), singleIds)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
func (c MemberBlog) DeleteSingle(singleId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
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"
|
||||
c.RenderArgs["singles"] = blogService.GetSingles(c.GetUserId())
|
||||
|
||||
return c.RenderTemplate("member/blog/single.html");
|
||||
}
|
||||
|
||||
// 主题
|
||||
func (c MemberBlog) Theme() revel.Result {
|
||||
c.common()
|
||||
activeTheme, otherThemes := themeService.GetUserThemes(c.GetUserId())
|
||||
c.RenderArgs["activeTheme"] = activeTheme
|
||||
c.RenderArgs["otherThemes"] = otherThemes
|
||||
|
||||
c.RenderArgs["optionThemes"] = themeService.GetDefaultThemes()
|
||||
|
||||
c.RenderArgs["title"] = "Theme"
|
||||
return c.RenderTemplate("member/blog/theme.html");
|
||||
}
|
||||
|
||||
// 编辑主题
|
||||
var baseTpls = []string{"header.html", "footer.html", "index.html", "cate.html", "search.html", "post.html", "single.html", "tags.html", "tag_posts.html", "archive.html", "share_comment.html", "404.html", "theme.json", "style.css", "blog.js"}
|
||||
func (c MemberBlog) UpdateTheme(themeId string, isNew int) revel.Result {
|
||||
// 查看用户是否有该theme, 若没有则复制default之
|
||||
// 得到主题的文件列表
|
||||
userBlog := blogService.GetUserBlog(c.GetUserId())
|
||||
if themeId == "" {
|
||||
_, themeId = themeService.NewThemeForFirst(userBlog)
|
||||
return c.Redirect("/member/blog/updateTheme?themeId=" + themeId)
|
||||
}
|
||||
|
||||
c.common()
|
||||
c.RenderArgs["title"] = "Upate Theme"
|
||||
c.RenderArgs["isNew"] = isNew
|
||||
|
||||
// 先复制之
|
||||
c.RenderArgs["themeId"] = themeId
|
||||
|
||||
// 得到脚本目录
|
||||
userId := c.GetUserId()
|
||||
|
||||
theme := themeService.GetTheme(userId, themeId)
|
||||
c.RenderArgs["theme"] = theme
|
||||
|
||||
path := revel.BasePath + "/" + theme.Path
|
||||
|
||||
tpls := ListDir(path)
|
||||
myTpls := make([]string, len(baseTpls))
|
||||
tplMap := map[string]bool{}
|
||||
for i, t := range baseTpls {
|
||||
myTpls[i] = t
|
||||
tplMap[t] = true
|
||||
}
|
||||
// 得到没有的tpls
|
||||
for _, t := range tpls {
|
||||
if t == "images" {
|
||||
continue;
|
||||
}
|
||||
if !tplMap[t] {
|
||||
myTpls = append(myTpls, t)
|
||||
}
|
||||
}
|
||||
|
||||
c.RenderArgs["myTpls"] = myTpls
|
||||
|
||||
return c.RenderTemplate("member/blog/update_theme.html");
|
||||
}
|
||||
|
||||
// 得到文件内容
|
||||
func (c MemberBlog) GetTplContent(themeId string, filename string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = true
|
||||
re.Item = themeService.GetTplContent(c.GetUserId(), themeId, filename)
|
||||
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c MemberBlog) UpdateTplContent(themeId, filename, content string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok, re.Msg = themeService.UpdateTplContent(c.GetUserId(), themeId, filename, content)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
func (c MemberBlog) DeleteTpl(themeId, filename string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = themeService.DeleteTpl(c.GetUserId(), themeId, filename)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
func (c MemberBlog) ListThemeImages(themeId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
userId := c.GetUserId()
|
||||
path := themeService.GetThemeAbsolutePath(userId, themeId) + "/images"
|
||||
os.MkdirAll(path, 0755)
|
||||
images := ListDir(path)
|
||||
re.List = images
|
||||
re.Ok = true
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
func (c MemberBlog) DeleteThemeImage(themeId, filename string) revel.Result {
|
||||
re := info.NewRe()
|
||||
path := themeService.GetThemeAbsolutePath(c.GetUserId(), themeId) + "/images/" + filename
|
||||
re.Ok = DeleteFile(path)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 上传主题图片
|
||||
func (c MemberBlog) UploadThemeImage(themeId string) revel.Result {
|
||||
re := c.uploadImage(themeId);
|
||||
c.RenderArgs["fileUrlPath"] = re.Id
|
||||
c.RenderArgs["resultCode"] = re.Code
|
||||
c.RenderArgs["resultMsg"] = re.Msg
|
||||
return c.RenderTemplate("file/blog_logo.html")
|
||||
}
|
||||
func (c MemberBlog) uploadImage(themeId string) (re info.Re) {
|
||||
var fileId = ""
|
||||
var resultCode = 0 // 1表示正常
|
||||
var resultMsg = "内部错误" // 错误信息
|
||||
var Ok = false
|
||||
|
||||
defer func() {
|
||||
re.Id = fileId // 只是id, 没有其它信息
|
||||
re.Code = resultCode
|
||||
re.Msg = resultMsg
|
||||
re.Ok = Ok
|
||||
}()
|
||||
|
||||
file, handel, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
defer file.Close()
|
||||
// 生成上传路径
|
||||
dir := themeService.GetThemeAbsolutePath(c.GetUserId(), themeId) + "/images"
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
// 生成新的文件名
|
||||
filename := handel.Filename
|
||||
|
||||
var ext string;
|
||||
|
||||
_, ext = SplitFilename(filename)
|
||||
if(ext != ".gif" && ext != ".jpg" && ext != ".png" && ext != ".bmp" && ext != ".jpeg") {
|
||||
resultMsg = "不是图片"
|
||||
return re
|
||||
}
|
||||
|
||||
filename = filename
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
LogJ(err)
|
||||
return re
|
||||
}
|
||||
|
||||
// > 2M?
|
||||
if(len(data) > 5 * 1024 * 1024) {
|
||||
resultCode = 0
|
||||
resultMsg = "图片大于2M"
|
||||
return re
|
||||
}
|
||||
|
||||
toPath := dir + "/" + filename;
|
||||
err = ioutil.WriteFile(toPath, data, 0777)
|
||||
if err != nil {
|
||||
LogJ(err)
|
||||
return re
|
||||
}
|
||||
TransToGif(toPath, 0, true)
|
||||
resultCode = 1
|
||||
resultMsg = "上传成功!"
|
||||
|
||||
return re
|
||||
}
|
||||
|
||||
//
|
||||
// 使用主题
|
||||
func (c MemberBlog) ActiveTheme(themeId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = themeService.ActiveTheme(c.GetUserId(), themeId)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
// 删除主题
|
||||
func (c MemberBlog) DeleteTheme(themeId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = themeService.DeleteTheme(c.GetUserId(), themeId)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
// 管理员公开主题
|
||||
func (c MemberBlog) PublicTheme(themeId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = themeService.PublicTheme(c.GetUserId(), themeId)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
// 导出
|
||||
func (c MemberBlog) ExportTheme(themeId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
var path string
|
||||
re.Ok, path = themeService.ExportTheme(c.GetUserId(), themeId)
|
||||
if !re.Ok {
|
||||
return c.RenderText("error...")
|
||||
}
|
||||
fw, err := os.Open(path)
|
||||
if err != nil {
|
||||
return c.RenderText("error")
|
||||
}
|
||||
return c.RenderBinary(fw, GetFilename(path), revel.Attachment, time.Now()) // revel.Attachment
|
||||
}
|
||||
|
||||
// 导入主题
|
||||
func (c MemberBlog) ImportTheme() revel.Result {
|
||||
re := info.NewRe()
|
||||
|
||||
file, handel, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
re.Msg = fmt.Sprintf("%v", err)
|
||||
return c.RenderJson(re)
|
||||
|
||||
}
|
||||
defer file.Close()
|
||||
// 生成上传路径
|
||||
userId := c.GetUserId()
|
||||
dir := revel.BasePath + "/public/upload/" + userId + "/tmp"
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
re.Msg = fmt.Sprintf("%v", err)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
// 生成新的文件名
|
||||
filename := handel.Filename
|
||||
|
||||
var ext string;
|
||||
_, ext = SplitFilename(filename)
|
||||
if(ext != ".zip") {
|
||||
re.Msg = "请上传zip文件"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
filename = filename
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// > 10M?
|
||||
if(len(data) > 10 * 1024 * 1024) {
|
||||
re.Msg = "文件大于10M"
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
toPath := dir + "/" + filename;
|
||||
err = ioutil.WriteFile(toPath, data, 0777)
|
||||
if err != nil {
|
||||
re.Msg = fmt.Sprintf("%v", err)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 上传好后, 增加之
|
||||
themeService.ImportTheme(c.GetUserId(), toPath)
|
||||
|
||||
re.Ok = true
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 安装
|
||||
func (c MemberBlog) InstallTheme(themeId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = themeService.InstallTheme(c.GetUserId(), themeId)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
// 新建主题
|
||||
func (c MemberBlog) NewTheme() revel.Result {
|
||||
_, themeId := themeService.NewTheme(c.GetUserId())
|
||||
return c.Redirect("/member/blog/updateTheme?isNew=1&themeId=" + themeId)
|
||||
}
|
||||
//-----------
|
||||
//
|
||||
func (c MemberBlog) SetUserBlogBase(userBlog info.UserBlogBase) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = blogService.UpdateUserBlogBase(c.GetUserId(), userBlog)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c MemberBlog) SetUserBlogComment(userBlog info.UserBlogComment) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = blogService.UpdateUserBlogComment(c.GetUserId(), userBlog)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c MemberBlog) SetUserBlogStyle(userBlog info.UserBlogStyle) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = blogService.UpdateUserBlogStyle(c.GetUserId(), userBlog)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c MemberBlog) SetUserBlogPaging(perPageSize int, sortField string, isAsc bool) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok, re.Msg = blogService.UpdateUserBlogPaging(c.GetUserId(), perPageSize, sortField, isAsc)
|
||||
return c.RenderRe(re)
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
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)
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package member
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// admin 首页
|
||||
|
||||
type MemberIndex struct {
|
||||
MemberBaseController
|
||||
}
|
||||
|
||||
// admin 主页
|
||||
func (c MemberIndex) Index() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.RenderArgs["title"] = "Leanote Member Center"
|
||||
|
||||
c.RenderArgs["countNote"] = noteService.CountNote(c.GetUserId())
|
||||
c.RenderArgs["countBlog"] = noteService.CountBlog(c.GetUserId())
|
||||
|
||||
c.SetLocale()
|
||||
|
||||
return c.RenderTemplate("member/index.html");
|
||||
}
|
||||
|
||||
// 模板
|
||||
func (c MemberIndex) T(t string) revel.Result {
|
||||
c.RenderArgs["str"] = configService.GlobalStringConfigs
|
||||
c.RenderArgs["arr"] = configService.GlobalArrayConfigs
|
||||
c.RenderArgs["map"] = configService.GlobalMapConfigs
|
||||
c.RenderArgs["arrMap"] = configService.GlobalArrMapConfigs
|
||||
return c.RenderTemplate("admin/" + t + ".html")
|
||||
}
|
||||
|
||||
func (c MemberIndex) GetView(view string) revel.Result {
|
||||
return c.RenderTemplate("admin/" + view);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package member
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// 帐户信息
|
||||
|
||||
type MemberUser struct {
|
||||
MemberBaseController
|
||||
}
|
||||
|
||||
func (c MemberUser) Username() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Username"
|
||||
return c.RenderTemplate("member/user/username.html");
|
||||
}
|
||||
|
||||
func (c MemberUser) Email() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Email"
|
||||
return c.RenderTemplate("member/user/email.html");
|
||||
}
|
||||
|
||||
func (c MemberUser) Password() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Password"
|
||||
return c.RenderTemplate("member/user/password.html");
|
||||
}
|
||||
|
||||
func (c MemberUser) Avatar() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Avatar"
|
||||
c.RenderArgs["globalConfigs"] = configService.GetGlobalConfigForUser()
|
||||
return c.RenderTemplate("member/user/avatar.html");
|
||||
}
|
||||
func (c MemberUser) AddAccount() revel.Result {
|
||||
c.SetUserInfo()
|
||||
c.SetLocale()
|
||||
c.RenderArgs["title"] = "Add Account"
|
||||
return c.RenderTemplate("member/user/add_account.html");
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
包括基本信息设置
|
||||
博客设置
|
||||
+5
-29
@@ -2,9 +2,9 @@ package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/revel/revel"
|
||||
"gopkg.in/mgo.v2"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// Init mgo and the common DAO
|
||||
@@ -23,12 +23,9 @@ var ShareNotebooks *mgo.Collection
|
||||
var HasShareNotes *mgo.Collection
|
||||
var Blogs *mgo.Collection
|
||||
var Users *mgo.Collection
|
||||
var Groups *mgo.Collection
|
||||
var GroupUsers *mgo.Collection
|
||||
|
||||
var Tags *mgo.Collection
|
||||
//var TagNotes *mgo.Collection
|
||||
var TagCounts *mgo.Collection
|
||||
var TagNotes *mgo.Collection
|
||||
|
||||
var UserBlogs *mgo.Collection
|
||||
|
||||
@@ -49,8 +46,6 @@ var EmailLogs *mgo.Collection
|
||||
var BlogLikes *mgo.Collection
|
||||
var BlogComments *mgo.Collection
|
||||
var Reports *mgo.Collection
|
||||
var BlogSingles *mgo.Collection
|
||||
var Themes *mgo.Collection
|
||||
|
||||
// session
|
||||
var Sessions *mgo.Collection
|
||||
@@ -59,7 +54,7 @@ var Sessions *mgo.Collection
|
||||
func Init() {
|
||||
var url string
|
||||
var ok bool
|
||||
config := revel.Config
|
||||
config := revel.Config;
|
||||
url, ok = config.String("db.url")
|
||||
dbname, _ := config.String("db.dbname")
|
||||
if !ok {
|
||||
@@ -102,22 +97,16 @@ func Init() {
|
||||
|
||||
// user
|
||||
Users = Session.DB(dbname).C("users")
|
||||
// group
|
||||
Groups = Session.DB(dbname).C("groups")
|
||||
GroupUsers = Session.DB(dbname).C("group_users")
|
||||
|
||||
// blog
|
||||
Blogs = Session.DB(dbname).C("blogs")
|
||||
|
||||
// tag
|
||||
Tags = Session.DB(dbname).C("tags")
|
||||
// TagNotes = Session.DB(dbname).C("tag_notes")
|
||||
TagCounts = Session.DB(dbname).C("tag_count")
|
||||
TagNotes = Session.DB(dbname).C("tag_notes")
|
||||
|
||||
// blog
|
||||
UserBlogs = Session.DB(dbname).C("user_blogs")
|
||||
BlogSingles = Session.DB(dbname).C("blog_singles")
|
||||
Themes = Session.DB(dbname).C("themes")
|
||||
|
||||
// find password
|
||||
Tokens = Session.DB(dbname).C("tokens")
|
||||
@@ -190,24 +179,17 @@ func UpdateByIdAndUserIdField(collection *mgo.Collection, id, userId, field stri
|
||||
func UpdateByIdAndUserIdMap(collection *mgo.Collection, id, userId string, v bson.M) bool {
|
||||
return UpdateByIdAndUserId(collection, id, userId, bson.M{"$set": v})
|
||||
}
|
||||
|
||||
func UpdateByIdAndUserIdField2(collection *mgo.Collection, id, userId bson.ObjectId, field string, value interface{}) bool {
|
||||
return UpdateByIdAndUserId2(collection, id, userId, bson.M{"$set": bson.M{field:value}})
|
||||
}
|
||||
func UpdateByIdAndUserIdMap2(collection *mgo.Collection, id, userId bson.ObjectId, v bson.M) bool {
|
||||
return UpdateByIdAndUserId2(collection, id, userId, bson.M{"$set": v})
|
||||
}
|
||||
|
||||
//
|
||||
func UpdateByQField(collection *mgo.Collection, q interface{}, field string, value interface{}) bool {
|
||||
_, err := collection.UpdateAll(q, bson.M{"$set": bson.M{field: value}})
|
||||
return Err(err)
|
||||
}
|
||||
func UpdateByQI(collection *mgo.Collection, q interface{}, v interface{}) bool {
|
||||
_, err := collection.UpdateAll(q, bson.M{"$set": v})
|
||||
return Err(err)
|
||||
}
|
||||
|
||||
// 查询条件和值
|
||||
func UpdateByQMap(collection *mgo.Collection, q interface{}, v interface{}) bool {
|
||||
_, err := collection.UpdateAll(q, bson.M{"$set": v})
|
||||
@@ -273,7 +255,6 @@ func GetByQWithFields(collection *mgo.Collection, q bson.M, fields []string, i i
|
||||
}
|
||||
collection.Find(q).Select(selector).One(i)
|
||||
}
|
||||
|
||||
// 查询某些字段, q是查询条件, fields是字段名列表
|
||||
func ListByQWithFields(collection *mgo.Collection, q bson.M, fields []string, i interface{}) {
|
||||
selector := make(bson.M, len(fields))
|
||||
@@ -289,11 +270,6 @@ func GetByIdAndUserId2(collection *mgo.Collection, id, userId bson.ObjectId, i i
|
||||
collection.Find(GetIdAndUserIdBsonQ(id, userId)).One(i)
|
||||
}
|
||||
|
||||
// 按field去重
|
||||
func Distinct(collection *mgo.Collection, q bson.M, field string, i interface{}) {
|
||||
collection.Find(q).Distinct(field, i)
|
||||
}
|
||||
|
||||
//----------------------
|
||||
|
||||
func Count(collection *mgo.Collection, q interface{}) int {
|
||||
@@ -327,7 +303,7 @@ func Err(err error) bool {
|
||||
fmt.Println(err)
|
||||
// 删除时, 查找
|
||||
if err.Error() == "not found" {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package info
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 仅仅为了博客的主题
|
||||
|
||||
type BlogInfoCustom struct {
|
||||
UserId string
|
||||
Username string
|
||||
UserLogo string
|
||||
Title string
|
||||
SubTitle string
|
||||
Logo string
|
||||
OpenComment bool
|
||||
CommentType string
|
||||
ThemeId string
|
||||
SubDomain string
|
||||
Domain string
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
NoteId string
|
||||
Title string
|
||||
UrlTitle string
|
||||
ImgSrc string
|
||||
CreatedTime time.Time
|
||||
UpdatedTime time.Time
|
||||
PublicTime time.Time
|
||||
Desc string
|
||||
Abstract string
|
||||
Content string
|
||||
Tags []string
|
||||
CommentNum int
|
||||
ReadNum int
|
||||
LikeNum int
|
||||
IsMarkdown bool
|
||||
}
|
||||
// 归档
|
||||
type ArchiveMonth struct {
|
||||
Month int
|
||||
Posts []*Post
|
||||
}
|
||||
type Archive struct {
|
||||
Year int
|
||||
MonthAchives []ArchiveMonth
|
||||
Posts []*Post
|
||||
}
|
||||
+4
-46
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
type BlogItem struct {
|
||||
Note
|
||||
Abstract string
|
||||
Content string // 可能是content的一部分, 截取. 点击more后就是整个信息了
|
||||
HasMore bool // 是否是否还有
|
||||
User User // 用户信息
|
||||
@@ -19,7 +18,7 @@ type UserBlogBase struct {
|
||||
Logo string `Logo`
|
||||
Title string `Title` // 标题
|
||||
SubTitle string `SubTitle` // 副标题
|
||||
// AboutMe string `AboutMe` // 关于我
|
||||
AboutMe string `AboutMe` // 关于我
|
||||
}
|
||||
|
||||
type UserBlogComment struct {
|
||||
@@ -39,7 +38,7 @@ type UserBlog struct {
|
||||
Logo string `Logo`
|
||||
Title string `Title` // 标题
|
||||
SubTitle string `SubTitle` // 副标题
|
||||
AboutMe string `AboutMe` // 关于我, 弃用
|
||||
AboutMe string `AboutMe` // 关于我
|
||||
|
||||
CanComment bool `CanComment` // 是否可以评论
|
||||
|
||||
@@ -49,38 +48,8 @@ type UserBlog struct {
|
||||
Style string `Style` // 风格
|
||||
Css string `Css` // 自定义css
|
||||
|
||||
ThemeId bson.ObjectId `ThemeId,omitempty` // 主题Id
|
||||
ThemePath string `bson:"ThemePath" json:"-"` // 不存值, 从Theme中获取, 相对路径 public/
|
||||
|
||||
CateIds []string `CateIds,omitempty` // 分类Id, 排序好的
|
||||
Singles []map[string]string `Singles,omitempty` // 单页, 排序好的, map包含: ["Title"], ["SingleId"]
|
||||
|
||||
PerPageSize int `PerPageSize,omitempty`
|
||||
SortField string `SortField` // 排序字段
|
||||
IsAsc bool `IsAsc,omitempty` // 排序类型, 降序, 升序, 默认是false, 表示降序
|
||||
|
||||
SubDomain string `SubDomain` // 二级域名
|
||||
Domain string `Domain` // 自定义域名
|
||||
|
||||
}
|
||||
|
||||
// 博客统计信息
|
||||
type BlogStat struct {
|
||||
NoteId bson.ObjectId `bson:"_id,omitempty"`
|
||||
ReadNum int `ReadNum,omitempty` // 阅读次数 2014/9/28
|
||||
LikeNum int `LikeNum,omitempty` // 点赞次数 2014/9/28
|
||||
CommentNum int `CommentNum,omitempty` // 评论次数 2014/9/28
|
||||
}
|
||||
|
||||
// 单页
|
||||
type BlogSingle struct {
|
||||
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`
|
||||
}
|
||||
|
||||
//------------------------
|
||||
@@ -88,7 +57,7 @@ type BlogSingle struct {
|
||||
|
||||
// 点赞记录
|
||||
type BlogLike struct {
|
||||
LikeId bson.ObjectId `bson:"_id,omitempty"`
|
||||
LikeId bson.ObjectId `bson:"_id"`
|
||||
NoteId bson.ObjectId `NoteId`
|
||||
UserId bson.ObjectId `UserId`
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
@@ -96,7 +65,7 @@ type BlogLike struct {
|
||||
|
||||
// 评论
|
||||
type BlogComment struct {
|
||||
CommentId bson.ObjectId `bson:"_id,omitempty"`
|
||||
CommentId bson.ObjectId `bson:"_id"`
|
||||
NoteId bson.ObjectId `NoteId`
|
||||
|
||||
UserId bson.ObjectId `UserId` // UserId回复ToUserId
|
||||
@@ -115,14 +84,3 @@ 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
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
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`
|
||||
}
|
||||
@@ -21,10 +21,8 @@ type Note struct {
|
||||
IsTrash bool `IsTrash` // 是否是trash, 默认是false
|
||||
|
||||
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
|
||||
|
||||
@@ -13,7 +13,6 @@ 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 新加
|
||||
|
||||
@@ -76,9 +76,7 @@ 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,omitempty"`
|
||||
ToGroupId bson.ObjectId `bson:"ToGroupId,omitempty"` // 分享给的用户组
|
||||
ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息
|
||||
ToUserId bson.ObjectId `bson:"ToUserId"`
|
||||
NotebookId bson.ObjectId `bson:"NotebookId"`
|
||||
Seq int `bson:"Seq"` // 排序
|
||||
Perm int `bson:"Perm"` // 权限, 其下所有notes 0只读, 1可修改
|
||||
@@ -136,9 +134,7 @@ 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,omitempty"`
|
||||
ToGroupId bson.ObjectId `bson:"ToGroupId,omitempty"` // 分享给的用户组
|
||||
ToGroup Group `ToGroup,omitempty` // 仅仅为了显示, 不存储, 分组信息
|
||||
ToUserId bson.ObjectId `bson:"ToUserId"`
|
||||
NoteId bson.ObjectId `bson:"NoteId"`
|
||||
Perm int `bson:"Perm"` // 权限, 0只读, 1可修改
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
|
||||
@@ -5,38 +5,15 @@ import (
|
||||
)
|
||||
|
||||
// 这里主要是为了统计每个tag的note数目
|
||||
// 暂时没用
|
||||
/*
|
||||
type TagNote struct {
|
||||
TagId bson.ObjectId `bson:"_id,omitempty"` // 必须要设置bson:"_id" 不然mgo不会认为是主键
|
||||
UserId bson.ObjectId `bson:"UserId"`
|
||||
Tag string `Title` // 标题
|
||||
NoteNum int `NoteNum` // note数目
|
||||
}
|
||||
*/
|
||||
|
||||
// 每个用户一条记录, 存储用户的所有tags
|
||||
type Tag struct {
|
||||
UserId bson.ObjectId `bson:"_id"`
|
||||
Tags []string `Tags`
|
||||
}
|
||||
|
||||
type TagCount struct {
|
||||
TagCountId bson.ObjectId `bson:"_id,omitempty"`
|
||||
UserId bson.ObjectId `UserId` // 谁的
|
||||
Tag string `Tag`
|
||||
IsBlog bool `IsBlog` // 是否是博客的tag统计
|
||||
Count int `Count` // 统计数量
|
||||
}
|
||||
/*
|
||||
type TagsCounts []TagCount
|
||||
func (this TagsCounts) Len() int {
|
||||
return len(this)
|
||||
}
|
||||
func (this TagsCounts) Less(i, j int) bool {
|
||||
return this[i].Count > this[j].Count
|
||||
}
|
||||
func (this TagsCounts) Swap(i, j int) {
|
||||
this[i], this[j] = this[j], this[i]
|
||||
}
|
||||
*/
|
||||
@@ -1,26 +0,0 @@
|
||||
package info
|
||||
|
||||
import (
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 主题, 每个用户有多个主题, 这里面有主题的配置信息
|
||||
// 模板, css, js, images, 都在路径Path下
|
||||
type Theme struct {
|
||||
ThemeId bson.ObjectId `bson:"_id,omitempty"` // 必须要设置bson:"_id" 不然mgo不会认为是主键
|
||||
UserId bson.ObjectId `UserId`
|
||||
Name string `Name`
|
||||
Version string `Version`
|
||||
Author string `Author`
|
||||
AuthorUrl string `AuthorUrl`
|
||||
Path string `Path` // 文件夹路径
|
||||
Info map[string]interface{} `Info` // 所有信息
|
||||
IsActive bool `IsActive` // 是否在用
|
||||
|
||||
IsDefault bool `IsDefault` // leanote默认主题, 如果用户修改了默认主题, 则先copy之. 也是admin用户的主题
|
||||
Style string `Style,omitempty` // 之前的, 只有default的用户才有blog_default, blog_daqi, blog_left_fixed
|
||||
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
UpdatedTime time.Time `UpdatedTime`
|
||||
}
|
||||
@@ -34,47 +34,4 @@ type User struct {
|
||||
ThirdUserId string `ThirdUserId` // 用户Id, 在第三方中唯一可识别
|
||||
ThirdUsername string `ThirdUsername` // 第三方中username, 为了显示
|
||||
ThirdType int `ThirdType` // 第三方类型
|
||||
|
||||
// 用户的帐户类型
|
||||
|
||||
ImageNum int `bson:"ImageNum" json:"-"` // 图片数量
|
||||
ImageSize int `bson:"ImageSize" json:"-"` // 图片大小
|
||||
AttachNum int `bson:"AttachNum" json:"-"` // 附件数量
|
||||
AttachSize int `bson:"AttachSize" json:"-"` // 附件大小
|
||||
PerAttachSize int `bson:"PerAttachSize" json:"-"` // 单个附件大小
|
||||
|
||||
AccountType string `bson:"AccountType" json:"-"` // normal(为空), premium
|
||||
AccountStartTime time.Time `bson:"AccountStartTime" json:"-"` // 开始日期
|
||||
AccountEndTime time.Time `bson:"AccountEndTime" json:"-"` // 结束日期
|
||||
// 阈值
|
||||
MaxImageNum int `bson:"MaxImageNums" json:"-"` // 图片数量
|
||||
MaxImageSize int `bson:"MaxImageSize" json:"-"` // 图片大小
|
||||
MaxAttachNum int `bson:"MaxAttachNum" json:"-"` // 图片数量
|
||||
MaxAttachSize int `bson:"MaxAttachSize" json:"-"` // 图片大小
|
||||
MaxPerAttachSize int `bson:"MaxPerAttachSize" json:"-"` // 单个附件大小
|
||||
}
|
||||
|
||||
type UserAccount struct {
|
||||
AccountType string `bson:"AccountType" json:"-"` // normal(为空), premium
|
||||
AccountStartTime time.Time `bson:"AccountStartTime" json:"-"` // 开始日期
|
||||
AccountEndTime time.Time `bson:"AccountEndTime" json:"-"` // 结束日期
|
||||
// 阈值
|
||||
MaxImageNum int `bson:"MaxImageNums" json:"-"` // 图片数量
|
||||
MaxImageSize int `bson:"MaxImageSize" json:"-"` // 图片大小
|
||||
MaxAttachNum int `bson:"MaxAttachNum" json:"-"` // 图片数量
|
||||
MaxAttachSize int `bson:"MaxAttachSize" json:"-"` // 图片大小
|
||||
MaxPerAttachSize int `bson:"MaxPerAttachSize" json:"-"` // 单个附件大小
|
||||
}
|
||||
|
||||
// 用户与博客信息结合, 公开
|
||||
type UserAndBlog struct {
|
||||
UserId bson.ObjectId `bson:"_id,omitempty"` // 必须要设置bson:"_id" 不然mgo不会认为是主键
|
||||
Email string `Email` // 全是小写
|
||||
Username string `Username` // 不区分大小写, 全是小写
|
||||
Logo string `Logo`
|
||||
BlogTitle string `BlogTitle` // 博客标题
|
||||
BlogLogo string `BlogLogo` // 博客Logo
|
||||
BlogUrl string `BlogUrl` // 博客链接, 主页
|
||||
|
||||
BlogUrls // 各个页面
|
||||
}
|
||||
+1
-2
@@ -9,7 +9,6 @@ import (
|
||||
type Page struct {
|
||||
CurPage int // 当前页码
|
||||
TotalPage int // 总页
|
||||
PerPageSize int
|
||||
Count int // 总记录数
|
||||
List interface{}
|
||||
}
|
||||
@@ -19,5 +18,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, perPageSize, count, list}
|
||||
return Page{page, totalPage, count, list}
|
||||
}
|
||||
+2
-21
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
"github.com/leanote/leanote/app/controllers/admin"
|
||||
"github.com/leanote/leanote/app/controllers/member"
|
||||
_ "github.com/leanote/leanote/app/lea/binder"
|
||||
"github.com/leanote/leanote/app/lea/session"
|
||||
"github.com/leanote/leanote/app/lea/memcache"
|
||||
@@ -20,7 +19,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -58,11 +56,6 @@ func init() {
|
||||
i = i - 1;
|
||||
return i
|
||||
}
|
||||
// 增加或减少
|
||||
revel.TemplateFuncs["incr"] = func(n, i int) int {
|
||||
n = n + i;
|
||||
return n
|
||||
}
|
||||
revel.TemplateFuncs["join"] = func(arr []string) template.HTML {
|
||||
if arr == nil {
|
||||
return template.HTML("")
|
||||
@@ -79,24 +72,13 @@ 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)
|
||||
}
|
||||
revel.TemplateFuncs["jsonJs"] = func(i interface{}) template.JS {
|
||||
b, _ := json.Marshal(i)
|
||||
return template.JS(string(b))
|
||||
}
|
||||
revel.TemplateFuncs["datetime"] = func(t time.Time) template.HTML {
|
||||
return template.HTML(t.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
revel.TemplateFuncs["dateFormat"] = func(t time.Time, format string) template.HTML {
|
||||
return template.HTML(t.Format(format))
|
||||
}
|
||||
revel.TemplateFuncs["unixDatetime"] = func(unixSec string) template.HTML {
|
||||
sec, _ := strconv.Atoi(unixSec)
|
||||
t := time.Unix(int64(sec), 0)
|
||||
@@ -153,6 +135,8 @@ func init() {
|
||||
}
|
||||
*/
|
||||
revel.TemplateFuncs["li"] = func(a string) string {
|
||||
Log(a)
|
||||
Log("life==")
|
||||
return ""
|
||||
}
|
||||
// str连接
|
||||
@@ -264,7 +248,6 @@ func init() {
|
||||
// https://groups.google.com/forum/#!topic/golang-nuts/OEdSDgEC7js
|
||||
// http://play.golang.org/p/snygrVpQva
|
||||
// http://grokbase.com/t/gg/golang-nuts/142a6dhfh3/go-nuts-text-template-using-comparison-operators-eq-gt-etc-on-non-existent-variable-causes-the-template-to-stop-outputting-but-with-no-error-correct-behaviour
|
||||
/*
|
||||
revel.TemplateFuncs["gt"] = func(a1, a2 interface{}) bool {
|
||||
switch a1.(type) {
|
||||
case string:
|
||||
@@ -290,7 +273,6 @@ func init() {
|
||||
}
|
||||
return false
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
{{range $i := N 1 10}}
|
||||
@@ -320,7 +302,6 @@ func init() {
|
||||
service.InitService()
|
||||
controllers.InitService()
|
||||
admin.InitService()
|
||||
member.InitService()
|
||||
service.ConfigS.InitGlobalConfigs()
|
||||
})
|
||||
}
|
||||
+5
-97
@@ -1,11 +1,10 @@
|
||||
package lea
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"path/filepath"
|
||||
"os"
|
||||
"io"
|
||||
)
|
||||
|
||||
// 分离文件名与扩展名(包含.)
|
||||
@@ -15,7 +14,7 @@ func SplitFilename(filename string) (baseName, ext string) {
|
||||
ext = SubstringByte(filename, strings.LastIndex(filename, "."))
|
||||
baseName = strings.TrimRight(filename, ext)
|
||||
ext = strings.ToLower(ext)
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// 转换文件的格式
|
||||
@@ -39,7 +38,7 @@ func GetFilesize(path string) int64 {
|
||||
if err == nil {
|
||||
return fileinfo.Size()
|
||||
}
|
||||
return 0
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 清空dir下所有的文件和文件夹
|
||||
@@ -80,55 +79,6 @@ func CopyFile(srcName, dstName string) (written int64, err error) {
|
||||
return io.Copy(dst, src)
|
||||
}
|
||||
|
||||
func CopyDir(source string, dest string) (err error) {
|
||||
// get properties of source dir
|
||||
sourceinfo, err := os.Stat(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create dest dir
|
||||
|
||||
err = os.MkdirAll(dest, sourceinfo.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
directory, _ := os.Open(source)
|
||||
|
||||
objects, err := directory.Readdir(-1)
|
||||
|
||||
for _, obj := range objects {
|
||||
|
||||
sourcefilepointer := source + "/" + obj.Name()
|
||||
|
||||
destinationfilepointer := dest + "/" + obj.Name()
|
||||
|
||||
if obj.IsDir() {
|
||||
// create sub-directories - recursively
|
||||
err = CopyDir(sourcefilepointer, destinationfilepointer)
|
||||
if err != nil {
|
||||
// fmt.Println(err)
|
||||
}
|
||||
} else {
|
||||
// perform copy
|
||||
_, err = CopyFile(sourcefilepointer, destinationfilepointer)
|
||||
if err != nil {
|
||||
// fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func DeleteFile(path string) bool {
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsDirExists(path string) bool {
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
@@ -138,45 +88,3 @@ func IsDirExists(path string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 获得文件str内容
|
||||
func GetFileStrContent(path string) string {
|
||||
fileBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(fileBytes)
|
||||
}
|
||||
|
||||
func IsFileExist(filename string) bool {
|
||||
var exist = true
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
exist = false
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// 写入string内容
|
||||
func PutFileStrContent(path, content string) bool {
|
||||
var f *os.File
|
||||
var err1 error
|
||||
defer (func() {
|
||||
if f != nil {
|
||||
f.Close()
|
||||
}
|
||||
})()
|
||||
f, err1 = os.OpenFile(path, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666) //打开文件
|
||||
// Log(err1)
|
||||
// var n int
|
||||
_, err1 = io.WriteString(f, content) //写入文件(字符串)
|
||||
// Log(content)
|
||||
// Log(err1)
|
||||
// Log(n)
|
||||
// Log(path)
|
||||
|
||||
if err1 != nil {
|
||||
Log(err1)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -27,12 +27,6 @@ var rulesStr = `{
|
||||
],
|
||||
"domain": [
|
||||
{"rule": "domain", "msg": "errorDomain"}
|
||||
],
|
||||
"perPageSize": [
|
||||
{"rule": "min", "data": "1", "msg": "errorPerPageSize"}
|
||||
],
|
||||
"sortField": [
|
||||
{"rule": "sortField", "msg": "errorSortField"}
|
||||
]
|
||||
}
|
||||
`
|
||||
@@ -55,25 +49,6 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok = len(value) >= dataI
|
||||
return
|
||||
},
|
||||
"min": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
data := rule["data"]
|
||||
dataI, _ := strconv.Atoi(data)
|
||||
vI, _ := strconv.Atoi(value)
|
||||
ok = vI >= dataI
|
||||
return
|
||||
},
|
||||
|
||||
"sortField": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
sortFields := []string{"PublicTime", "CreatedTime", "UpdatedTime", "Title"}
|
||||
ok = InArray(sortFields, value)
|
||||
return
|
||||
},
|
||||
|
||||
"password": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
if value == "" {
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
package archive
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// main functions shows how to TarGz a directory/file and
|
||||
// UnTarGz a file
|
||||
// Gzip and tar from source directory or file to destination file
|
||||
// you need check file exist before you call this function
|
||||
|
||||
func main() {
|
||||
/*
|
||||
os.Mkdir("/home/ty4z2008/tar", 0777)
|
||||
w, err := CopyFile("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/src/1.pdf")
|
||||
//targetfile,sourcefile
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
fmt.Println(w)
|
||||
|
||||
TarGz("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/test.tar.gz") //压缩
|
||||
//UnTarGz("/home/ty4z2008/1.tar.gz", "/home/ty4z2008") //解压
|
||||
os.RemoveAll("/home/ty4z2008/tar")
|
||||
*/
|
||||
// TaZip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.tar.gz")
|
||||
Zip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.zip")
|
||||
fmt.Println("ok")
|
||||
}
|
||||
|
||||
func TarGz(srcDirPath string, destFilePath string) (ok bool) {
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
// Gzip writer
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// Tar writer
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
tarGzDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
tarGzFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// Deal with directories
|
||||
// if find files, handle them with tarGzFile
|
||||
// Every recurrence append the base path to the recPath
|
||||
// recPath is the path inside of tar.gz
|
||||
func tarGzDir(srcDirPath string, recPath string, tw *tar.Writer) {
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
tarGzDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
|
||||
tarGzFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with files
|
||||
func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) {
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
// if last character of header name is '/' it also can be directory
|
||||
// but if you don't set Typeflag, error will occur when you untargz
|
||||
hdr.Name = recPath // + "/"
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Typeflag = tar.TypeDir
|
||||
// hdr.Size = 0
|
||||
//hdr.Mode = 0755 | c_ISDIR
|
||||
// hdr.Mode = int64(fi.Mode()) // 加这个会有错误!!!
|
||||
// hdr.ModTime = fi.ModTime() // 加这个会有错误!!
|
||||
|
||||
// Write hander
|
||||
err := tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
hdr.Name = recPath
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Size = fi.Size()
|
||||
hdr.Mode = int64(fi.Mode())
|
||||
hdr.ModTime = fi.ModTime()
|
||||
|
||||
// Write hander
|
||||
err = tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Write file data
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ungzip and untar from source file to destination directory
|
||||
// you need check file exist before you call this function
|
||||
func UnTarGz(srcFilePath string, destDirPath string) {
|
||||
// fmt.Println("UnTarGzing " + srcFilePath + "...")
|
||||
// Create destination directory
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
|
||||
fr, err := os.Open(srcFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Gzip reader
|
||||
gr, err := gzip.NewReader(fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer gr.Close()
|
||||
|
||||
// Tar reader
|
||||
tr := tar.NewReader(gr)
|
||||
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
// End of tar archive
|
||||
break
|
||||
}
|
||||
//handleError(err)
|
||||
// fmt.Println("UnTarGzing file..." + hdr.Name)
|
||||
// Check if it is diretory or file
|
||||
if hdr.Typeflag != tar.TypeDir {
|
||||
// Get files from archive
|
||||
// Create diretory before create file
|
||||
os.MkdirAll(destDirPath+"/"+path.Dir(hdr.Name), os.ModePerm)
|
||||
// Write data to file
|
||||
fw, _ := os.Create(destDirPath + "/" + hdr.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, tr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// fmt.Println("Well done!")
|
||||
}
|
||||
|
||||
// Copyfile
|
||||
func CopyFile(dstName, srcName string) (written int64, err error) {
|
||||
src, err := os.Open(srcName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer dst.Close()
|
||||
return io.Copy(dst, src)
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
package archive
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"strings"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// main functions shows how to TarGz a directory/file and
|
||||
// UnTarGz a file
|
||||
// Gzip and tar from source directory or file to destination file
|
||||
// you need check file exist before you call this function
|
||||
|
||||
func Zip(srcDirPath string, destFilePath string) (ok bool) {
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
// Tar writer
|
||||
tw := zip.NewWriter(fw)
|
||||
defer tw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
zipDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
zipFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// Deal with directories
|
||||
// if find files, handle them with zipFile
|
||||
// Every recurrence append the base path to the recPath
|
||||
// recPath is the path inside of tar.gz
|
||||
func zipDir(srcDirPath string, recPath string, tw *zip.Writer) {
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
zipDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
|
||||
zipFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with files
|
||||
func zipFile(srcFile string, recPath string, tw *zip.Writer, fi os.FileInfo) {
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
/*
|
||||
fh, err := zip.FileInfoHeader(fi)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fh.Name = recPath // + "/"
|
||||
err = tw.WriteHeader(hdr)
|
||||
tw.Create(recPath)
|
||||
*/
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Write hander
|
||||
w, err2 := tw.Create(recPath)
|
||||
if err2 != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write file data
|
||||
_, err = io.Copy(w, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ungzip and untar from source file to destination directory
|
||||
// you need check file exist before you call this function
|
||||
func Unzip(srcFilePath string, destDirPath string) (ok bool, msg string) {
|
||||
ok = false
|
||||
msg = ""
|
||||
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
r, err := zip.OpenReader(srcFilePath);
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer r.Close();
|
||||
for _, f := range r.File {
|
||||
// fmt.Println("FileName : ", f.Name); // j/aaa.zip
|
||||
rc, err := f.Open();
|
||||
if err!=nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 把首文件夹去掉, 即j去掉, 分离出文件夹和文件名
|
||||
paths := strings.Split(f.Name, "/")
|
||||
prePath := ""
|
||||
filename := ""
|
||||
l := len(paths)
|
||||
// fmt.Println(l)
|
||||
if l > 1 {
|
||||
// 去掉第1个文件夹
|
||||
if l == 2 {
|
||||
filename = paths[1]
|
||||
} else {
|
||||
filename = paths[l-1]
|
||||
prePath = strings.Join(paths[1:l-1], "/")
|
||||
}
|
||||
} else {
|
||||
filename = f.Name
|
||||
}
|
||||
// fmt.Println(prePath)
|
||||
|
||||
// 相对于目标文件件下的路径
|
||||
destPath := destDirPath + "/" + filename
|
||||
if prePath != "" {
|
||||
os.MkdirAll(destDirPath + "/" + prePath, os.ModePerm)
|
||||
destPath = destDirPath + "/" + prePath + "/" + filename
|
||||
}
|
||||
// Write data to file
|
||||
// fmt.Println(destPath)
|
||||
fw, _ := os.Create(destPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, rc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
@@ -1,302 +0,0 @@
|
||||
package blog
|
||||
|
||||
import (
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
// "os"
|
||||
"fmt"
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//--------------------
|
||||
// leanote 自定义主题
|
||||
// 不使用revel的模板机制
|
||||
// By life
|
||||
//--------------------
|
||||
|
||||
var ts = []string{"header.html", "footer.html", "highlight.html", "comment.html", "view.html", "404.html"}
|
||||
var selfTs = []string{"header.html", "footer.html", "index.html", "about_me.html"} // 用户自定义的文件列表
|
||||
|
||||
type BlogTpl struct {
|
||||
Template *template.Template
|
||||
PathContent map[string]string // path => content
|
||||
}
|
||||
|
||||
func (this *BlogTpl) Content(name string) string {
|
||||
return this.PathContent[name]
|
||||
}
|
||||
|
||||
var BlogTplObject *BlogTpl
|
||||
var CloneTemplate *template.Template
|
||||
|
||||
type RenderTemplateResult struct {
|
||||
Template *template.Template
|
||||
PathContent map[string]string
|
||||
RenderArgs map[string]interface{}
|
||||
|
||||
IsPreview bool // 是否是预览
|
||||
CurBlogTpl *BlogTpl
|
||||
}
|
||||
|
||||
func parseTemplateError(err error) (templateName string, line int, description string) {
|
||||
description = err.Error()
|
||||
i := regexp.MustCompile(`:\d+:`).FindStringIndex(description)
|
||||
if i != nil {
|
||||
line, err = strconv.Atoi(description[i[0]+1 : i[1]-1])
|
||||
if err != nil {
|
||||
}
|
||||
templateName = description[:i[0]]
|
||||
if colon := strings.Index(templateName, ":"); colon != -1 {
|
||||
templateName = templateName[colon+1:]
|
||||
}
|
||||
templateName = strings.TrimSpace(templateName)
|
||||
description = description[i[1]+1:]
|
||||
}
|
||||
return templateName, line, description
|
||||
}
|
||||
func (r *RenderTemplateResult) render(req *revel.Request, resp *revel.Response, wr io.Writer) {
|
||||
err := r.Template.Execute(wr, r.RenderArgs)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var templateContent []string
|
||||
templateName, line, description := parseTemplateError(err)
|
||||
var content = ""
|
||||
if templateName == "" {
|
||||
templateName = r.Template.Name()
|
||||
content = r.PathContent[templateName]
|
||||
} else {
|
||||
content = r.PathContent[templateName]
|
||||
}
|
||||
if content != "" {
|
||||
templateContent = strings.Split(content, "\n")
|
||||
}
|
||||
|
||||
compileError := &revel.Error{
|
||||
Title: "Template Execution Error",
|
||||
Path: templateName,
|
||||
Description: description,
|
||||
Line: line,
|
||||
SourceLines: templateContent,
|
||||
}
|
||||
|
||||
// 这里, 错误!!
|
||||
// 这里应该导向到本主题的错误页面
|
||||
resp.Status = 500
|
||||
ErrorResult{r.RenderArgs, compileError, r.IsPreview, r.CurBlogTpl}.Apply(req, resp)
|
||||
}
|
||||
|
||||
func (r *RenderTemplateResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
// Handle panics when rendering templates.
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
}
|
||||
}()
|
||||
|
||||
chunked := revel.Config.BoolDefault("results.chunked", false)
|
||||
|
||||
// If it's a HEAD request, throw away the bytes.
|
||||
out := io.Writer(resp.Out)
|
||||
if req.Method == "HEAD" {
|
||||
out = ioutil.Discard
|
||||
}
|
||||
|
||||
// In a prod mode, write the status, render, and hope for the best.
|
||||
// (In a dev mode, always render to a temporary buffer first to avoid having
|
||||
// error pages distorted by HTML already written)
|
||||
if chunked && !revel.DevMode {
|
||||
resp.WriteHeader(http.StatusOK, "text/html; charset=utf-8")
|
||||
r.render(req, resp, out) // 这里!!!
|
||||
return
|
||||
}
|
||||
|
||||
// Render the template into a temporary buffer, to see if there was an error
|
||||
// rendering the template. If not, then copy it into the response buffer.
|
||||
// Otherwise, template render errors may result in unpredictable HTML (and
|
||||
// would carry a 200 status code)
|
||||
var b bytes.Buffer
|
||||
r.render(req, resp, &b)
|
||||
if !chunked {
|
||||
resp.Out.Header().Set("Content-Length", strconv.Itoa(b.Len()))
|
||||
}
|
||||
resp.WriteHeader(http.StatusOK, "text/html; charset=utf-8")
|
||||
b.WriteTo(out)
|
||||
}
|
||||
|
||||
// 博客模板
|
||||
func Init() {
|
||||
BlogTplObject = &BlogTpl{PathContent: map[string]string{}}
|
||||
BlogTplObject.Template = template.New("blog").Funcs(revel.TemplateFuncs)
|
||||
for _, path := range ts {
|
||||
fileBytes, _ := ioutil.ReadFile(revel.ViewsPath + "/Blog/" + path)
|
||||
fileStr := string(fileBytes)
|
||||
path := "blog/" + path
|
||||
// path := path
|
||||
BlogTplObject.PathContent[path] = fileStr
|
||||
BlogTplObject.Template.New(path).Parse(fileStr) // 以blog为根
|
||||
}
|
||||
// 复制一份
|
||||
CloneTemplate, _ = BlogTplObject.Template.Clone()
|
||||
}
|
||||
|
||||
// name = index.html, search.html, cate.html, page.html
|
||||
// basePath 表未用户主题的基路径, 如/xxx/public/upload/32323232/themes/theme1, 如果没有, 则表示用自带的
|
||||
// isPreview 如果是, 错误提示则显示系统的 500 错误详情信息, 供debug
|
||||
//
|
||||
func RenderTemplate(name string, args map[string]interface{}, basePath string, isPreview bool) revel.Result {
|
||||
var r *RenderTemplateResult
|
||||
// 传来的主题路径为空, 则用系统的
|
||||
// 都不会为空的
|
||||
if basePath == "" {
|
||||
path := "blog/" + name
|
||||
// path := name
|
||||
t := BlogTplObject.Template.Lookup(path)
|
||||
r = &RenderTemplateResult{
|
||||
Template: t,
|
||||
PathContent: BlogTplObject.PathContent, // 为了显示错误
|
||||
RenderArgs: args, // 把args给它
|
||||
}
|
||||
} else {
|
||||
// 复制一份
|
||||
newBlogTplObject := &BlogTpl{}
|
||||
var err error
|
||||
newBlogTplObject.Template, err = CloneTemplate.Clone() // 复制一份, 为防止多用户出现问题, 因为newBlogTplObject是全局的
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
newBlogTplObject.PathContent = map[string]string{}
|
||||
for k, v := range BlogTplObject.PathContent {
|
||||
newBlogTplObject.PathContent[k] = v
|
||||
}
|
||||
|
||||
// 将该basePath下的所有文件提出
|
||||
files := ListDir(basePath)
|
||||
Log(basePath)
|
||||
LogJ(files);
|
||||
for _, t := range files {
|
||||
if !strings.Contains(t, ".html") {
|
||||
continue;
|
||||
}
|
||||
fileBytes, err := ioutil.ReadFile(basePath + "/" + t)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
fileStr := string(fileBytes)
|
||||
newBlogTplObject.PathContent[t] = fileStr
|
||||
newBlogTplObject.Template.New(t).Parse(fileStr)
|
||||
}
|
||||
|
||||
// 如果本主题下没有, 则用系统的
|
||||
t := newBlogTplObject.Template.Lookup(name)
|
||||
|
||||
if t == nil {
|
||||
path := "blog/" + name
|
||||
t = BlogTplObject.Template.Lookup(path)
|
||||
}
|
||||
r = &RenderTemplateResult{
|
||||
Template: t,
|
||||
PathContent: newBlogTplObject.PathContent, // 为了显示错误
|
||||
RenderArgs: args,
|
||||
CurBlogTpl: newBlogTplObject,
|
||||
IsPreview: isPreview,
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// 错误显示
|
||||
|
||||
type ErrorResult struct {
|
||||
RenderArgs map[string]interface{}
|
||||
Error error
|
||||
IsPreview bool
|
||||
CurBlogTpl *BlogTpl
|
||||
}
|
||||
|
||||
// 错误显示出
|
||||
func (r ErrorResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
format := req.Format
|
||||
status := resp.Status
|
||||
if status == 0 {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
|
||||
contentType := revel.ContentTypeByFilename("xxx." + format)
|
||||
if contentType == revel.DefaultFileContentType {
|
||||
contentType = "text/plain"
|
||||
}
|
||||
|
||||
// Get the error template.
|
||||
var err error
|
||||
templatePath := fmt.Sprintf("errors/%d.%s", status, format)
|
||||
err = nil
|
||||
// tmpl, err := revel.MainTemplateLoader.Template("index.html") // 这里找到错误页面主题
|
||||
|
||||
// This func shows a plaintext error message, in case the template rendering
|
||||
// doesn't work.
|
||||
showPlaintext := func(err error) {
|
||||
revel.PlaintextErrorResult{fmt.Errorf("Server Error:\n%s\n\n"+
|
||||
"Additionally, an error occurred when rendering the error page:\n%s",
|
||||
r.Error, err)}.Apply(req, resp)
|
||||
}
|
||||
|
||||
// 根据是否是preview来得到404模板
|
||||
// 是, 则显示系统的错误信息, blog-500.html
|
||||
var tmpl *template.Template
|
||||
if r.IsPreview {
|
||||
tmpl = r.CurBlogTpl.Template.Lookup("blog/404.html")
|
||||
} else {
|
||||
tmpl = r.CurBlogTpl.Template.Lookup("404.html")
|
||||
}
|
||||
if tmpl == nil {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("Couldn't find template %s", templatePath)
|
||||
}
|
||||
showPlaintext(err)
|
||||
return
|
||||
}
|
||||
|
||||
// If it's not a revel error, wrap it in one.
|
||||
var revelError *revel.Error
|
||||
switch e := r.Error.(type) {
|
||||
case *revel.Error:
|
||||
revelError = e
|
||||
case error:
|
||||
revelError = &revel.Error{
|
||||
Title: "Server Error",
|
||||
Description: e.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
if revelError == nil {
|
||||
panic("no error provided")
|
||||
}
|
||||
|
||||
if r.RenderArgs == nil {
|
||||
r.RenderArgs = make(map[string]interface{})
|
||||
}
|
||||
r.RenderArgs["Error"] = revelError
|
||||
r.RenderArgs["Router"] = revel.MainRouter
|
||||
|
||||
// 不是preview就不要显示错误了
|
||||
LogJ(revelError)
|
||||
// if r.IsPreview {
|
||||
var b bytes.Buffer
|
||||
out := io.Writer(resp.Out)
|
||||
// out = ioutil.Discard
|
||||
err = tmpl.Execute(&b, r.RenderArgs)
|
||||
resp.WriteHeader(http.StatusOK, "text/html; charset=utf-8")
|
||||
b.WriteTo(out)
|
||||
// }
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import (
|
||||
"strings"
|
||||
"os"
|
||||
// "path/filepath"
|
||||
"net"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
@@ -91,12 +90,3 @@ func trimQueryParams(url string) string {
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
// 通过domain得到ip
|
||||
func GetIpFromDomain(domain string) string {
|
||||
ip, _ := net.LookupIP(domain)
|
||||
if ip != nil && len(ip) > 0 {
|
||||
return ip[0].String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -44,12 +44,8 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
if route.ControllerName != "Static" {
|
||||
// api设置
|
||||
// leanote.com/api/user/get => ApiUser::Get
|
||||
//* /api/login ApiAuth.Login, 这里的设置, 其实已经转成了ApiAuth了
|
||||
if strings.HasPrefix(path, "/api") && !strings.HasPrefix(route.ControllerName, "Api"){
|
||||
if strings.HasPrefix(path, "/api/") || strings.HasPrefix(path, "api/") {
|
||||
route.ControllerName = "Api" + route.ControllerName
|
||||
} else if strings.HasPrefix(path, "/member") && !strings.HasPrefix(route.ControllerName, "Member") {
|
||||
// member设置
|
||||
route.ControllerName = "Member" + route.ControllerName
|
||||
}
|
||||
// end
|
||||
}
|
||||
|
||||
@@ -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, "userHasBeenRegistered-" + email
|
||||
return false, email + " 已被注册"
|
||||
}
|
||||
user := info.User{UserId: bson.NewObjectId(), Email: email, Username: email, Pwd: Md5(pwd)}
|
||||
return this.register(user)
|
||||
@@ -90,10 +90,7 @@ 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, ""
|
||||
|
||||
+54
-696
@@ -1,13 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "time"
|
||||
// "sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -31,30 +30,10 @@ note, notebook都可设为blog
|
||||
type BlogService struct {
|
||||
}
|
||||
|
||||
// 得到博客统计信息
|
||||
// ReadNum, LikeNum, CommentNum
|
||||
func (this *BlogService) GetBlogStat(noteId string) (stat info.BlogStat) {
|
||||
note := noteService.GetBlogNote(noteId)
|
||||
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
|
||||
}
|
||||
@@ -63,7 +42,7 @@ func (this *BlogService) GetBlogItem(note info.Note) (blog info.BlogItem) {
|
||||
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.Content, false, info.User{}}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -77,11 +56,11 @@ 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)
|
||||
func (this *BlogService) ListBlogs(userId, notebookId string, page, pageSize int, sortField string, isAsc bool) (int, []info.BlogItem) {
|
||||
count, notes := noteService.ListNotes(userId, notebookId, false, page, pageSize, sortField, isAsc, true);
|
||||
|
||||
if notes == nil || len(notes) == 0 {
|
||||
return info.Page{}, nil
|
||||
if(notes == nil || len(notes) == 0) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// 得到content, 并且每个都要substring
|
||||
@@ -104,212 +83,21 @@ func (this *BlogService) ListBlogs(userId, notebookId string, page, pageSize int
|
||||
for i, note := range notes {
|
||||
hasMore := true
|
||||
var content string
|
||||
var abstract string
|
||||
if noteContent, ok := noteContentsMap[note.NoteId]; ok {
|
||||
abstract = noteContent.Abstract
|
||||
content = noteContent.Content
|
||||
content = noteContent.Abstract
|
||||
}
|
||||
blogs[i] = info.BlogItem{note, abstract, content, hasMore, info.User{}}
|
||||
blogs[i] = info.BlogItem{note, content, hasMore, info.User{}}
|
||||
}
|
||||
return count, blogs
|
||||
}
|
||||
|
||||
pageInfo := info.NewPage(page, pageSize, count, nil)
|
||||
func (this *BlogService) SearchBlog(key, userId string, page, pageSize int, sortField string, isAsc bool) (int, []info.BlogItem) {
|
||||
count, notes := noteService.SearchNote(key, userId, page, pageSize, sortField, isAsc, true);
|
||||
|
||||
return pageInfo, blogs
|
||||
if(notes == nil || len(notes) == 0) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// 得到博客的标签, 那得先得到所有博客, 比较慢
|
||||
/*
|
||||
[
|
||||
{Tag:xxx, Count: 32}
|
||||
]
|
||||
*/
|
||||
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 {
|
||||
// 得到所有博客
|
||||
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
|
||||
}
|
||||
// 统计所有的Tags和数目
|
||||
tagsCount := map[string]int{}
|
||||
for _, note := range notes {
|
||||
tags := note.Tags
|
||||
if tags != nil && len(tags) > 0 {
|
||||
for _, tag := range tags {
|
||||
count := tagsCount[tag]
|
||||
count++
|
||||
tagsCount[tag] = count
|
||||
}
|
||||
}
|
||||
}
|
||||
// 一个个插入
|
||||
for tag, count := range tagsCount {
|
||||
db.Insert(db.TagCounts,
|
||||
info.TagCount{UserId: userIdO, IsBlog: true, Tag: tag, Count: count})
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 归档博客
|
||||
/*
|
||||
数据: 按年汇总
|
||||
[
|
||||
archive1,
|
||||
archive2,
|
||||
]
|
||||
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);
|
||||
q := bson.M{"UserId": bson.ObjectIdHex(userId), "IsBlog": true, "IsTrash": false}
|
||||
if notebookId != "" {
|
||||
q["NotebookId"] = bson.ObjectIdHex(notebookId)
|
||||
}
|
||||
if year > 0 {
|
||||
now := time.Now()
|
||||
nextYear := year
|
||||
nextMonth := month
|
||||
if month == 0 {
|
||||
month = 1
|
||||
nextYear = year + 1
|
||||
nextMonth = month
|
||||
} else if month >= 12 {
|
||||
month = 12
|
||||
nextYear = year + 1
|
||||
nextMonth = 1
|
||||
} else { // month 在1-12之间
|
||||
nextMonth = month + 1
|
||||
}
|
||||
leftT := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, now.Location())
|
||||
rightT := time.Date(nextYear, time.Month(nextMonth), 1, 0, 0, 0, 0, now.Location())
|
||||
if sortField == "CreatedTime" || sortField == "UpdatedTime" {
|
||||
q[sortField] = bson.M{"$gte": leftT, "$lt": rightT}
|
||||
} else {
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
arcs := []info.Archive{}
|
||||
// 按年汇总
|
||||
arcsMap := map[int]info.Archive{}
|
||||
// 按月汇总
|
||||
arcsMonth := []info.ArchiveMonth{}
|
||||
var t time.Time
|
||||
var arc info.Archive
|
||||
everYear := 0
|
||||
for _, note := range notes {
|
||||
if sortField == "PublicTime" {
|
||||
t = note.PublicTime
|
||||
} else if sortField == "CreatedTime" {
|
||||
t = note.CreatedTime
|
||||
} else {
|
||||
t = note.UpdatedTime
|
||||
}
|
||||
year := t.Year()
|
||||
month := int(t.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{}}
|
||||
}
|
||||
|
||||
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 {
|
||||
arcsMonth = append(arcsMonth, info.ArchiveMonth{month, []*info.Post{p}})
|
||||
} else {
|
||||
arcsMonth[lm-1].Posts = append(arcsMonth[lm-1].Posts, p)
|
||||
}
|
||||
}
|
||||
// 最后一个
|
||||
if everYear > 0 {
|
||||
yearArc := arcsMap[everYear]
|
||||
yearArc.MonthAchives = arcsMonth
|
||||
arcs = append(arcs, yearArc)
|
||||
}
|
||||
|
||||
return arcs
|
||||
}
|
||||
|
||||
// 根据tag搜索博客
|
||||
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)
|
||||
|
||||
// 总记录数
|
||||
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 {
|
||||
// 得到content, 并且每个都要substring
|
||||
noteIds := make([]bson.ObjectId, len(notes))
|
||||
for i, note := range notes {
|
||||
@@ -318,7 +106,7 @@ func (this *BlogService) notes2BlogItems(notes []info.Note) []info.BlogItem {
|
||||
|
||||
// 直接得到noteContents表的abstract
|
||||
// 这里可能是乱序的
|
||||
noteContents := noteService.ListNoteContentByNoteIds(noteIds) // 返回[info.NoteContent]
|
||||
noteContents := noteService.ListNoteAbstractsByNoteIds(noteIds) // 返回[info.NoteContent]
|
||||
noteContentsMap := make(map[bson.ObjectId]info.NoteContent, len(noteContents))
|
||||
for _, noteContent := range noteContents {
|
||||
noteContentsMap[noteContent.NoteId] = noteContent
|
||||
@@ -329,90 +117,20 @@ func (this *BlogService) notes2BlogItems(notes []info.Note) []info.BlogItem {
|
||||
blogs := make([]info.BlogItem, len(noteIds))
|
||||
for i, note := range notes {
|
||||
hasMore := true
|
||||
var content, abstract string
|
||||
var content string
|
||||
if noteContent, ok := noteContentsMap[note.NoteId]; ok {
|
||||
abstract = noteContent.Abstract
|
||||
content = noteContent.Content
|
||||
content = noteContent.Abstract
|
||||
}
|
||||
blogs[i] = info.BlogItem{note, abstract, content, hasMore, info.User{}}
|
||||
blogs[i] = info.BlogItem{note, content, hasMore, info.User{}}
|
||||
}
|
||||
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 {
|
||||
return info.Page{}, nil
|
||||
}
|
||||
|
||||
blogs := this.notes2BlogItems(notes)
|
||||
pageInfo := info.NewPage(page, pageSize, count, nil)
|
||||
return pageInfo, blogs
|
||||
}
|
||||
|
||||
// 上一篇文章, 下一篇文章
|
||||
// sorterField, baseTime是基准, sorterField=PublicTime, title
|
||||
// isAsc是用户自定义的排序方式
|
||||
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
|
||||
--
|
||||
*/
|
||||
// 上一篇时间要比它大, 找最小的
|
||||
sortFieldT1 = bson.M{"$gt": baseTime}
|
||||
sortFieldR1 = sorterField
|
||||
// 下一篇时间要比它小
|
||||
sortFieldT2 = bson.M{"$lt": baseTime}
|
||||
sortFieldR2 = "-" + sorterField
|
||||
} else {
|
||||
// 升序
|
||||
/*
|
||||
--- pre
|
||||
----- now
|
||||
------- next
|
||||
---------
|
||||
*/
|
||||
// 上一篇要比它小, 找最大的
|
||||
sortFieldT1 = bson.M{"$lt": baseTime}
|
||||
sortFieldR1 = "-" + sorterField
|
||||
// 下一篇, 找最小的
|
||||
sortFieldT2 = bson.M{"$gt": baseTime}
|
||||
sortFieldR2 = sorterField
|
||||
}
|
||||
|
||||
// 上一篇, 比基时间要小, 但是是最后一篇, 所以是降序
|
||||
note := info.Note{}
|
||||
query := bson.M{"UserId": userIdO, "IsTrash": false, "IsBlog": true,
|
||||
sorterField: sortFieldT1,
|
||||
}
|
||||
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)
|
||||
q.Sort(sortFieldR2).Limit(1).One(¬e2)
|
||||
|
||||
return this.FixNote(note), this.FixNote(note2)
|
||||
return count, blogs
|
||||
}
|
||||
|
||||
//-------
|
||||
// p
|
||||
// 平台 lea+
|
||||
// 博客列表
|
||||
func (this *BlogService) ListAllBlogs(userId, tag string, keywords string, isRecommend bool, page, pageSize int, sorterField string, isAsc bool) (info.Page, []info.BlogItem) {
|
||||
func (this *BlogService) ListAllBlogs(tag string, keywords string, isRecommend bool, page, pageSize int, sorterField string, isAsc bool) (info.Page, []info.BlogItem) {
|
||||
pageInfo := info.Page{CurPage: page}
|
||||
notes := []info.Note{}
|
||||
|
||||
@@ -423,12 +141,9 @@ func (this *BlogService) ListAllBlogs(userId, tag string, keywords string, isRec
|
||||
if tag != "" {
|
||||
query["Tags"] = bson.M{"$in": []string{tag}}
|
||||
}
|
||||
if userId != "" {
|
||||
query["UserId"] = bson.ObjectIdHex(userId)
|
||||
}
|
||||
// 不是demo的博客
|
||||
demoUserId := configService.GetGlobalStringConfig("demoUserId")
|
||||
if userId == "" && demoUserId != "" {
|
||||
if demoUserId != "" {
|
||||
query["UserId"] = bson.M{"$ne": bson.ObjectIdHex(demoUserId)}
|
||||
}
|
||||
|
||||
@@ -438,7 +153,7 @@ func (this *BlogService) ListAllBlogs(userId, tag string, keywords string, isRec
|
||||
if keywords != "" {
|
||||
query["Title"] = bson.M{"$regex": bson.RegEx{".*?" + keywords + ".*", "i"}}
|
||||
}
|
||||
q := db.Notes.Find(query)
|
||||
q := db.Notes.Find(query);
|
||||
|
||||
// 总记录数
|
||||
count, _ := q.Count()
|
||||
@@ -448,7 +163,7 @@ func (this *BlogService) ListAllBlogs(userId, tag string, keywords string, isRec
|
||||
Limit(pageSize).
|
||||
All(¬es)
|
||||
|
||||
if notes == nil || len(notes) == 0 {
|
||||
if(notes == nil || len(notes) == 0) {
|
||||
return pageInfo, nil
|
||||
}
|
||||
|
||||
@@ -485,7 +200,7 @@ func (this *BlogService) ListAllBlogs(userId, tag string, keywords string, isRec
|
||||
content = noteContent.Abstract
|
||||
}
|
||||
*/
|
||||
blogs[i] = info.BlogItem{note, "", content, hasMore, userMap[note.UserId]}
|
||||
blogs[i] = info.BlogItem{note, content, hasMore, userMap[note.UserId]}
|
||||
}
|
||||
pageInfo = info.NewPage(page, pageSize, count, nil)
|
||||
|
||||
@@ -495,27 +210,18 @@ func (this *BlogService) ListAllBlogs(userId, tag string, keywords string, isRec
|
||||
//------------------------
|
||||
// 博客设置
|
||||
func (this *BlogService) fixUserBlog(userBlog *info.UserBlog) {
|
||||
/*
|
||||
if userBlog.Title == "" {
|
||||
userInfo := userService.GetUserInfo(userBlog)
|
||||
userBlog.Title = userInfo.Username + " 's Blog"
|
||||
}
|
||||
*/
|
||||
|
||||
// Logo路径问题, 有些有http: 有些没有
|
||||
Log(userBlog.Logo)
|
||||
if userBlog.Logo != "" && !strings.HasPrefix(userBlog.Logo, "http") {
|
||||
userBlog.Logo = strings.Trim(userBlog.Logo, "/")
|
||||
userBlog.Logo = configService.GetSiteUrl() + "/" + userBlog.Logo
|
||||
}
|
||||
|
||||
if userBlog.SortField == "" {
|
||||
userBlog.SortField = "PublicTime"
|
||||
}
|
||||
if userBlog.PerPageSize <= 0 {
|
||||
userBlog.PerPageSize = 10
|
||||
}
|
||||
|
||||
// themePath
|
||||
if userBlog.Style == "" {
|
||||
userBlog.Style = defaultStyle
|
||||
}
|
||||
if userBlog.ThemeId == "" {
|
||||
userBlog.ThemePath = themeService.GetDefaultThemePath(userBlog.Style)
|
||||
} else {
|
||||
userBlog.ThemePath = themeService.GetThemePath(userBlog.UserId.Hex(), userBlog.ThemeId.Hex())
|
||||
userBlog.Logo = siteUrl + "/" + userBlog.Logo
|
||||
}
|
||||
}
|
||||
func (this *BlogService) GetUserBlog(userId string) info.UserBlog {
|
||||
@@ -529,7 +235,6 @@ 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)
|
||||
@@ -542,28 +247,6 @@ func (this *BlogService) UpdateUserBlogStyle(userId string, userBlog info.UserBl
|
||||
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)},
|
||||
bson.M{"PerPageSize": perPageSize, "SortField": sortField, "IsAsc": isAsc})
|
||||
return
|
||||
}
|
||||
|
||||
func (this *BlogService) GetUserBlogBySubDomain(subDomain string) info.UserBlog {
|
||||
blogUser := info.UserBlog{}
|
||||
db.GetByQ(db.UserBlogs, bson.M{"SubDomain": subDomain}, &blogUser)
|
||||
this.fixUserBlog(&blogUser)
|
||||
return blogUser
|
||||
}
|
||||
func (this *BlogService) GetUserBlogByDomain(domain string) info.UserBlog {
|
||||
blogUser := info.UserBlog{}
|
||||
db.GetByQ(db.UserBlogs, bson.M{"Domain": domain}, &blogUser)
|
||||
this.fixUserBlog(&blogUser)
|
||||
return blogUser
|
||||
}
|
||||
|
||||
//---------------------
|
||||
// 后台管理
|
||||
@@ -581,14 +264,14 @@ func (this *BlogService) SetRecommend(noteId string, isRecommend bool) bool {
|
||||
// 博客社交, 评论
|
||||
|
||||
// 返回所有liked用户, bool是否还有
|
||||
func (this *BlogService) ListLikedUsers(noteId string, isAll bool) ([]info.UserAndBlog, bool) {
|
||||
func (this *BlogService) ListLikedUsers(noteId string, isAll bool) ([]info.User, bool) {
|
||||
// 默认前5
|
||||
pageSize := 5
|
||||
skipNum, sortFieldR := parsePageAndSort(1, pageSize, "CreatedTime", false)
|
||||
|
||||
likes := []info.BlogLike{}
|
||||
query := bson.M{"NoteId": bson.ObjectIdHex(noteId)}
|
||||
q := db.BlogLikes.Find(query)
|
||||
q := db.BlogLikes.Find(query);
|
||||
|
||||
// 总记录数
|
||||
count, _ := q.Count()
|
||||
@@ -608,11 +291,11 @@ func (this *BlogService) ListLikedUsers(noteId string, isAll bool) ([]info.UserA
|
||||
userIds[i] = like.UserId
|
||||
}
|
||||
// 得到用户信息
|
||||
userMap := userService.MapUserAndBlogByUserIds(userIds)
|
||||
userMap := userService.MapUserInfoAndBlogInfosByUserIds(userIds)
|
||||
|
||||
users := make([]info.UserAndBlog, len(likes))
|
||||
users := make([]info.User, len(likes));
|
||||
for i, like := range likes {
|
||||
users[i] = userMap[like.UserId.Hex()]
|
||||
users[i] = userMap[like.UserId]
|
||||
}
|
||||
|
||||
return users, count > pageSize
|
||||
@@ -709,7 +392,7 @@ func (this *BlogService) Comment(noteId, toCommentId, userId, content string) (b
|
||||
|
||||
if userId != note.UserId.Hex() || toCommentId != "" {
|
||||
go func() {
|
||||
this.sendEmail(note, comment2, userId, content)
|
||||
this.sendEmail(note, comment2, userId, content);
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -718,7 +401,7 @@ func (this *BlogService) Comment(noteId, toCommentId, userId, content string) (b
|
||||
|
||||
// 发送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 := "评论提醒"
|
||||
@@ -762,7 +445,7 @@ func (this *BlogService) DeleteComment(noteId, commentId, userId string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if userId == configService.GetAdminUserId() || note.UserId.Hex() == userId || comment.UserId.Hex() == userId {
|
||||
if userId == adminUserId || note.UserId.Hex() == userId || comment.UserId.Hex() == userId {
|
||||
if db.Delete(db.BlogComments, bson.M{"_id": bson.ObjectIdHex(commentId)}) {
|
||||
// 评论-1
|
||||
db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"CommentNum": -1}})
|
||||
@@ -812,7 +495,7 @@ func (this *BlogService) LikeComment(commentId, userId string) (ok bool, isILike
|
||||
// 评论列表
|
||||
// userId主要是显示userId是否点过某评论的赞
|
||||
// 还要获取用户信息
|
||||
func (this *BlogService) ListComments(userId, noteId string, page, pageSize int) (info.Page, []info.BlogCommentPublic, map[string]info.UserAndBlog) {
|
||||
func (this *BlogService) ListComments(userId, noteId string, page, pageSize int) (info.Page, []info.BlogCommentPublic, map[string]info.User) {
|
||||
pageInfo := info.Page{CurPage: page}
|
||||
|
||||
comments2 := []info.BlogComment{}
|
||||
@@ -820,13 +503,13 @@ func (this *BlogService) ListComments(userId, noteId string, page, pageSize int)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -839,7 +522,7 @@ func (this *BlogService) ListComments(userId, noteId string, page, pageSize int)
|
||||
}
|
||||
}
|
||||
|
||||
note := noteService.GetNoteById(noteId)
|
||||
note := noteService.GetNoteById(noteId);
|
||||
|
||||
// 得到用户信息
|
||||
userIdsMap := map[bson.ObjectId]bool{note.UserId: true}
|
||||
@@ -857,14 +540,19 @@ func (this *BlogService) ListComments(userId, noteId string, page, pageSize int)
|
||||
}
|
||||
|
||||
// 得到用户信息
|
||||
userMap := userService.MapUserAndBlogByUserIds(userIds)
|
||||
userMap := userService.MapUserInfoByUserIds(userIds)
|
||||
userMap2 := make(map[string]info.User, len(userMap))
|
||||
for userId, v := range userMap {
|
||||
userMap2[userId.Hex()] = v
|
||||
}
|
||||
|
||||
pageInfo = info.NewPage(page, pageSize, count, nil)
|
||||
|
||||
return pageInfo, comments, userMap
|
||||
return pageInfo, comments, userMap2
|
||||
}
|
||||
|
||||
// 举报
|
||||
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
|
||||
@@ -881,333 +569,3 @@ func (this *BlogService) Report(noteId, commentId, reason, userId string) bool {
|
||||
}
|
||||
return db.Insert(db.Reports, report)
|
||||
}
|
||||
|
||||
//---------------
|
||||
// 分类排序
|
||||
|
||||
// CateIds
|
||||
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 {
|
||||
page := 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, urlTitle string) (ok bool) {
|
||||
userBlog := this.GetUserBlog(userId)
|
||||
singles := userBlog.Singles
|
||||
if singles == nil {
|
||||
singles = []map[string]string{}
|
||||
}
|
||||
if isDelete || !isAdd { // 删除或更新, 需要找到相应的
|
||||
i := 0
|
||||
for _, p := range singles {
|
||||
if p["SingleId"] == singleId {
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
// 得到i
|
||||
// 找不到
|
||||
if i == len(singles) {
|
||||
} else {
|
||||
// 找到了, 如果是删除, 则删除
|
||||
if isDelete {
|
||||
singles = append(singles[:i], singles[i+1:]...)
|
||||
} else {
|
||||
// 是更新
|
||||
if title != "" {
|
||||
singles[i]["Title"] = title
|
||||
}
|
||||
if urlTitle != "" {
|
||||
singles[i]["UrlTitle"] = urlTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 是添加, 直接添加到最后
|
||||
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)
|
||||
}
|
||||
|
||||
// 删除页面
|
||||
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, "", "")
|
||||
}
|
||||
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,
|
||||
"UpdatedTime": time.Now(),
|
||||
})
|
||||
if ok {
|
||||
// 还要修改UserBlog中的Singles
|
||||
this.updateBlogSingles(userId, false, false, singleId, title, "")
|
||||
}
|
||||
return
|
||||
}
|
||||
// 添加
|
||||
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, page.UrlTitle)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 重新排序
|
||||
func (this *BlogService) SortSingles(userId string, singleIds []string) (ok bool) {
|
||||
if singleIds == nil || len(singleIds) == 0 {
|
||||
return
|
||||
}
|
||||
userBlog := this.GetUserBlog(userId)
|
||||
singles := userBlog.Singles
|
||||
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, username string) string {
|
||||
if userBlog.Domain != "" && configService.AllowCustomDomain() {
|
||||
return configService.GetUserUrl(userBlog.Domain)
|
||||
} else if userBlog.SubDomain != "" {
|
||||
return configService.GetUserSubUrl(userBlog.SubDomain)
|
||||
}
|
||||
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,
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,6 @@ import (
|
||||
// 配置服务
|
||||
// 只是全局的, 用户的配置没有
|
||||
type ConfigService struct {
|
||||
adminUserId string
|
||||
siteUrl string
|
||||
adminUsername string
|
||||
// 全局的
|
||||
GlobalAllConfigs map[string]interface{}
|
||||
GlobalStringConfigs map[string]string
|
||||
@@ -27,6 +24,9 @@ type ConfigService struct {
|
||||
GlobalMapConfigs map[string]map[string]string
|
||||
GlobalArrMapConfigs map[string][]map[string]string
|
||||
}
|
||||
|
||||
var adminUserId = ""
|
||||
|
||||
// appStart时 将全局的配置从数据库中得到作为全局
|
||||
func (this *ConfigService) InitGlobalConfigs() bool {
|
||||
this.GlobalAllConfigs = map[string]interface{}{}
|
||||
@@ -35,17 +35,16 @@ func (this *ConfigService) InitGlobalConfigs() bool {
|
||||
this.GlobalMapConfigs = map[string]map[string]string{}
|
||||
this.GlobalArrMapConfigs = map[string][]map[string]string{}
|
||||
|
||||
this.adminUsername, _ = revel.Config.String("adminUsername")
|
||||
if this.adminUsername == "" {
|
||||
this.adminUsername = "admin"
|
||||
adminUsername, _ := revel.Config.String("adminUsername")
|
||||
if adminUsername == "" {
|
||||
adminUsername = "admin"
|
||||
}
|
||||
this.siteUrl, _ = revel.Config.String("site.url")
|
||||
|
||||
userInfo := userService.GetUserInfoByAny(this.adminUsername)
|
||||
userInfo := userService.GetUserInfoByAny(adminUsername)
|
||||
if userInfo.UserId == "" {
|
||||
return false
|
||||
}
|
||||
this.adminUserId = userInfo.UserId.Hex()
|
||||
adminUserId = userInfo.UserId.Hex()
|
||||
|
||||
configs := []info.Config{}
|
||||
db.ListByQ(db.Configs, bson.M{"UserId": userInfo.UserId}, &configs)
|
||||
@@ -69,16 +68,6 @@ func (this *ConfigService) InitGlobalConfigs() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *ConfigService) GetSiteUrl() string {
|
||||
return this.siteUrl;
|
||||
}
|
||||
func (this *ConfigService) GetAdminUsername() string {
|
||||
return this.adminUsername
|
||||
}
|
||||
func (this *ConfigService) GetAdminUserId() string {
|
||||
return this.adminUserId
|
||||
}
|
||||
|
||||
// 通用方法
|
||||
func (this *ConfigService) updateGlobalConfig(userId, key string, value interface{}, isArr, isMap, isArrMap bool) bool {
|
||||
// 判断是否存在
|
||||
@@ -194,7 +183,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
if registerSharedUserId == "" {
|
||||
ok = true
|
||||
msg = "share userId is blank, So it share nothing to register"
|
||||
this.UpdateGlobalStringConfig(this.adminUserId, "registerSharedUserId", "")
|
||||
this.UpdateGlobalStringConfig(adminUserId, "registerSharedUserId", "")
|
||||
return
|
||||
} else {
|
||||
user := userService.GetUserInfo(registerSharedUserId)
|
||||
@@ -203,7 +192,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
msg = "no such user: " + registerSharedUserId
|
||||
return
|
||||
} else {
|
||||
this.UpdateGlobalStringConfig(this.adminUserId, "registerSharedUserId", registerSharedUserId)
|
||||
this.UpdateGlobalStringConfig(adminUserId, "registerSharedUserId", registerSharedUserId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +219,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
}
|
||||
}
|
||||
}
|
||||
this.UpdateGlobalArrMapConfig(this.adminUserId, "registerSharedNotebooks", notebooks)
|
||||
this.UpdateGlobalArrMapConfig(adminUserId, "registerSharedNotebooks", notebooks)
|
||||
|
||||
notes := []map[string]string{}
|
||||
// 共享笔记
|
||||
@@ -255,7 +244,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
}
|
||||
}
|
||||
}
|
||||
this.UpdateGlobalArrMapConfig(this.adminUserId, "registerSharedNotes", notes)
|
||||
this.UpdateGlobalArrMapConfig(adminUserId, "registerSharedNotes", notes)
|
||||
|
||||
// 复制
|
||||
noteIds := []string{}
|
||||
@@ -276,7 +265,7 @@ func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
|
||||
}
|
||||
}
|
||||
}
|
||||
this.UpdateGlobalArrayConfig(this.adminUserId, "registerCopyNoteIds", noteIds)
|
||||
this.UpdateGlobalArrayConfig(adminUserId, "registerCopyNoteIds", noteIds)
|
||||
|
||||
ok = true
|
||||
return
|
||||
@@ -288,7 +277,7 @@ func (this *ConfigService) AddBackup(path, remark string) bool {
|
||||
n := time.Now().Unix()
|
||||
nstr := fmt.Sprintf("%v", n)
|
||||
backups = append(backups, map[string]string{"createdTime": nstr, "path": path, "remark": remark})
|
||||
return this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
|
||||
return this.UpdateGlobalArrMapConfig(adminUserId, "backups", backups)
|
||||
}
|
||||
|
||||
func (this *ConfigService) getBackupDirname() string {
|
||||
@@ -304,7 +293,7 @@ func (this *ConfigService) Backup(remark string) (ok bool, msg string) {
|
||||
port, _ := revel.Config.String("db.port")
|
||||
username, _ := revel.Config.String("db.username")
|
||||
password, _ := revel.Config.String("db.password")
|
||||
// mongodump -h localhost -d leanote -o /root/mongodb_backup/leanote-9-22/ -u leanote -p nKFAkxKnWkEQy8Vv2LlM
|
||||
// mongodump -h localhost -d leanote -o /root/mongodb_backup/leanote-10-25/ -u leanote -p xx
|
||||
binPath = binPath + " -h " + host + " -d " + dbname + " -port " + port
|
||||
if username != "" {
|
||||
binPath += " -u " + username + " -p " + password
|
||||
@@ -409,7 +398,7 @@ func (this *ConfigService) DeleteBackup(createdTime string) (bool, string) {
|
||||
// 删除之
|
||||
backups = append(backups[0:i], backups[i+1:]...)
|
||||
|
||||
ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
|
||||
ok := this.UpdateGlobalArrMapConfig(adminUserId, "backups", backups)
|
||||
return ok, ""
|
||||
}
|
||||
|
||||
@@ -427,7 +416,7 @@ func (this *ConfigService) UpdateBackupRemark(createdTime, remark string) (bool,
|
||||
}
|
||||
backup["remark"] = remark;
|
||||
|
||||
ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
|
||||
ok := this.UpdateGlobalArrMapConfig(adminUserId, "backups", backups)
|
||||
return ok, ""
|
||||
}
|
||||
|
||||
@@ -462,7 +451,7 @@ func init() {
|
||||
port = "";
|
||||
}
|
||||
|
||||
siteUrl, _ := revel.Config.String("site.url") // 已包含:9000, http, 去掉成 leanote.com
|
||||
siteUrl, _ = revel.Config.String("site.url") // 已包含:9000, http, 去掉成 leanote.com
|
||||
if strings.HasPrefix(siteUrl, "http://") {
|
||||
defaultDomain = siteUrl[len("http://"):]
|
||||
} else if strings.HasPrefix(siteUrl, "https://") {
|
||||
@@ -472,6 +461,7 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func (this *ConfigService) GetSchema() string {
|
||||
return schema;
|
||||
}
|
||||
@@ -549,36 +539,3 @@ func (this *ConfigService) IsGoodSubDomain(domain string) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 上传大小
|
||||
func (this *ConfigService) GetUploadSize(key string) float64 {
|
||||
f, _ := strconv.ParseFloat(this.GetGlobalStringConfig(key), 64)
|
||||
return f;
|
||||
}
|
||||
func (this *ConfigService) GetUploadSizeLimit() map[string]float64 {
|
||||
return map[string]float64{
|
||||
"uploadImageSize": this.GetUploadSize("uploadImageSize"),
|
||||
"uploadBlogLogoSize":this.GetUploadSize("uploadBlogLogoSize"),
|
||||
"uploadAttachSize":this.GetUploadSize("uploadAttachSize"),
|
||||
"uploadAvatarSize":this.GetUploadSize("uploadAvatarSize"),
|
||||
}
|
||||
}
|
||||
// 为用户得到全局的配置
|
||||
// NoteController调用
|
||||
func (this *ConfigService) GetGlobalConfigForUser() map[string]interface{} {
|
||||
uploadSizeConfigs := this.GetUploadSizeLimit();
|
||||
config := map[string]interface{}{}
|
||||
for k, v := range uploadSizeConfigs {
|
||||
config[k] = v
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// 主页是否是管理员的博客页
|
||||
func (this *ConfigService) HomePageIsAdminsBlog() bool {
|
||||
return this.GetGlobalStringConfig("homePage") == ""
|
||||
}
|
||||
|
||||
func (this *ConfigService) GetVersion() string {
|
||||
return "1.0-beta2"
|
||||
}
|
||||
+10
-10
@@ -82,9 +82,9 @@ func (this *EmailService) RegisterSendActiveEmail(userInfo info.User, email stri
|
||||
return false
|
||||
}
|
||||
|
||||
tokenUrl := configService.GetSiteUrl() + "/user/activeEmail?token=" + token
|
||||
tokenUrl := siteUrl + "/user/activeEmail?token=" + token
|
||||
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.id} {user.email} {user.username}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
||||
token2Value := map[string]interface{}{"siteUrl": siteUrl, "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
||||
"user": map[string]interface{}{
|
||||
"userId": userInfo.UserId.Hex(),
|
||||
"email": userInfo.Email,
|
||||
@@ -122,9 +122,9 @@ func (this *EmailService) UpdateEmailSendActiveEmail(userInfo info.User, email s
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateUpdateEmail");
|
||||
|
||||
// 发送邮件
|
||||
tokenUrl := configService.GetSiteUrl() + "/user/updateEmail?token=" + token
|
||||
tokenUrl := siteUrl + "/user/updateEmail?token=" + token
|
||||
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.userId} {user.email} {user.username}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
||||
token2Value := map[string]interface{}{"siteUrl": siteUrl, "tokenUrl": tokenUrl, "token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail))),
|
||||
"newEmail": email,
|
||||
"user": map[string]interface{}{
|
||||
"userId": userInfo.UserId.Hex(),
|
||||
@@ -148,9 +148,9 @@ func (this *EmailService) FindPwdSendEmail(token, email string) (ok bool, msg st
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateFindPassword");
|
||||
|
||||
// 发送邮件
|
||||
tokenUrl := configService.GetSiteUrl() + "/findPassword/" + token
|
||||
tokenUrl := siteUrl + "/findPassword/" + token
|
||||
// {siteUrl} {tokenUrl} {token} {tokenTimeout} {user.id} {user.email} {user.username}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "tokenUrl": tokenUrl,
|
||||
token2Value := map[string]interface{}{"siteUrl": siteUrl, "tokenUrl": tokenUrl,
|
||||
"token": token, "tokenTimeout": strconv.Itoa(int(tokenService.GetOverHours(info.TokenActiveEmail)))}
|
||||
|
||||
ok, msg, subject, tpl = this.renderEmail(subject, tpl, token2Value)
|
||||
@@ -167,8 +167,8 @@ func (this *EmailService) SendInviteEmail(userInfo info.User, email, content str
|
||||
subject := configService.GetGlobalStringConfig("emailTemplateInviteSubject");
|
||||
tpl := configService.GetGlobalStringConfig("emailTemplateInvite");
|
||||
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(),
|
||||
"registerUrl": configService.GetSiteUrl() + "/register?from=" + userInfo.Username,
|
||||
token2Value := map[string]interface{}{"siteUrl": siteUrl,
|
||||
"registerUrl": siteUrl + "/register?from=" + userInfo.Username,
|
||||
"content": content,
|
||||
"user": map[string]interface{}{
|
||||
"username": userInfo.Username,
|
||||
@@ -225,7 +225,7 @@ func (this *EmailService) SendCommentEmail(note info.Note, comment info.BlogComm
|
||||
// {blog.id} {blog.title} {blog.url}
|
||||
// {commentUser.userId} {commentUser.username} {commentUser.email}
|
||||
// {commentedUser.userId} {commentedUser.username} {commentedUser.email}
|
||||
token2Value := map[string]interface{}{"siteUrl": configService.GetSiteUrl(), "blogUrl": configService.GetBlogUrl(),
|
||||
token2Value := map[string]interface{}{"siteUrl": siteUrl, "blogUrl": configService.GetBlogUrl(),
|
||||
"blog": map[string]string{
|
||||
"id": note.NoteId.Hex(),
|
||||
"title": note.Title,
|
||||
@@ -316,7 +316,7 @@ func (this *EmailService) renderEmail(subject, body string, values map[string]in
|
||||
|
||||
var tpl *template.Template
|
||||
|
||||
values["siteUrl"] = configService.GetSiteUrl();
|
||||
values["siteUrl"] = siteUrl;
|
||||
|
||||
// subject
|
||||
if subject != "" {
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
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)}), ""
|
||||
}
|
||||
@@ -32,12 +32,7 @@ func (this *NoteImageService) GetNoteIds(imageId string) ([]bson.ObjectId) {
|
||||
// 解析内容中的图片, 建立图片与note的关系
|
||||
// <img src="/file/outputImage?fileId=12323232" />
|
||||
// 图片必须是我的, 不然不添加
|
||||
// imgSrc 防止博客修改了, 但内容删除了
|
||||
func (this *NoteImageService) UpdateNoteImages(userId, noteId, imgSrc, content string) bool {
|
||||
// 让主图成为内容的一员
|
||||
if imgSrc != "" {
|
||||
content = "<img src=\"" + imgSrc + "\" >" + content
|
||||
}
|
||||
func (this *NoteImageService) UpdateNoteImages(userId, noteId, content string) bool {
|
||||
reg, _ := regexp.Compile("outputImage\\?fileId=([a-z0-9A-Z]{24})")
|
||||
find := reg.FindAllStringSubmatch(content, -1) // 查找所有的
|
||||
|
||||
|
||||
+13
-80
@@ -111,16 +111,10 @@ func (this *NoteService) ListNoteAbstractsByNoteIds(noteIds []bson.ObjectId) (no
|
||||
db.ListByQWithFields(db.NoteContents, bson.M{"_id": bson.M{"$in": noteIds}}, []string{"_id", "Abstract"}, ¬es)
|
||||
return
|
||||
}
|
||||
func (this *NoteService) ListNoteContentByNoteIds(noteIds []bson.ObjectId) (notes []info.NoteContent) {
|
||||
notes = []info.NoteContent{}
|
||||
db.ListByQWithFields(db.NoteContents, bson.M{"_id": bson.M{"$in": noteIds}}, []string{"_id", "Abstract", "Content"}, ¬es)
|
||||
return
|
||||
}
|
||||
|
||||
// 添加笔记
|
||||
// 首先要判断Notebook是否是Blog, 是的话设为blog
|
||||
// [ok]
|
||||
|
||||
func (this *NoteService) AddNote(note info.Note) info.Note {
|
||||
if(note.NoteId.Hex() == "") {
|
||||
noteId := bson.NewObjectId();
|
||||
@@ -130,7 +124,6 @@ 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()
|
||||
@@ -171,24 +164,13 @@ 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;
|
||||
}
|
||||
|
||||
// 添加笔记和内容
|
||||
// 这里使用 info.NoteAndContent 接收?
|
||||
func (this *NoteService) AddNoteAndContentForController(note info.Note, noteContent info.NoteContent, updatedUserId string) info.Note {
|
||||
if note.UserId.Hex() != updatedUserId {
|
||||
if !shareService.HasUpdateNotebookPerm(note.UserId.Hex(), updatedUserId, note.NotebookId.Hex()) {
|
||||
Log("NO AUTH11")
|
||||
return info.Note{}
|
||||
} else {
|
||||
Log("HAS AUTH -----------")
|
||||
}
|
||||
}
|
||||
return this.AddNoteAndContent(note, noteContent, bson.ObjectIdHex(updatedUserId));
|
||||
}
|
||||
func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note {
|
||||
if(note.NoteId.Hex() == "") {
|
||||
noteId := bson.NewObjectId()
|
||||
@@ -207,24 +189,18 @@ 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 {
|
||||
if !shareService.HasUpdatePerm(userId, updatedUserId, noteId) {
|
||||
Log("NO AUTH2")
|
||||
Log("NO AUTH")
|
||||
return false
|
||||
} else {
|
||||
Log("HAS AUTH -----------")
|
||||
}
|
||||
}
|
||||
|
||||
// 是否已自定义
|
||||
note := this.GetNoteById(noteId)
|
||||
if note.IsBlog && note.HasSelfDefined {
|
||||
delete(needUpdate, "ImgSrc")
|
||||
delete(needUpdate, "Desc")
|
||||
}
|
||||
|
||||
needUpdate["UpdatedUserId"] = bson.ObjectIdHex(updatedUserId);
|
||||
needUpdate["UpdatedTime"] = time.Now();
|
||||
|
||||
@@ -268,18 +244,12 @@ func (this *NoteService) UpdateNoteContent(userId, updatedUserId, noteId, conten
|
||||
}
|
||||
}
|
||||
|
||||
data := bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId),
|
||||
if db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId,
|
||||
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,
|
||||
@@ -287,7 +257,7 @@ func (this *NoteService) UpdateNoteContent(userId, updatedUserId, noteId, conten
|
||||
})
|
||||
|
||||
// 更新笔记图片
|
||||
noteImageService.UpdateNoteImages(userId, noteId, note.ImgSrc, content)
|
||||
noteImageService.UpdateNoteImages(userId, noteId, content)
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -308,29 +278,6 @@ func (this *NoteService) UpdateTags(noteId string, userId string, tags []string)
|
||||
return db.UpdateByIdAndUserIdField(db.Notes, noteId, userId, "Tags", tags)
|
||||
}
|
||||
|
||||
func (this *NoteService) ToBlog(userId, noteId string, isBlog, isTop bool) bool {
|
||||
noteUpdate := bson.M{}
|
||||
if isTop {
|
||||
isBlog = true
|
||||
}
|
||||
if !isBlog {
|
||||
isTop = false
|
||||
}
|
||||
noteUpdate["IsBlog"] = isBlog
|
||||
noteUpdate["IsTop"] = isTop
|
||||
if isBlog {
|
||||
noteUpdate["PublicTime"] = time.Now()
|
||||
} else {
|
||||
noteUpdate["HasSelfDefined"] = false
|
||||
}
|
||||
ok := db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, noteUpdate)
|
||||
// 重新计算tags
|
||||
go (func() {
|
||||
blogService.ReCountBlogTags(userId)
|
||||
})()
|
||||
return ok
|
||||
}
|
||||
|
||||
// 移动note
|
||||
// trash, 正常的都可以用
|
||||
// 1. 要检查下notebookId是否是自己的
|
||||
@@ -472,20 +419,15 @@ func (this *NoteService) GetNotebookId(noteId string) bson.ObjectId {
|
||||
}
|
||||
|
||||
//------------------
|
||||
// 搜索Note, 博客使用了
|
||||
// 搜索Note
|
||||
func (this *NoteService) SearchNote(key, userId string, pageNumber, pageSize int, sortField string, isAsc, isBlog bool) (count int, notes []info.Note) {
|
||||
notes = []info.Note{}
|
||||
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
|
||||
|
||||
// 利用标题和desc, 不用content
|
||||
orQ := []bson.M{
|
||||
bson.M{"Title": bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}}},
|
||||
bson.M{"Desc": bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}}},
|
||||
}
|
||||
// 不是trash的
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId),
|
||||
"IsTrash": false,
|
||||
"$or": orQ,
|
||||
"Title": bson.M{"$regex": bson.RegEx{".*?" + key + ".*", "i"}},
|
||||
}
|
||||
if isBlog {
|
||||
query["IsBlog"] = true
|
||||
@@ -567,20 +509,11 @@ func (this *NoteService) SearchNoteByTags(tags []string, userId string, pageNumb
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
//------------
|
||||
// 统计
|
||||
func (this *NoteService) CountNote(userId string) int {
|
||||
q := bson.M{"IsTrash": false}
|
||||
if userId != "" {
|
||||
q["UserId"] = bson.ObjectIdHex(userId)
|
||||
func (this *NoteService) CountNote() int {
|
||||
return db.Count(db.Notes, bson.M{"IsTrash": false})
|
||||
}
|
||||
return db.Count(db.Notes, q)
|
||||
}
|
||||
func (this *NoteService) CountBlog(userId string) int {
|
||||
q := bson.M{"IsBlog": true, "IsTrash": false}
|
||||
if userId != "" {
|
||||
q["UserId"] = bson.ObjectIdHex(userId)
|
||||
}
|
||||
return db.Count(db.Notes, q)
|
||||
func (this *NoteService) CountBlog() int {
|
||||
return db.Count(db.Notes, bson.M{"IsBlog": true, "IsTrash": false})
|
||||
}
|
||||
@@ -101,15 +101,6 @@ 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
|
||||
// 排序好之后返回
|
||||
@@ -142,7 +133,6 @@ 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,22 +170,16 @@ func (this *NotebookService) UpdateNotebookTitle(notebookId, userId, title strin
|
||||
// 更新notebook
|
||||
func (this *NotebookService) UpdateNotebook(userId, notebookId string, needUpdate bson.M) bool {
|
||||
needUpdate["UpdatedTime"] = time.Now();
|
||||
return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, needUpdate)
|
||||
}
|
||||
|
||||
// ToBlog or Not
|
||||
func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (bool) {
|
||||
// 笔记本
|
||||
db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, bson.M{"IsBlog": isBlog})
|
||||
|
||||
// 更新笔记
|
||||
// 如果有IsBlog之类的, 需要特殊处理
|
||||
if isBlog, ok := needUpdate["IsBlog"]; ok {
|
||||
// 设为blog/取消, 把它下面所有的note都设为isBlog
|
||||
if is, ok2 := isBlog.(bool); ok2 {
|
||||
q := bson.M{"UserId": bson.ObjectIdHex(userId),
|
||||
"NotebookId": bson.ObjectIdHex(notebookId)}
|
||||
data := bson.M{"IsBlog": isBlog}
|
||||
if isBlog {
|
||||
data := bson.M{"IsBlog": is}
|
||||
if is {
|
||||
data["PublicTime"] = time.Now()
|
||||
} else {
|
||||
data["HasSelfDefined"] = false
|
||||
}
|
||||
db.UpdateByQMap(db.Notes, q, data)
|
||||
|
||||
@@ -210,13 +194,10 @@ func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (boo
|
||||
}
|
||||
db.UpdateByQMap(db.NoteContents, bson.M{"_id": bson.M{"$in": noteIds}}, bson.M{"IsBlog": isBlog})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重新计算tags
|
||||
go (func() {
|
||||
blogService.ReCountBlogTags(userId)
|
||||
})()
|
||||
|
||||
return true
|
||||
return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, needUpdate)
|
||||
}
|
||||
|
||||
// 查看是否有子notebook
|
||||
|
||||
+68
-267
@@ -13,10 +13,7 @@ import (
|
||||
type ShareService struct {
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// 返回shareNotebooks, sharedUserInfos
|
||||
// info.ShareNotebooksByUser, []info.User
|
||||
|
||||
//-----------------
|
||||
// 总体来说, 这个方法比较麻烦, 速度未知. 以后按以下方案来缓存用户基础数据
|
||||
|
||||
// 以后建个用户的基本数据表, 放所有notebook, sharedNotebook的缓存!!
|
||||
@@ -30,48 +27,23 @@ type ShareService struct {
|
||||
// 3 每个层按seq进行排序
|
||||
// 4 按用户分组
|
||||
// [ok]
|
||||
|
||||
// 谁共享给了我的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)
|
||||
//-------------
|
||||
// 查询HasShareNote表得到所有其它用户信息
|
||||
hasShareNotes := []info.HasShareNote{}
|
||||
db.ListByQ(db.HasShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(userId)}, &hasShareNotes);
|
||||
|
||||
// 不查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...)
|
||||
userIds := make([]bson.ObjectId, len(hasShareNotes))
|
||||
for i, each := range hasShareNotes {
|
||||
userIds[i] = each.UserId
|
||||
}
|
||||
userInfos := userService.GetUserInfosOrderBySeq(userIds);
|
||||
|
||||
//--------------------
|
||||
// 得到他们共享给我的notebooks
|
||||
|
||||
// 这里可能会得到重复的记录
|
||||
// 权限: 笔记本分享给个人 > 笔记本分享给组织
|
||||
shareNotebooks := []info.ShareNotebook{}
|
||||
db.ShareNotebooks.Find(q).Sort("-ToUserId").All(&shareNotebooks) // 按ToUserId降序排序, 那么有ToUserId的在前面
|
||||
db.ShareNotebooks.Find(bson.M{"ToUserId": bson.ObjectIdHex(userId)}).All(&shareNotebooks)
|
||||
|
||||
if len(shareNotebooks) == 0 {
|
||||
return nil, userInfos
|
||||
@@ -80,16 +52,13 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB
|
||||
shareNotebooksLen := len(shareNotebooks)
|
||||
|
||||
// 找到了所有的notbookId, 那么找notebook表得到其详细信息
|
||||
notebookIds := []bson.ObjectId{}
|
||||
notebookIds := make([]bson.ObjectId, shareNotebooksLen)
|
||||
shareNotebooksMap := make(map[bson.ObjectId]info.ShareNotebook, shareNotebooksLen)
|
||||
for _, each := range shareNotebooks {
|
||||
// 之后的就不要了, 只留权限高的
|
||||
if _, ok := shareNotebooksMap[each.NotebookId]; !ok {
|
||||
for i, each := range shareNotebooks {
|
||||
// 默认的是没有notebookId的
|
||||
notebookIds = append(notebookIds, each.NotebookId)
|
||||
notebookIds[i] = each.NotebookId
|
||||
shareNotebooksMap[each.NotebookId] = each
|
||||
}
|
||||
}
|
||||
|
||||
// 1, 2
|
||||
subNotebooks := notebookService.GetNotebooksByNotebookIds(notebookIds)
|
||||
@@ -158,13 +127,9 @@ 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,
|
||||
q,
|
||||
&shareNotebook)
|
||||
db.GetByQ(db.ShareNotebooks, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(sharedUserId), "ToUserId": bson.ObjectIdHex(myUserId)}, &shareNotebook)
|
||||
|
||||
if shareNotebook.NotebookId == "" {
|
||||
return nil
|
||||
@@ -181,19 +146,7 @@ func (this *ShareService) ListShareNotesByNotebookId(notebookId, myUserId, share
|
||||
for i, note := range notes {
|
||||
noteIds[i] = note.NoteId
|
||||
}
|
||||
// 笔记的权限
|
||||
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);
|
||||
notePerms := this.getNotesPerm(noteIds, myUserId, sharedUserId);
|
||||
|
||||
// 3.2 组合
|
||||
notesWithPerm := make([]info.ShareNoteWithPerm, len(notes))
|
||||
@@ -209,21 +162,17 @@ 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
|
||||
@@ -235,12 +184,9 @@ 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(q).
|
||||
Sort("-ToUserId"). // 给个人的权限 > 给组织的权限
|
||||
Find(bson.M{"UserId": bson.ObjectIdHex(sharedUserId), "ToUserId": bson.ObjectIdHex(myUserId)}).
|
||||
// Sort(sortFieldR).
|
||||
Skip(skipNum).
|
||||
Limit(pageSize).
|
||||
All(&shareNotes)
|
||||
@@ -254,20 +200,15 @@ func (this *ShareService) ListShareNotes(myUserId, sharedUserId string,
|
||||
noteIds[i] = each.NoteId
|
||||
}
|
||||
notes := noteService.ListNotesByNoteIds(noteIds)
|
||||
notesMap := map[bson.ObjectId]info.Note{}
|
||||
notesMap := make(map[bson.ObjectId]info.Note, len(notes))
|
||||
for _, each := range notes {
|
||||
notesMap[each.NoteId] = each
|
||||
}
|
||||
|
||||
// 将shareNotes与notes结合起来
|
||||
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
|
||||
}
|
||||
notesWithPerm := make([]info.ShareNoteWithPerm, len(shareNotes))
|
||||
for i, each := range shareNotes {
|
||||
notesWithPerm[i] = info.ShareNoteWithPerm{notesMap[each.NoteId], each.Perm}
|
||||
}
|
||||
return notesWithPerm
|
||||
}
|
||||
@@ -345,25 +286,19 @@ 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 {
|
||||
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) {
|
||||
if !db.Has(db.ShareNotes,
|
||||
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NoteId": bson.ObjectIdHex(noteId)}) {
|
||||
// noteId的notebookId是否被共享了?
|
||||
notebookId := noteService.GetNotebookId(noteId)
|
||||
if notebookId.Hex() == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
delete(q, "NoteId")
|
||||
q["NotebookId"] = notebookId
|
||||
|
||||
// 判断notebook是否被共享
|
||||
if !db.Has(db.ShareNotebooks, q) {
|
||||
if !db.Has(db.ShareNotebooks,
|
||||
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NotebookId": notebookId}) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
@@ -375,44 +310,43 @@ func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool
|
||||
|
||||
// updatedUserId是否有修改userId noteId的权限?
|
||||
func (this *ShareService) HasUpdatePerm(userId, updatedUserId, noteId string) bool {
|
||||
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的权限
|
||||
// 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
|
||||
}
|
||||
|
||||
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个权限最大
|
||||
}
|
||||
// 判断notebook是否被共享
|
||||
if !db.Has(db.ShareNotebooks,
|
||||
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NotebookId": notebookId, "Perm": 1}) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// updatedUserId是否有修改userId notebookId的权限?
|
||||
func (this *ShareService) HasUpdateNotebookPerm(userId, updatedUserId, notebookId string) bool {
|
||||
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个权限最大
|
||||
}
|
||||
// 判断notebook是否被共享
|
||||
if !db.Has(db.ShareNotebooks,
|
||||
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NotebookId": bson.ObjectIdHex(notebookId), "Perm": 1}) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 共享note, notebook时使用
|
||||
@@ -438,16 +372,12 @@ 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共享了我
|
||||
// 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) {
|
||||
if this.HasSharedNote(noteId, myUserId) || this.HasSharedNotebook(noteId, myUserId, sharedUserId) {
|
||||
db.Get(db.NoteContents, noteId, ¬eContent)
|
||||
} else {
|
||||
}
|
||||
@@ -461,15 +391,7 @@ 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),
|
||||
"ToGroupId": bson.M{"$exists": false},
|
||||
}, &shareNotes, 100)
|
||||
|
||||
// Log("<<>>>>")
|
||||
// Log(len(shareNotes))
|
||||
db.ListByQLimit(db.ShareNotes, bson.M{"NoteId": bson.ObjectIdHex(noteId), "UserId": bson.ObjectIdHex(userId)}, &shareNotes, 100)
|
||||
|
||||
if len(shareNotes) == 0 {
|
||||
return nil
|
||||
@@ -528,11 +450,7 @@ func (this *ShareService) ListNotebookShareUserInfo(notebookId, userId string) [
|
||||
shareNotebooks := []info.ShareNotebook{}
|
||||
|
||||
db.ListByQLimit(db.ShareNotebooks,
|
||||
bson.M{
|
||||
"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"ToGroupId": bson.M{"$exists": false},
|
||||
},
|
||||
bson.M{"NotebookId": bson.ObjectIdHex(notebookId), "UserId": bson.ObjectIdHex(userId)},
|
||||
&shareNotebooks, 100)
|
||||
|
||||
if len(shareNotebooks) == 0 {
|
||||
@@ -637,7 +555,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;
|
||||
@@ -659,120 +577,3 @@ func (this *ShareService) HasReadNotePerm(noteId, userId string) bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------
|
||||
// 用户分组
|
||||
|
||||
// 得到笔记分享给的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),
|
||||
});
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/lea/archive"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"strings"
|
||||
"os"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"regexp"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// 主题
|
||||
type ThemeService struct {
|
||||
}
|
||||
|
||||
var defaultStyle = "blog_default"
|
||||
var elegantStyle = "blog_daqi"
|
||||
var fixedStyle = "blog_left_fixed"
|
||||
|
||||
// admin用户的主题基路径
|
||||
func (this *ThemeService) getDefaultThemeBasePath() string {
|
||||
return revel.BasePath + "/public/blog/themes"
|
||||
}
|
||||
// 默认主题路径
|
||||
func (this *ThemeService) getDefaultThemePath(style string) string {
|
||||
if style == elegantStyle {
|
||||
return this.getDefaultThemeBasePath() + "/elegant"
|
||||
} else if style == fixedStyle {
|
||||
return this.getDefaultThemeBasePath() + "/nav_fixed"
|
||||
} else {
|
||||
return this.getDefaultThemeBasePath() + "/default"
|
||||
}
|
||||
}
|
||||
// blogService用
|
||||
func (this *ThemeService) GetDefaultThemePath(style string) string {
|
||||
if style == elegantStyle {
|
||||
return "public/blog/themes/elegant"
|
||||
} else if style == fixedStyle {
|
||||
return "public/blog/themes/nav_fixed"
|
||||
} else {
|
||||
return "public/blog/themes/default"
|
||||
}
|
||||
}
|
||||
|
||||
// 得到默认主题
|
||||
// style是之前的值, 有3个值 blog_default, blog_daqi, blog_left_fixed
|
||||
func (this *ThemeService) getDefaultTheme(style string) info.Theme {
|
||||
if style == elegantStyle {
|
||||
return info.Theme{
|
||||
IsDefault: true,
|
||||
Path: "public/blog/themes/elegant",
|
||||
Name: "leanote elegant",
|
||||
Author: "leanote",
|
||||
AuthorUrl: "http://leanote.com",
|
||||
Version: "1.0",
|
||||
}
|
||||
} else if style == fixedStyle {
|
||||
return info.Theme{
|
||||
IsDefault: true,
|
||||
Path: "public/blog/themes/nav_fixed",
|
||||
Name: "leanote nav fixed",
|
||||
Author: "leanote",
|
||||
AuthorUrl: "http://leanote.com",
|
||||
Version: "1.0",
|
||||
}
|
||||
} else { // blog default
|
||||
return info.Theme{
|
||||
IsDefault: true,
|
||||
Path: "public/blog/themes/default",
|
||||
Name: "leanote default",
|
||||
Author: "leanote",
|
||||
AuthorUrl: "http://leanote.com",
|
||||
Version: "1.0",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 用户的主题路径设置
|
||||
func (this *ThemeService) getUserThemeBasePath(userId string) string {
|
||||
return revel.BasePath + "/public/upload/" + userId + "/themes"
|
||||
}
|
||||
func (this *ThemeService) getUserThemePath(userId, themeId string) string {
|
||||
return this.getUserThemeBasePath(userId) + "/" + themeId
|
||||
}
|
||||
func (this *ThemeService) getUserThemePath2(userId, themeId string) string {
|
||||
return "public/upload/" + userId + "/themes/" + themeId
|
||||
}
|
||||
|
||||
// 新建主题
|
||||
// 复制默认主题到文件夹下
|
||||
func (this *ThemeService) CopyDefaultTheme(userBlog info.UserBlog) (ok bool, themeId string) {
|
||||
newThemeId := bson.NewObjectId()
|
||||
themeId = newThemeId.Hex()
|
||||
userId := userBlog.UserId.Hex()
|
||||
themePath := this.getUserThemePath(userId, themeId)
|
||||
err := os.MkdirAll(themePath, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 复制默认主题
|
||||
defaultThemePath := this.getDefaultThemePath(userBlog.Style)
|
||||
err = CopyDir(defaultThemePath, themePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 保存到数据库中
|
||||
theme, _ := this.getThemeConfig(themePath)
|
||||
theme.ThemeId = newThemeId
|
||||
theme.Path = this.getUserThemePath2(userId, themeId)
|
||||
theme.CreatedTime = time.Now()
|
||||
theme.UpdatedTime = theme.CreatedTime
|
||||
theme.UserId = bson.ObjectIdHex(userId)
|
||||
|
||||
ok = db.Insert(db.Themes, theme)
|
||||
return ok, themeId
|
||||
}
|
||||
|
||||
// 第一次新建主题
|
||||
// 设为active true
|
||||
func (this *ThemeService) NewThemeForFirst(userBlog info.UserBlog) (ok bool, themeId string) {
|
||||
ok, themeId = this.CopyDefaultTheme(userBlog)
|
||||
db.UpdateByQField(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId)}, "IsActive", true)
|
||||
return
|
||||
}
|
||||
|
||||
// 新建主题, 判断是否有主题了
|
||||
func (this *ThemeService) NewTheme(userId string) (ok bool, themeId string) {
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
// 如果还没有主题, 那先复制旧的主题
|
||||
if userBlog.ThemeId == "" {
|
||||
themeService.NewThemeForFirst(userBlog)
|
||||
}
|
||||
// 再copy一个默认主题
|
||||
userBlog.Style = "defaultStyle";
|
||||
ok, themeId = this.CopyDefaultTheme(userBlog)
|
||||
return
|
||||
}
|
||||
|
||||
// 将字符串转成Theme配置
|
||||
func (this *ThemeService) parseConfig(configStr string) (theme info.Theme, err error) {
|
||||
theme = info.Theme{}
|
||||
// 除去/**/注释
|
||||
reg, _ := regexp.Compile("/\\*[\\s\\S]*?\\*/")
|
||||
configStr = reg.ReplaceAllString(configStr, "")
|
||||
// 转成map
|
||||
config := map[string]interface{}{}
|
||||
err = json.Unmarshal([]byte(configStr), &config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 没有错, 则将Name, Version, Author, AuthorUrl
|
||||
Name := config["Name"]
|
||||
if Name != nil {
|
||||
theme.Name = Name.(string)
|
||||
}
|
||||
Version := config["Version"]
|
||||
if Version != nil {
|
||||
theme.Version = Version.(string)
|
||||
}
|
||||
Author := config["Author"]
|
||||
if Author != nil {
|
||||
theme.Author = Author.(string)
|
||||
}
|
||||
AuthorUrl := config["AuthorUrl"]
|
||||
if AuthorUrl != nil {
|
||||
theme.AuthorUrl = AuthorUrl.(string)
|
||||
}
|
||||
theme.Info = config
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 读取theme.json得到值
|
||||
func (this *ThemeService) getThemeConfig(themePath string) (theme info.Theme, err error) {
|
||||
theme = info.Theme{}
|
||||
configStr := GetFileStrContent(themePath + "/theme.json")
|
||||
theme, err = this.parseConfig(configStr)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *ThemeService) GetTheme(userId, themeId string) info.Theme {
|
||||
theme := info.Theme{}
|
||||
db.GetByQ(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)}, &theme)
|
||||
return theme
|
||||
}
|
||||
func (this *ThemeService) GetThemeById(themeId string) info.Theme {
|
||||
theme := info.Theme{}
|
||||
db.GetByQ(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId)}, &theme)
|
||||
return theme
|
||||
}
|
||||
|
||||
// 得到主题信息, 为了给博客用
|
||||
func (this *ThemeService) GetThemeInfo(themeId, style string) map[string]interface{} {
|
||||
q := bson.M{}
|
||||
if themeId == "" {
|
||||
if style == "" {
|
||||
style = defaultStyle
|
||||
}
|
||||
q["Style"] = style
|
||||
q["IsDefault"] = true
|
||||
} else {
|
||||
q["_id"] = bson.ObjectIdHex(themeId)
|
||||
}
|
||||
theme := info.Theme{}
|
||||
db.GetByQ(db.Themes, q, &theme)
|
||||
return theme.Info
|
||||
}
|
||||
|
||||
// 得到用户的主题
|
||||
// 若用户没有主题, 则至少有一个默认主题
|
||||
// 第一个返回值是当前active
|
||||
func (this *ThemeService) GetUserThemes(userId string) (theme info.Theme, themes []info.Theme) {
|
||||
theme = info.Theme{}
|
||||
themes = []info.Theme{}
|
||||
|
||||
// db.ListByQ(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId)}, &themes)
|
||||
|
||||
// 创建时间逆序
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId)}
|
||||
q := db.Themes.Find(query);
|
||||
q.Sort("-CreatedTime").All(&themes)
|
||||
if len(themes) == 0 {
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
theme = this.getDefaultTheme(userBlog.Style)
|
||||
} else {
|
||||
var has = false
|
||||
// 第一个是active的主题
|
||||
themes2 := make([]info.Theme, len(themes))
|
||||
i := 0
|
||||
for _, t := range themes {
|
||||
if t.IsActive {
|
||||
theme = t
|
||||
} else {
|
||||
has = true
|
||||
themes2[i] = t
|
||||
i++
|
||||
}
|
||||
}
|
||||
if has {
|
||||
themes = themes2
|
||||
} else {
|
||||
themes = nil
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 得到默认主题供选择
|
||||
func (this *ThemeService) GetDefaultThemes() (themes []info.Theme) {
|
||||
themes = []info.Theme{}
|
||||
db.ListByQ(db.Themes, bson.M{"IsDefault": true}, &themes)
|
||||
return
|
||||
}
|
||||
|
||||
// 得到模板内容
|
||||
func (this *ThemeService) GetTplContent(userId, themeId, filename string) string {
|
||||
path := this.GetThemeAbsolutePath(userId, themeId) + "/" + filename
|
||||
return GetFileStrContent(path)
|
||||
}
|
||||
|
||||
// 得到主题的绝对路径
|
||||
func (this *ThemeService) GetThemeAbsolutePath(userId, themeId string) string {
|
||||
theme := info.Theme{}
|
||||
db.GetByQWithFields(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)}, []string{"Path"}, &theme)
|
||||
if theme.Path != "" {
|
||||
return revel.BasePath + "/" + theme.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func (this *ThemeService) GetThemePath(userId, themeId string) string {
|
||||
theme := info.Theme{}
|
||||
db.GetByQWithFields(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)}, []string{"Path"}, &theme)
|
||||
if theme.Path != "" {
|
||||
return theme.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
// 更新模板内容
|
||||
func (this *ThemeService) UpdateTplContent(userId, themeId, filename, content string) (ok bool, msg string) {
|
||||
path := this.GetThemeAbsolutePath(userId, themeId) + "/" + filename
|
||||
if strings.Contains(filename, ".html") {
|
||||
// 模板
|
||||
if ok, msg = this.mustTpl(filename, content); ok {
|
||||
ok = PutFileStrContent(path, content)
|
||||
}
|
||||
return
|
||||
} else if filename == "theme.json" {
|
||||
// 主题配置, 判断是否是正确的json
|
||||
theme, err := this.parseConfig(content)
|
||||
if err != nil {
|
||||
return false, fmt.Sprintf("%v", err)
|
||||
}
|
||||
// 正确, 更新theme信息
|
||||
ok = db.UpdateByQMap(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)},
|
||||
bson.M{
|
||||
"Name": theme.Name,
|
||||
"Version": theme.Version,
|
||||
"Author": theme.Author,
|
||||
"AuthorUrl": theme.AuthorUrl,
|
||||
"Info": theme.Info,
|
||||
})
|
||||
if ok {
|
||||
ok = PutFileStrContent(path, content)
|
||||
}
|
||||
return
|
||||
}
|
||||
ok = PutFileStrContent(path, content)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *ThemeService) DeleteTpl(userId, themeId, filename string) (ok bool) {
|
||||
path := this.GetThemeAbsolutePath(userId, themeId) + "/" + filename
|
||||
ok = DeleteFile(path)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断是否有语法错误
|
||||
func (this *ThemeService) mustTpl(filename, content string) (ok bool, msg string) {
|
||||
ok = true
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
Log(err)
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
}
|
||||
}()
|
||||
template.Must(template.New(filename).Funcs(revel.TemplateFuncs).Parse(content))
|
||||
return
|
||||
}
|
||||
|
||||
/////////
|
||||
|
||||
// 使用主题
|
||||
func (this *ThemeService) ActiveTheme(userId, themeId string) (ok bool) {
|
||||
if db.Has(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId)}) {
|
||||
// 之前的设为false
|
||||
db.UpdateByQField(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId), "IsActive": true}, "IsActive", false)
|
||||
// 现在的设为true
|
||||
db.UpdateByQField(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId)}, "IsActive", true)
|
||||
|
||||
// UserBlog ThemeId
|
||||
db.UpdateByQField(db.UserBlogs, bson.M{"_id": bson.ObjectIdHex(userId)}, "ThemeId", bson.ObjectIdHex(themeId))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 删除主题
|
||||
func (this *ThemeService) DeleteTheme(userId, themeId string) (ok bool) {
|
||||
return db.Delete(db.Themes,bson.M{"_id": bson.ObjectIdHex(themeId), "UserId": bson.ObjectIdHex(userId), "IsActive": false})
|
||||
}
|
||||
|
||||
// 公开主题, 只有管理员才有权限, 之前没公开的变成公开
|
||||
func (this *ThemeService) PublicTheme(userId, themeId string) (ok bool) {
|
||||
// 是否是管理员?
|
||||
userInfo := userService.GetUserInfo(userId)
|
||||
if userInfo.Username == configService.GetAdminUsername() {
|
||||
theme := this.GetThemeById(themeId)
|
||||
return db.UpdateByQField(db.Themes, bson.M{"UserId": bson.ObjectIdHex(userId), "_id": bson.ObjectIdHex(themeId)}, "IsDefault", !theme.IsDefault)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 导出主题
|
||||
func (this *ThemeService) ExportTheme(userId, themeId string) (ok bool, path string) {
|
||||
theme := this.GetThemeById(themeId)
|
||||
// 打包
|
||||
// 验证路径, 别把整个项目打包了
|
||||
Log(theme.Path)
|
||||
if theme.Path == "" ||
|
||||
(!strings.HasPrefix(theme.Path, "public/upload") &&
|
||||
!strings.HasPrefix(theme.Path, "public/blog/themes")) ||
|
||||
strings.Contains(theme.Path, "..") {
|
||||
return
|
||||
}
|
||||
|
||||
sourcePath := revel.BasePath + "/" + theme.Path
|
||||
targetPath := revel.BasePath + "/public/upload/" + userId + "/tmp"
|
||||
err := os.MkdirAll(targetPath, 0755)
|
||||
if err != nil {
|
||||
Log(err)
|
||||
return
|
||||
}
|
||||
targetName := targetPath + "/" + theme.Name + ".zip"
|
||||
Log(sourcePath)
|
||||
Log(targetName)
|
||||
ok = archive.Zip(sourcePath, targetName)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
return true, targetName
|
||||
}
|
||||
// 导入主题
|
||||
// path == /llllllll/..../public/upload/.../aa.zip, 绝对路径
|
||||
func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string) {
|
||||
themeIdO := bson.NewObjectId()
|
||||
themeId := themeIdO.Hex()
|
||||
targetPath := this.getUserThemePath(userId, themeId) // revel.BasePath + "/public/upload/" + userId + "/themes/" + themeId
|
||||
if ok, msg = archive.Unzip(path, targetPath); !ok {
|
||||
DeleteFile(targetPath)
|
||||
return
|
||||
}
|
||||
// 解压成功, 那么新建之
|
||||
// 保存到数据库中
|
||||
theme, _ := this.getThemeConfig(targetPath)
|
||||
if theme.Name == "" {
|
||||
ok = false
|
||||
DeleteFile(targetPath)
|
||||
msg = "解析错误"
|
||||
return
|
||||
}
|
||||
theme.ThemeId = themeIdO
|
||||
theme.Path = this.getUserThemePath2(userId, themeId)
|
||||
theme.CreatedTime = time.Now()
|
||||
theme.UpdatedTime = theme.CreatedTime
|
||||
theme.UserId = bson.ObjectIdHex(userId)
|
||||
|
||||
ok = db.Insert(db.Themes, theme)
|
||||
if !ok {
|
||||
DeleteFile(targetPath)
|
||||
}
|
||||
DeleteFile(path)
|
||||
return
|
||||
}
|
||||
|
||||
// 升级用
|
||||
// public/
|
||||
|
||||
func (this *ThemeService) UpgradeThemeBeta2() (ok bool) {
|
||||
adminUserId := configService.GetAdminUserId()
|
||||
this.upgradeThemeBeta2(adminUserId, defaultStyle, true)
|
||||
this.upgradeThemeBeta2(adminUserId, elegantStyle, false)
|
||||
this.upgradeThemeBeta2(adminUserId, fixedStyle, false)
|
||||
return true
|
||||
}
|
||||
func (this *ThemeService) upgradeThemeBeta2(userId, style string, isActive bool) (ok bool) {
|
||||
// 解压成功, 那么新建之
|
||||
// 保存到数据库中
|
||||
targetPath := this.GetDefaultThemePath(style)
|
||||
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
|
||||
theme.Style = style
|
||||
ok = db.Insert(db.Themes, theme)
|
||||
return ok
|
||||
}
|
||||
|
||||
// 安装主题
|
||||
// 得到该主题路径
|
||||
func (this *ThemeService) InstallTheme(userId, themeId string) (ok bool) {
|
||||
theme := this.GetThemeById(themeId)
|
||||
// 不是默认主题, 即不是admin用户的主题, 不能乱安装
|
||||
if !theme.IsDefault {
|
||||
return false
|
||||
}
|
||||
|
||||
// 用户之前是否有主题?
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
if userBlog.ThemeId == "" {
|
||||
this.NewThemeForFirst(userBlog)
|
||||
}
|
||||
|
||||
// 生成新主题
|
||||
newThemeId := bson.NewObjectId()
|
||||
themeId = newThemeId.Hex()
|
||||
themePath := this.getUserThemePath(userId, themeId)
|
||||
err := os.MkdirAll(themePath, 0755)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 复制默认主题
|
||||
sourceThemePath := revel.BasePath + "/" + theme.Path
|
||||
err = CopyDir(sourceThemePath, themePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 保存到数据库中
|
||||
theme, _ = this.getThemeConfig(themePath)
|
||||
theme.ThemeId = newThemeId
|
||||
theme.Path = this.getUserThemePath2(userId, themeId)
|
||||
theme.CreatedTime = time.Now()
|
||||
theme.UpdatedTime = theme.CreatedTime
|
||||
theme.UserId = bson.ObjectIdHex(userId)
|
||||
|
||||
ok = db.Insert(db.Themes, theme)
|
||||
|
||||
return ok
|
||||
}
|
||||
@@ -19,86 +19,9 @@ func (this *UpgradeService) UpgradeBlog() bool {
|
||||
|
||||
// PublicTime, RecommendTime = UpdatedTime
|
||||
for _, note := range notes {
|
||||
if note.IsBlog && note.PublicTime.Year() < 100 {
|
||||
db.UpdateByIdAndUserIdMap2(db.Notes, note.NoteId, note.UserId, bson.M{"PublicTime": note.UpdatedTime, "RecommendTime": note.UpdatedTime})
|
||||
Log(note.NoteId.Hex())
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 11-5自定义博客升级, 将aboutMe移至pages
|
||||
/*
|
||||
<li>Migrate "About me" to single(a single post)</li>
|
||||
<li>Add some default themes to administrator</li>
|
||||
<li>Generate "UrlTitle" for all notes. "UrlTitle" is a friendly url for post</li>
|
||||
<li>Generate "UrlTitle" for all notebooks</li>
|
||||
<li>Generate "UrlTitle" for all singles</li>
|
||||
*/
|
||||
func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg string) {
|
||||
if configService.GetGlobalStringConfig("UpgradeBetaToBeta2") != "" {
|
||||
return false, "已升级"
|
||||
}
|
||||
|
||||
// 1. aboutMe -> page
|
||||
userBlogs := []info.UserBlog{}
|
||||
db.ListByQ(db.UserBlogs, bson.M{}, &userBlogs)
|
||||
|
||||
for _, userBlog := range userBlogs {
|
||||
blogService.AddOrUpdateSingle(userBlog.UserId.Hex(), "", "About Me", userBlog.AboutMe)
|
||||
}
|
||||
|
||||
// 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")
|
||||
|
||||
return
|
||||
}
|
||||
+7
-103
@@ -26,7 +26,7 @@ func (this *UserService) AddUser(user info.User) bool {
|
||||
go func() {
|
||||
emailService.RegisterSendActiveEmail(user, user.Email)
|
||||
// 发送给我 life@leanote.com
|
||||
emailService.SendEmail("life@leanote.com", "新增用户", "{header}用户名" + user.Email + "{footer}");
|
||||
// emailService.SendEmail("life@leanote.com", "新增用户", "{header}用户名" + user.Email + "{footer}");
|
||||
}();
|
||||
}
|
||||
|
||||
@@ -41,13 +41,6 @@ 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) == "" {
|
||||
@@ -82,7 +75,7 @@ func (this *UserService) setUserLogo(user *info.User) {
|
||||
}
|
||||
if user.Logo != "" && !strings.HasPrefix(user.Logo, "http") {
|
||||
user.Logo = strings.Trim(user.Logo, "/")
|
||||
user.Logo = configService.GetSiteUrl() + "/" + user.Logo
|
||||
user.Logo = siteUrl + "/" + user.Logo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,58 +133,6 @@ func (this *UserService) MapUserInfoAndBlogInfosByUserIds(userIds []bson.ObjectI
|
||||
return this.MapUserInfoByUserIds(userIds)
|
||||
}
|
||||
|
||||
// 返回info.UserAndBlog
|
||||
func (this *UserService) MapUserAndBlogByUserIds(userIds []bson.ObjectId) map[string]info.UserAndBlog {
|
||||
users := []info.User{}
|
||||
db.ListByQ(db.Users, bson.M{"_id": bson.M{"$in": userIds}}, &users)
|
||||
|
||||
userBlogs := []info.UserBlog{}
|
||||
db.ListByQ(db.UserBlogs, bson.M{"_id": bson.M{"$in": userIds}}, &userBlogs)
|
||||
|
||||
userBlogMap := make(map[bson.ObjectId]info.UserBlog, len(userBlogs))
|
||||
for _, user := range userBlogs {
|
||||
userBlogMap[user.UserId] = user
|
||||
}
|
||||
|
||||
userAndBlogMap := make(map[string]info.UserAndBlog, len(users))
|
||||
|
||||
for _, user := range users {
|
||||
this.setUserLogo(&user)
|
||||
|
||||
userBlog, ok := userBlogMap[user.UserId]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
userAndBlogMap[user.UserId.Hex()] = info.UserAndBlog{
|
||||
UserId: user.UserId,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
Logo: user.Logo,
|
||||
BlogTitle: userBlog.Title,
|
||||
BlogLogo: userBlog.Logo,
|
||||
BlogUrl: blogService.GetUserBlogUrl(&userBlog, user.Username),
|
||||
}
|
||||
}
|
||||
return userAndBlogMap
|
||||
}
|
||||
|
||||
// 得到userAndBlog公开信息
|
||||
func (this *UserService) GetUserAndBlog(userId string) info.UserAndBlog {
|
||||
user := this.GetUserInfo(userId)
|
||||
userBlog := blogService.GetUserBlog(userId)
|
||||
return info.UserAndBlog{
|
||||
UserId: user.UserId,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
Logo: user.Logo,
|
||||
BlogTitle: userBlog.Title,
|
||||
BlogLogo: userBlog.Logo,
|
||||
BlogUrl: blogService.GetUserBlogUrl(&userBlog, user.Username),
|
||||
BlogUrls: blogService.GetBlogUrls(&userBlog, &user),
|
||||
}
|
||||
}
|
||||
|
||||
// 通过ids得到users, 按id的顺序组织users
|
||||
func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.User {
|
||||
users := []info.User{}
|
||||
@@ -202,11 +143,9 @@ func (this *UserService) GetUserInfosOrderBySeq(userIds []bson.ObjectId) []info.
|
||||
usersMap[user.UserId] = user
|
||||
}
|
||||
|
||||
hasAppend := map[bson.ObjectId]bool{} // 为了防止userIds有重复的
|
||||
users2 := []info.User{};
|
||||
for _, userId := range userIds {
|
||||
if user, ok := usersMap[userId]; ok && !hasAppend[userId] {
|
||||
hasAppend[userId] = true
|
||||
if user, ok := usersMap[userId]; ok {
|
||||
users2 = append(users2, user)
|
||||
}
|
||||
}
|
||||
@@ -230,7 +169,7 @@ func (this *UserService) LoginGetUserInfo(emailOrUsername, md5Pwd string) info.U
|
||||
// 更新username
|
||||
func (this *UserService) UpdateUsername(userId, username string) (bool, string) {
|
||||
if userId == "" || username == "" || username == "admin" { // admin用户是内置的, 不能设置
|
||||
return false, "usernameIsExisted"
|
||||
return false, "用户已存在"
|
||||
}
|
||||
usernameRaw := username // 原先的, 可能是同一个, 但有大小写
|
||||
username = strings.ToLower(username)
|
||||
@@ -238,7 +177,7 @@ func (this *UserService) UpdateUsername(userId, username string) (bool, string)
|
||||
// 先判断是否存在
|
||||
userIdO := bson.ObjectIdHex(userId)
|
||||
if db.Has(db.Users, bson.M{"Username": username, "_id": bson.M{"$ne": userIdO}}) {
|
||||
return false, "usernameIsExisted"
|
||||
return false, "用户已存在"
|
||||
}
|
||||
|
||||
ok := db.UpdateByQMap(db.Users, bson.M{"_id": userIdO}, bson.M{"Username": username, "UsernameRaw": usernameRaw})
|
||||
@@ -256,42 +195,18 @@ func (this *UserService) UpdateAvatar(userId, avatarPath string) (bool) {
|
||||
func (this *UserService) UpdatePwd(userId, oldPwd, pwd string) (bool, string) {
|
||||
userInfo := this.GetUserInfo(userId)
|
||||
if userInfo.Pwd != Md5(oldPwd) {
|
||||
return false, "oldPasswordError"
|
||||
return false, "旧密码错误"
|
||||
}
|
||||
ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", Md5(pwd))
|
||||
return ok, ""
|
||||
}
|
||||
|
||||
// 管理员重置密码
|
||||
func (this *UserService) ResetPwd(adminUserId, userId, pwd string) (ok bool, msg string) {
|
||||
if configService.GetAdminUserId() != adminUserId {
|
||||
return
|
||||
}
|
||||
ok = db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Pwd", Md5(pwd))
|
||||
return
|
||||
}
|
||||
|
||||
// 修改主题
|
||||
func (this *UserService) UpdateTheme(userId, theme string) (bool) {
|
||||
ok := db.UpdateByQField(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, "Theme", theme)
|
||||
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
|
||||
|
||||
@@ -346,13 +261,6 @@ func (this *UserService) UpdateEmail(token string) (ok bool, msg, email string)
|
||||
//---------
|
||||
// 第三方添加账号
|
||||
func (this *UserService) ThirdAddUser(userId, email, pwd string) (ok bool, msg string) {
|
||||
// 判断该用户是否已有了帐户
|
||||
userInfo := this.GetUserInfo(userId)
|
||||
if userInfo.Email != "" {
|
||||
msg = "你已有帐户"
|
||||
return
|
||||
}
|
||||
|
||||
// 判断email是否存在
|
||||
if this.IsExistsUser(email) {
|
||||
msg = "该用户已存在"
|
||||
@@ -383,11 +291,7 @@ func (this *UserService) ListUsers(pageNumber, pageSize int, sortField string, i
|
||||
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
|
||||
query := bson.M{}
|
||||
if email != "" {
|
||||
orQ := []bson.M{
|
||||
bson.M{"Email": bson.M{"$regex": bson.RegEx{".*?" + email + ".*", "i"}}},
|
||||
bson.M{"Username": bson.M{"$regex": bson.RegEx{".*?" + email + ".*", "i"}}},
|
||||
}
|
||||
query["$or"] = orQ
|
||||
query["Email"] = bson.M{"$regex": bson.RegEx{".*?" + email + ".*", "i"}}
|
||||
}
|
||||
q := db.Users.Find(query);
|
||||
// 总记录数
|
||||
|
||||
+5
-79
@@ -1,13 +1,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"gopkg.in/mgo.v2"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// init service, for share service bettween services
|
||||
@@ -20,7 +14,6 @@ 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
|
||||
@@ -35,7 +28,8 @@ var emailService, EmailS *EmailService
|
||||
var AuthS *AuthService
|
||||
var UpgradeS *UpgradeService
|
||||
var SessionS, sessionService *SessionService
|
||||
var ThemeS, themeService *ThemeService
|
||||
|
||||
var siteUrl string
|
||||
|
||||
// onAppStart调用
|
||||
func InitService() {
|
||||
@@ -45,7 +39,6 @@ func InitService() {
|
||||
TrashS = &TrashService{}
|
||||
ShareS = &ShareService{}
|
||||
UserS = &UserService{}
|
||||
GroupS = &GroupService{}
|
||||
TagS = &TagService{}
|
||||
BlogS = &BlogService{}
|
||||
TokenS = &TokenService{}
|
||||
@@ -60,7 +53,6 @@ func InitService() {
|
||||
EmailS = NewEmailService()
|
||||
UpgradeS = &UpgradeService{}
|
||||
SessionS = &SessionService{}
|
||||
ThemeS = &ThemeService{}
|
||||
|
||||
notebookService = NotebookS
|
||||
noteService = NoteS
|
||||
@@ -68,7 +60,6 @@ func InitService() {
|
||||
trashService = TrashS
|
||||
shareService = ShareS
|
||||
userService = UserS
|
||||
groupService = GroupS
|
||||
tagService = TagS
|
||||
blogService = BlogS
|
||||
tokenService = TokenS
|
||||
@@ -79,72 +70,7 @@ func InitService() {
|
||||
configService = ConfigS
|
||||
emailService = EmailS
|
||||
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)
|
||||
//
|
||||
siteUrl, _ = revel.Config.String("site.url")
|
||||
}
|
||||
@@ -97,6 +97,9 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-4 text-center">
|
||||
<small class="text-muted inline m-t-sm m-b-sm">
|
||||
showing 20-30 of 50 items
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-sm-4 text-right text-center-xs">
|
||||
{{set . "url" (urlConcat "/adminBlog/index" "sorter" .sorter "keywords" .keywords)}}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -42,7 +42,7 @@ $(function() {
|
||||
var t = this;
|
||||
if($("#add_user_form").valid()) {
|
||||
$(t).button('loading');
|
||||
ajaxPost("/adminUser/register", getFormJsonData("add_user_form"), function(ret){
|
||||
ajaxPost("/auth/doRegister", getFormJsonData("add_user_form"), function(ret){
|
||||
$(t).button('reset')
|
||||
if(!ret.Ok) {
|
||||
art.alert(ret.Msg);
|
||||
@@ -4,8 +4,16 @@
|
||||
<section class="panel panel-default">
|
||||
<div class="row wrapper">
|
||||
<div class="col-sm-5 m-b-xs">
|
||||
<button class="btn btn-sm btn-default bulk-email">
|
||||
<select class="input-sm form-control input-s-sm inline v-middle">
|
||||
<option value="">
|
||||
Bulk action
|
||||
</option>
|
||||
<option value="1">
|
||||
Send Email
|
||||
</option>
|
||||
</select>
|
||||
<button class="btn btn-sm btn-default bulk-btn">
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-4 m-b-xs">
|
||||
@@ -13,7 +21,7 @@
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<div class="input-group search-group">
|
||||
<input type="text" class="input-sm form-control" placeholder="Username or Email" id="keywords" value="{{.keywords}}" />
|
||||
<input type="text" class="input-sm form-control" placeholder="Email" id="keywords" value="{{.keywords}}" />
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-sm btn-default" type="button" data-url="/adminUser/index">Search</button>
|
||||
</span>
|
||||
@@ -91,8 +99,7 @@
|
||||
{{.CreatedTime|datetime}}
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="btn btn-sm btn-default reset-pwd" data-id="{{.UserId.Hex}}">Reset Password</a>
|
||||
<a href="#" class="btn btn-sm btn-default send-email" data-email="{{.Email}}">Send Email</a>
|
||||
<a href="#" class="btn btn-default send-email" data-email="{{.Email}}">Send Email</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
@@ -102,8 +109,16 @@
|
||||
<footer class="panel-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-4 hidden-xs">
|
||||
<button class="btn btn-sm btn-default bulk-email">
|
||||
<select class="input-sm form-control input-s-sm inline v-middle">
|
||||
<option value="">
|
||||
Bulk action
|
||||
</option>
|
||||
<option value="1">
|
||||
Send Email
|
||||
</option>
|
||||
</select>
|
||||
<button class="btn btn-sm btn-default bulk-btn">
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -122,7 +137,9 @@ $(function() {
|
||||
$(".send-email").click(function() {
|
||||
openSendEmailDialog($(this).data("email"));
|
||||
});
|
||||
$(".bulk-email").click(function() {
|
||||
$(".bulk-btn").click(function() {
|
||||
// email
|
||||
if($(this).prev().val() == "1") {
|
||||
var emails = [];
|
||||
$(".ck:checked").each(function() {
|
||||
emails.push($(this).data("email"));
|
||||
@@ -132,12 +149,7 @@ $(function() {
|
||||
return;
|
||||
}
|
||||
openSendEmailDialog(emails.join(","));
|
||||
});
|
||||
|
||||
// reset password
|
||||
$(".reset-pwd").click(function() {
|
||||
var id = $(this).data("id");
|
||||
openDialog({width: 500, url: "/adminUser/resetPwd?userId=" + id, title: "Reset Password"});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -10,7 +10,7 @@
|
||||
<title>{{.title}}</title>
|
||||
|
||||
<link href="/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="/css/font-awesome-4.2.0/css/font-awesome.css" rel="stylesheet">
|
||||
<link href="/css/font-awesome-4.0.3/css/font-awesome.css" rel="stylesheet">
|
||||
<link href="/public/admin/css/admin.css" rel="stylesheet">
|
||||
<style>
|
||||
</style>
|
||||
File renamed without changes.
@@ -128,18 +128,10 @@
|
||||
</i>
|
||||
</span>
|
||||
<span>
|
||||
Configuration
|
||||
Setting
|
||||
</span>
|
||||
</a>
|
||||
<ul class="nav lt">
|
||||
<li>
|
||||
<a href="/admin/t?t=setting/home_page">
|
||||
<span>
|
||||
Home Page
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/admin/t?t=setting/demo">
|
||||
<span>
|
||||
@@ -149,7 +141,7 @@
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/admin/t?t=setting/open_register">
|
||||
<a href="/admin/t?t=setting/openRegister">
|
||||
<span>
|
||||
Open Register
|
||||
</span>
|
||||
@@ -163,14 +155,6 @@
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/admin/t?t=setting/upload">
|
||||
<span>
|
||||
Upload File Size Limit
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -208,32 +192,5 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<i class="fa fa-space-shuttle icon">
|
||||
<b class="bg-danger">
|
||||
</b>
|
||||
</i>
|
||||
<span class="pull-right">
|
||||
<i class="fa fa-angle-down text">
|
||||
</i>
|
||||
<i class="fa fa-angle-up text-active">
|
||||
</i>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Upgrade
|
||||
</span>
|
||||
</a>
|
||||
<ul class="nav lt">
|
||||
<li>
|
||||
<a href="/admin/t?t=upgrade/beta2">
|
||||
<span>
|
||||
v1.0-beta to v1.0-beta2
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -7,7 +7,7 @@
|
||||
</title>
|
||||
<meta name="description" content="leanote admin"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
|
||||
<link href="/css/font-awesome-4.2.0/css/font-awesome.css" rel="stylesheet">
|
||||
<link href="/css/font-awesome-4.0.3/css/font-awesome.css" rel="stylesheet">
|
||||
<link href="/public/admin/css/bootstrap.3.2.0.min.css" rel="stylesheet">
|
||||
<link href="/public/admin/css/admin.css" rel="stylesheet">
|
||||
<!--[if lt IE 9]>
|
||||
File renamed without changes.
@@ -1,4 +1,4 @@
|
||||
{{template "blog/header.html" .}}
|
||||
{{template "Blog/header.html" .}}
|
||||
|
||||
<div id="postsContainer">
|
||||
<div id="posts">
|
||||
@@ -16,4 +16,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "blog/footer.html" .}}
|
||||
{{template "Blog/footer.html" .}}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,4 @@
|
||||
{{template "blog/header.html" .}}
|
||||
{{template "Blog/header.html" .}}
|
||||
|
||||
<div id="postsContainer">
|
||||
<div class="container">
|
||||
@@ -44,7 +44,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "blog/footer.html" .}}
|
||||
{{template "blog/highlight.html"}}
|
||||
{{template "Blog/footer.html" .}}
|
||||
{{template "Blog/highlight.html"}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,4 @@
|
||||
{{template "blog/header.html" .}}
|
||||
{{template "Blog/header.html" .}}
|
||||
|
||||
<div id="postsContainer">
|
||||
<div class="container">
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "blog/footer.html" .}}
|
||||
{{template "blog/highlight.html"}}
|
||||
{{template "Blog/footer.html" .}}
|
||||
{{template "Blog/highlight.html"}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,4 @@
|
||||
{{template "blog/header.html" .}}
|
||||
{{template "Blog/header.html" .}}
|
||||
|
||||
<!-- set页面不是自定义域名和二级域名页 -->
|
||||
<link rel="stylesheet" href="{{.siteUrl}}/tinymce/skins/custom/skin.min.css" type="text/css">
|
||||
@@ -198,7 +198,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
{{template "blog/footer.html" .}}
|
||||
{{template "Blog/footer.html" .}}
|
||||
|
||||
<script src="{{.siteUrl}}/js/common-min.js"></script>
|
||||
<script type="text/javascript" src="{{.siteUrl}}/tinymce/tinymce.min.js"></script>
|
||||
@@ -1,4 +1,4 @@
|
||||
{{template "blog/header.html" .}}
|
||||
{{template "Blog/header.html" .}}
|
||||
|
||||
<div id="postsContainer">
|
||||
<div id="posts">
|
||||
@@ -56,8 +56,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "blog/footer.html" .}}
|
||||
{{template "blog/highlight.html"}}
|
||||
{{template "Blog/footer.html" .}}
|
||||
{{template "Blog/highlight.html"}}
|
||||
<div id="blogNav">
|
||||
<div id="blogNavNav">
|
||||
<i class="fa fa-align-justify" title="文档导航"></i>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 474 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user