API, Tag
This commit is contained in:
app
controllers
db
info
init.golea
service
AttachService.goAuthService.goBlogService.goConfigService.goFileService.goNoteImageService.goNoteService.goNotebookService.goSessionService.goShareService.goTagService.goTrashService.goUpgradeService.goUserService.go
views
public
blog
css
js
themes
README.html
backup
default
archive.htmlcate.htmlcomment.htmlfooter.htmlheader.htmlhighlight.html
images
index.htmlnoise.pngpage.htmlpaging.htmlsearch.htmlsingle.htmlstyle.csstag_posts.htmltags.htmltheme.jsonview.htmlview.jselegant
archive.htmlcate.htmlcomment.htmlfooter.htmlheader.htmlhighlight.html
images
index.htmlpage.htmlpaging.htmlsearch.htmlsingle.htmlstyle.csstag_posts.htmltags.htmltheme.jsonview.htmlview.jsnav_fixed
default
archive.htmlcate.htmlfooter.htmlheader.htmlindex.htmlpaging.htmlpost.htmlpost_abstract.htmlsearch.htmlshare_comment.htmlsingle.htmlstyle.csstag_posts.htmltags.htmltheme.json
elegant
archive.htmlcate.htmlfooter.htmlheader.htmlindex.htmlpaging.htmlpost.htmlpost_abstract.htmlsearch.htmlshare_comment.htmlsingle.htmltag_posts.htmltags.htmltheme.json
nav_fixed
css
blog
bootstrap.csscss
font-awesome-4.0.3
css
fonts
FontAwesome.otffontawesome-webfont.eotfontawesome-webfont.svgfontawesome-webfont.ttffontawesome-webfont.woff
less
bordered-pulled.lesscore.lessfixed-width.lessfont-awesome.lessicons.lesslarger.lesslist.lessmixins.lesspath.lessrotated-flipped.lessspinning.lessstacked.lessvariables.less
scss
theme
dist
themes
js
libs
ace
ace-modify.txtace.js
ck
ext-beautify-min.jsext-chromevox-min.jsext-elastic_tabstops_lite-min.jsext-emmet-min.jsext-error_marker-min.jsext-keybinding_menu-min.jsext-language_tools-min.jsext-linking-min.jsext-modelist-min.jsext-old_ie-min.jsext-settings_menu-min.jsext-spellcheck-min.jsext-split-min.jsext-static_highlight-min.jsext-statusbar-min.jsext-textarea-min.jsext-themelist-min.jsext-whitespace-min.jskeybinding-emacs-min.jsmode-abap-min.jsmode-actionscript-min.jsmode-ada-min.jsmode-apache_conf-min.jsmode-asciidoc-min.jsmode-assembly_x86-min.jsmode-autohotkey-min.jsmode-batchfile-min.jsmode-c9search-min.jsmode-cirru-min.jsmode-clojure-min.jsmode-cobol-min.jsmode-coffee-min.jsmode-coldfusion-min.jsmode-csharp-min.jsmode-css-min.jsmode-d-min.jsmode-dart-min.jsmode-diff-min.jsmode-django-min.jsmode-dot-min.jsmode-eiffel-min.jsmode-ejs-min.jsmode-erlang-min.jsmode-ftl-min.jsmode-gcode-min.jsmode-gherkin-min.jsmode-gitignore-min.jsmode-glsl-min.jsmode-golang-min.jsmode-groovy-min.jsmode-haml-min.jsmode-handlebars-min.js
ext-beautify.jsext-chromevox.jsext-elastic_tabstops_lite.jsext-emmet.jsext-error_marker.jsext-keybinding_menu.jsext-language_tools.jsext-linking.jsext-modelist.jsext-old_ie.jsext-searchbox.jsext-settings_menu.jsext-spellcheck.jsext-split.jsext-static_highlight.jsext-statusbar.jsext-textarea.jsext-themelist.jsext-whitespace.jskeybinding-emacs.jskeybinding-vim.jsmode-abap.jsmode-abc.jsmode-actionscript.jsmode-ada.jsmode-apache_conf.jsmode-applescript.jsmode-asciidoc.jsmode-assembly_x86.jsmode-autohotkey.jsmode-batchfile.jsmode-c9search.jsmode-c_cpp.jsmode-cirru.jsmode-clojure.jsmode-cobol.jsmode-coffee.jsmode-coldfusion.jsmode-csharp.jsmode-css.jsmode-curly.jsmode-d.jsmode-dart.jsmode-diff.jsmode-django.jsmode-dockerfile.jsmode-dot.jsmode-eiffel.jsmode-ejs.jsmode-elixir.jsmode-elm.jsmode-erlang.jsmode-forth.jsmode-ftl.jsmode-gcode.jsmode-gherkin.jsmode-gitignore.jsmode-glsl.jsmode-golang.jsmode-groovy.jsmode-haml.jsmode-handlebars.jsmode-haskell.jsmode-haxe.jsmode-html.jsmode-html_ruby.jsmode-ini.jsmode-io.jsmode-jack.jsmode-jade.jsmode-java.jsmode-javascript.jsmode-json.jsmode-jsoniq.jsmode-jsp.jsmode-jsx.jsmode-julia.jsmode-latex.jsmode-lean.jsmode-less.jsmode-liquid.jsmode-lisp.jsmode-livescript.jsmode-logiql.jsmode-lsl.jsmode-lua.jsmode-luapage.jsmode-lucene.jsmode-makefile.jsmode-markdown.jsmode-mask.jsmode-matlab.jsmode-mel.jsmode-mushcode.jsmode-mysql.jsmode-nix.jsmode-objectivec.jsmode-ocaml.jsmode-pascal.jsmode-perl.jsmode-pgsql.jsmode-php.jsmode-plain_text.jsmode-powershell.jsmode-praat.jsmode-prolog.jsmode-properties.jsmode-protobuf.jsmode-python.jsmode-r.jsmode-rdoc.jsmode-rhtml.jsmode-ruby.jsmode-rust.jsmode-sass.jsmode-scad.jsmode-scala.jsmode-scheme.jsmode-scss.jsmode-sh.jsmode-sjs.jsmode-smarty.jsmode-snippets.jsmode-soy_template.jsmode-space.jsmode-sql.jsmode-stylus.jsmode-svg.jsmode-tcl.jsmode-tex.jsmode-text.jsmode-textile.jsmode-toml.jsmode-twig.jsmode-typescript.jsmode-vala.jsmode-vbscript.jsmode-velocity.jsmode-verilog.jsmode-vhdl.jsmode-xml.jsmode-xquery.jsmode-yaml.jssnippets
abap.jsabc.jsactionscript.jsada.jsapache_conf.jsapplescript.jsasciidoc.jsassembly_x86.jsautohotkey.jsbatchfile.jsc9search.jsc_cpp.jscirru.jsclojure.jscobol.jscoffee.jscoldfusion.jscsharp.jscss.jscurly.jsd.jsdart.jsdiff.jsdjango.jsdockerfile.jsdot.jseiffel.jsejs.jselixir.jselm.jserlang.jsforth.jsftl.jsgcode.jsgherkin.jsgitignore.jsglsl.jsgolang.jsgroovy.jshaml.jshandlebars.jshaskell.jshaxe.jshtml.jshtml_ruby.jsini.jsio.jsjack.jsjade.jsjava.jsjavascript.jsjson.jsjsoniq.jsjsp.jsjsx.jsjulia.jslatex.jslean.jsless.jsliquid.jslisp.jslivescript.jslogiql.jslsl.jslua.jsluapage.jslucene.jsmakefile.jsmarkdown.jsmask.jsmatlab.jsmel.jsmushcode.jsmysql.jsnix.jsobjectivec.jsocaml.jspascal.jsperl.jspgsql.jsphp.jsplain_text.jspowershell.jspraat.jsprolog.jsproperties.jsprotobuf.jspython.jsr.jsrdoc.jsrhtml.jsruby.jsrust.jssass.jsscad.jsscala.jsscheme.jsscss.jssh.jssjs.jssmarty.jssnippets.jssoy_template.jsspace.jssql.jsstylus.jssvg.jstcl.jstex.jstext.jstextile.jstoml.jstwig.jstypescript.jsvala.jsvbscript.jsvelocity.jsverilog.jsvhdl.jsxml.jsxquery.jsyaml.js
theme-ambiance.jstheme-chaos.jstheme-chrome.jstheme-clouds.jstheme-clouds_midnight.jstheme-cobalt.jstheme-crimson_editor.jstheme-dawn.jstheme-dreamweaver.jstheme-eclipse.jstheme-github.jstheme-idle_fingers.jstheme-katzenmilch.jstheme-kr_theme.jstheme-kuroir.jstheme-merbivore.jstheme-merbivore_soft.jstheme-mono_industrial.jstheme-monokai.jstheme-pastel_on_dark.jstheme-solarized_dark.jstheme-solarized_light.jstheme-terminal.jstheme-textmate.jstheme-tomorrow.jstheme-tomorrow_night.jstheme-tomorrow_night_blue.jstheme-tomorrow_night_bright.jstheme-tomorrow_night_eighties.jstheme-twilight.jstheme-vibrant_ink.jstheme-xcode.jsworker-coffee.jsworker-css.jsworker-html.jsworker-javascript.jsworker-json.jsworker-lua.jsworker-php.jsworker-xml.jsworker-xquery.jstinymce
plugins
leaui_image
public
paste
spellchecker
table
@ -1,30 +1,47 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AttachService struct {
|
||||
}
|
||||
|
||||
// add attach
|
||||
func (this *AttachService) AddAttach(attach info.Attach) (ok bool, msg string) {
|
||||
// api调用时, 添加attach之前是没有note的
|
||||
// fromApi表示是api添加的, updateNote传过来的, 此时不要incNote's usn, 因为updateNote会inc的
|
||||
func (this *AttachService) AddAttach(attach info.Attach, fromApi bool) (ok bool, msg string) {
|
||||
attach.CreatedTime = time.Now()
|
||||
ok = db.Insert(db.Attachs, attach)
|
||||
|
||||
note := noteService.GetNoteById(attach.NoteId.Hex())
|
||||
|
||||
// api调用时, 添加attach之前是没有note的
|
||||
var userId string
|
||||
if note.NoteId != "" {
|
||||
userId = note.UserId.Hex()
|
||||
} else {
|
||||
userId = attach.UploadUserId.Hex()
|
||||
}
|
||||
|
||||
if ok {
|
||||
// 更新笔记的attachs num
|
||||
this.updateNoteAttachNum(attach.NoteId, 1)
|
||||
}
|
||||
|
||||
return
|
||||
if !fromApi {
|
||||
// 增长note's usn
|
||||
noteService.IncrNoteUsn(attach.NoteId.Hex(), userId)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 更新笔记的附件个数
|
||||
@ -50,17 +67,32 @@ func (this *AttachService) ListAttachs(noteId, userId string) []info.Attach {
|
||||
if !shareService.HasUpdateNotePerm(noteId, userId) {
|
||||
return attachs
|
||||
}
|
||||
|
||||
|
||||
db.ListByQ(db.Attachs, bson.M{"NoteId": bson.ObjectIdHex(noteId)}, &attachs)
|
||||
|
||||
|
||||
return attachs
|
||||
}
|
||||
|
||||
// api调用, 通过noteIds得到note's attachs, 通过noteId归类返回
|
||||
func (this *AttachService) getAttachsByNoteIds(noteIds []bson.ObjectId) map[string][]info.Attach {
|
||||
attachs := []info.Attach{}
|
||||
db.ListByQ(db.Attachs, bson.M{"NoteId": bson.M{"$in": noteIds}}, &attachs)
|
||||
noteAttchs := make(map[string][]info.Attach)
|
||||
for _, attach := range attachs {
|
||||
noteId := attach.NoteId.Hex()
|
||||
if itAttachs, ok := noteAttchs[noteId]; ok {
|
||||
noteAttchs[noteId] = append(itAttachs, attach)
|
||||
} else {
|
||||
noteAttchs[noteId] = []info.Attach{attach}
|
||||
}
|
||||
}
|
||||
return noteAttchs
|
||||
}
|
||||
|
||||
func (this *AttachService) UpdateImageTitle(userId, fileId, title string) bool {
|
||||
return db.UpdateByIdAndUserIdField(db.Files, fileId, userId, "Title", title)
|
||||
}
|
||||
|
||||
|
||||
// Delete note to delete attas firstly
|
||||
func (this *AttachService) DeleteAllAttachs(noteId, userId string) bool {
|
||||
note := noteService.GetNoteById(noteId)
|
||||
@ -73,7 +105,7 @@ func (this *AttachService) DeleteAllAttachs(noteId, userId string) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -93,7 +125,11 @@ func (this *AttachService) DeleteAttach(attachId, userId string) (bool, string)
|
||||
attach.Path = strings.TrimLeft(attach.Path, "/")
|
||||
err := os.Remove(revel.BasePath + "/" + attach.Path)
|
||||
if err == nil {
|
||||
return true, "delete file error"
|
||||
// userService.UpdateAttachSize(note.UserId.Hex(), -attach.Size)
|
||||
// 修改note Usn
|
||||
noteService.IncrNoteUsn(attach.NoteId.Hex(), userId)
|
||||
|
||||
return true, "delete file success"
|
||||
}
|
||||
return false, "delete file error"
|
||||
}
|
||||
@ -107,37 +143,37 @@ func (this *AttachService) DeleteAttach(attachId, userId string) (bool, string)
|
||||
// userId是否具有attach的访问权限
|
||||
func (this *AttachService) GetAttach(attachId, userId string) (attach info.Attach) {
|
||||
if attachId == "" {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
attach = info.Attach{}
|
||||
db.Get(db.Attachs, attachId, &attach)
|
||||
path := attach.Path
|
||||
if path == "" {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
note := noteService.GetNoteById(attach.NoteId.Hex())
|
||||
|
||||
|
||||
// 判断权限
|
||||
|
||||
|
||||
// 笔记是否是公开的
|
||||
if note.IsBlog {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 笔记是否是我的
|
||||
if note.UserId.Hex() == userId {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 我是否有权限查看或协作
|
||||
if shareService.HasReadNotePerm(attach.NoteId.Hex(), userId) {
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
attach = info.Attach{}
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
// 复制笔记时需要复制附件
|
||||
@ -145,31 +181,58 @@ func (this *AttachService) GetAttach(attachId, userId string) (attach info.Attac
|
||||
func (this *AttachService) CopyAttachs(noteId, toNoteId, toUserId string) bool {
|
||||
attachs := []info.Attach{}
|
||||
db.ListByQ(db.Attachs, bson.M{"NoteId": bson.ObjectIdHex(noteId)}, &attachs)
|
||||
|
||||
|
||||
// 复制之
|
||||
toNoteIdO := bson.ObjectIdHex(toNoteId)
|
||||
for _, attach := range attachs {
|
||||
attach.AttachId = ""
|
||||
attach.NoteId = toNoteIdO
|
||||
|
||||
|
||||
// 文件复制一份
|
||||
_, ext := SplitFilename(attach.Name)
|
||||
newFilename := NewGuid() + ext
|
||||
dir := "files/" + toUserId + "/attachs"
|
||||
filePath := dir + "/" + newFilename
|
||||
err := os.MkdirAll(revel.BasePath + "/" + dir, 0755)
|
||||
err := os.MkdirAll(revel.BasePath+"/"+dir, 0755)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_, err = CopyFile(revel.BasePath + "/" + attach.Path, revel.BasePath + "/" + filePath)
|
||||
_, err = CopyFile(revel.BasePath+"/"+attach.Path, revel.BasePath+"/"+filePath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
attach.Name = newFilename
|
||||
attach.Path = filePath
|
||||
|
||||
this.AddAttach(attach)
|
||||
|
||||
this.AddAttach(attach, false)
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 只留下files的数据, 其它的都删除
|
||||
func (this *AttachService) UpdateOrDeleteAttachApi(noteId, userId string, files []info.NoteFile) bool {
|
||||
// 现在数据库内的
|
||||
attachs := this.ListAttachs(noteId, userId)
|
||||
|
||||
nowAttachs := map[string]bool{}
|
||||
if files != nil {
|
||||
for _, file := range files {
|
||||
if file.IsAttach && file.FileId != "" {
|
||||
nowAttachs[file.FileId] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, attach := range attachs {
|
||||
fileId := attach.AttachId.Hex()
|
||||
if !nowAttachs[fileId] {
|
||||
// 需要删除的
|
||||
// TODO 权限验证去掉
|
||||
this.DeleteAttach(fileId, userId)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ func (this *AuthService) Register(email, pwd, fromUserId string) (bool, string)
|
||||
func (this *AuthService) register(user info.User) (bool, string) {
|
||||
if userService.AddUser(user) {
|
||||
// 添加笔记本, 生活, 学习, 工作
|
||||
userId := user.UserId.Hex();
|
||||
notebook := info.Notebook{
|
||||
Seq: -1,
|
||||
UserId: user.UserId}
|
||||
@ -62,8 +63,6 @@ func (this *AuthService) register(user info.User) (bool, string) {
|
||||
notebookService.AddNotebook(notebook);
|
||||
}
|
||||
|
||||
email := user.Email
|
||||
|
||||
// 添加leanote -> 该用户的共享
|
||||
registerSharedUserId := configService.GetGlobalStringConfig("registerSharedUserId")
|
||||
if(registerSharedUserId != "") {
|
||||
@ -74,20 +73,23 @@ func (this *AuthService) register(user info.User) (bool, string) {
|
||||
// 添加共享笔记本
|
||||
for _, notebook := range registerSharedNotebooks {
|
||||
perm, _ := strconv.Atoi(notebook["perm"])
|
||||
shareService.AddShareNotebook(notebook["notebookId"], perm, registerSharedUserId, email);
|
||||
shareService.AddShareNotebookToUserId(notebook["notebookId"], perm, registerSharedUserId, userId);
|
||||
}
|
||||
|
||||
// 添加共享笔记
|
||||
for _, note := range registerSharedNotes {
|
||||
perm, _ := strconv.Atoi(note["perm"])
|
||||
shareService.AddShareNote(note["noteId"], perm, registerSharedUserId, email);
|
||||
shareService.AddShareNoteToUserId(note["noteId"], perm, registerSharedUserId, userId);
|
||||
}
|
||||
|
||||
// 复制笔记
|
||||
for _, noteId := range registerCopyNoteIds {
|
||||
note := noteService.CopySharedNote(noteId, title2Id["life"].Hex(), registerSharedUserId, user.UserId.Hex());
|
||||
noteUpdate := bson.M{"IsBlog": true}
|
||||
noteService.UpdateNote(user.UserId.Hex(), user.UserId.Hex(), note.NoteId.Hex(), noteUpdate)
|
||||
// Log(noteId)
|
||||
// Log("Copy")
|
||||
// LogJ(note)
|
||||
noteUpdate := bson.M{"IsBlog": false} // 不要是博客
|
||||
noteService.UpdateNote(user.UserId.Hex(), note.NoteId.Hex(), noteUpdate, -1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +97,7 @@ func (this *AuthService) register(user info.User) (bool, string) {
|
||||
// 添加一条userBlog
|
||||
blogService.UpdateUserBlog(info.UserBlog{UserId: user.UserId,
|
||||
Title: user.Username + " 's Blog",
|
||||
SubTitle: "love leanote!",
|
||||
SubTitle: "Love Leanote!",
|
||||
AboutMe: "Hello, I am (^_^)",
|
||||
CanComment: true,
|
||||
})
|
||||
|
@ -69,9 +69,14 @@ func (this *BlogService) GetBlogItem(note info.Note) (blog info.BlogItem) {
|
||||
}
|
||||
|
||||
// 得到用户共享的notebooks
|
||||
// 3/19 博客不是deleted
|
||||
func (this *BlogService) ListBlogNotebooks(userId string) []info.Notebook {
|
||||
notebooks := []info.Notebook{}
|
||||
db.ListByQ(db.Notebooks, bson.M{"UserId": bson.ObjectIdHex(userId), "IsBlog": true}, ¬ebooks)
|
||||
orQ := []bson.M{
|
||||
bson.M{"IsDeleted": false},
|
||||
bson.M{"IsDeleted": bson.M{"$exists": false}},
|
||||
}
|
||||
db.ListByQ(db.Notebooks, bson.M{"UserId": bson.ObjectIdHex(userId), "IsBlog": true, "$or": orQ}, ¬ebooks)
|
||||
return notebooks
|
||||
}
|
||||
|
||||
@ -1094,13 +1099,15 @@ func (this *BlogService) SortSingles(userId string, singleIds []string) (ok bool
|
||||
|
||||
// 得到用户的博客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()
|
||||
if userBlog != nil {
|
||||
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
|
||||
}
|
||||
|
@ -580,5 +580,5 @@ func (this *ConfigService) HomePageIsAdminsBlog() bool {
|
||||
}
|
||||
|
||||
func (this *ConfigService) GetVersion() string {
|
||||
return "1.0-beta2"
|
||||
return "1.0-beta.4"
|
||||
}
|
||||
|
@ -243,5 +243,9 @@ func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, strin
|
||||
|
||||
// 是否是我的文件
|
||||
func (this *FileService) IsMyFile(userId, fileId string) bool {
|
||||
// 如果有问题会panic
|
||||
if !bson.IsObjectIdHex(fileId) || !bson.IsObjectIdHex(userId) {
|
||||
return false;
|
||||
}
|
||||
return db.Has(db.Files, bson.M{"UserId": bson.ObjectIdHex(userId), "_id": bson.ObjectIdHex(fileId)})
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ func (this *NoteImageService) GetNoteIds(imageId string) ([]bson.ObjectId) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO 这个web可以用, 但api会传来, 不用用了
|
||||
// 解析内容中的图片, 建立图片与note的关系
|
||||
// <img src="/file/outputImage?fileId=12323232" />
|
||||
// 图片必须是我的, 不然不添加
|
||||
@ -38,20 +39,21 @@ func (this *NoteImageService) UpdateNoteImages(userId, noteId, imgSrc, content s
|
||||
if imgSrc != "" {
|
||||
content = "<img src=\"" + imgSrc + "\" >" + content
|
||||
}
|
||||
reg, _ := regexp.Compile("outputImage\\?fileId=([a-z0-9A-Z]{24})")
|
||||
// life 添加getImage
|
||||
reg, _ := regexp.Compile("(outputImage|getImage)\\?fileId=([a-z0-9A-Z]{24})")
|
||||
find := reg.FindAllStringSubmatch(content, -1) // 查找所有的
|
||||
|
||||
|
||||
// 删除旧的
|
||||
db.DeleteAll(db.NoteImages, bson.M{"NoteId": bson.ObjectIdHex(noteId)})
|
||||
|
||||
|
||||
// 添加新的
|
||||
var fileId string
|
||||
noteImage := info.NoteImage{NoteId: bson.ObjectIdHex(noteId)}
|
||||
hasAdded := make(map[string]bool)
|
||||
if find != nil && len(find) > 0 {
|
||||
for _, each := range find {
|
||||
if each != nil && len(each) == 2 {
|
||||
fileId = each[1]
|
||||
if each != nil && len(each) == 3 {
|
||||
fileId = each[2] // 现在有两个子表达式了
|
||||
// 之前没能添加过的
|
||||
if _, ok := hasAdded[fileId]; !ok {
|
||||
Log(fileId)
|
||||
@ -105,3 +107,48 @@ func (this *NoteImageService) CopyNoteImages(fromNoteId, fromUserId, newNoteId,
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
//
|
||||
func (this *NoteImageService) getImagesByNoteIds(noteIds []bson.ObjectId) map[string][]info.File {
|
||||
noteNoteImages := []info.NoteImage{}
|
||||
db.ListByQ(db.NoteImages, bson.M{"NoteId": bson.M{"$in": noteIds}}, ¬eNoteImages)
|
||||
|
||||
// 得到imageId, 再去files表查所有的Files
|
||||
imageIds := []bson.ObjectId{}
|
||||
|
||||
// 图片1 => N notes
|
||||
imageIdNotes := map[string][]string{} // imageId => [noteId1, noteId2, ...]
|
||||
for _, noteImage := range noteNoteImages {
|
||||
imageId := noteImage.ImageId
|
||||
imageIds = append(imageIds, imageId)
|
||||
|
||||
imageIdHex := imageId.Hex()
|
||||
noteId := noteImage.NoteId.Hex()
|
||||
if notes, ok := imageIdNotes[imageIdHex]; ok {
|
||||
imageIdNotes[imageIdHex] = append(notes, noteId)
|
||||
} else {
|
||||
imageIdNotes[imageIdHex] = []string{noteId}
|
||||
}
|
||||
}
|
||||
|
||||
// 得到所有files
|
||||
files := []info.File{}
|
||||
db.ListByQ(db.Files, bson.M{"_id": bson.M{"$in": imageIds}}, &files)
|
||||
|
||||
// 建立note->file关联
|
||||
noteImages := make(map[string][]info.File)
|
||||
for _, file := range files {
|
||||
fileIdHex := file.FileId.Hex() // == imageId
|
||||
// 这个fileIdHex有哪些notes呢?
|
||||
if notes, ok := imageIdNotes[fileIdHex]; ok {
|
||||
for _, noteId := range notes {
|
||||
if files, ok2 := noteImages[noteId]; ok2 {
|
||||
noteImages[noteId] = append(files, file)
|
||||
} else {
|
||||
noteImages[noteId] = []info.File{file}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return noteImages
|
||||
}
|
||||
|
@ -44,14 +44,115 @@ func (this *NoteService) GetNoteAndContent(noteId, userId string) (noteAndConten
|
||||
return info.NoteAndContent{note, noteContent}
|
||||
}
|
||||
|
||||
// 获取同步的笔记
|
||||
// > afterUsn的笔记
|
||||
func (this *NoteService) GetSyncNotes(userId string, afterUsn, maxEntry int) []info.ApiNote {
|
||||
notes := []info.Note{}
|
||||
q := db.Notes.Find(bson.M{
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"Usn": bson.M{"$gt": afterUsn},
|
||||
});
|
||||
q.Sort("Usn").Limit(maxEntry).All(¬es)
|
||||
|
||||
return this.ToApiNotes(notes)
|
||||
}
|
||||
|
||||
// note与apiNote的转换
|
||||
func (this *NoteService) ToApiNotes(notes []info.Note) []info.ApiNote {
|
||||
// 2, 得到所有图片, 附件信息
|
||||
// 查images表, attachs表
|
||||
if len(notes) > 0 {
|
||||
noteIds := make([]bson.ObjectId, len(notes));
|
||||
for i, note := range notes {
|
||||
noteIds[i] = note.NoteId
|
||||
}
|
||||
noteFilesMap := this.getFiles(noteIds)
|
||||
// 生成info.ApiNote
|
||||
apiNotes := make([]info.ApiNote, len(notes))
|
||||
for i, note := range notes {
|
||||
noteId := note.NoteId.Hex()
|
||||
apiNotes[i] = this.ToApiNote(¬e, noteFilesMap[noteId])
|
||||
}
|
||||
return apiNotes
|
||||
}
|
||||
// 返回空的
|
||||
return []info.ApiNote{}
|
||||
}
|
||||
|
||||
|
||||
// note与apiNote的转换
|
||||
func (this *NoteService) ToApiNote(note *info.Note, files []info.NoteFile) info.ApiNote {
|
||||
apiNote := info.ApiNote{
|
||||
NoteId: note.NoteId.Hex(),
|
||||
NotebookId: note.NotebookId.Hex(),
|
||||
UserId : note.UserId.Hex(),
|
||||
Title : note.Title,
|
||||
Tags : note.Tags,
|
||||
IsMarkdown : note.IsMarkdown,
|
||||
IsBlog : note.IsBlog,
|
||||
IsTrash : note.IsTrash,
|
||||
IsDeleted : note.IsDeleted,
|
||||
Usn : note.Usn,
|
||||
CreatedTime : note.CreatedTime,
|
||||
UpdatedTime : note.UpdatedTime,
|
||||
PublicTime : note.PublicTime,
|
||||
Files: files,
|
||||
}
|
||||
return apiNote
|
||||
}
|
||||
|
||||
// getDirtyNotes, 把note的图片, 附件信息都发送给客户端
|
||||
// 客户端保存到本地, 再获取图片, 附件
|
||||
|
||||
// 得到所有图片, 附件信息
|
||||
// 查images表, attachs表
|
||||
// [待测]
|
||||
func (this *NoteService) getFiles(noteIds []bson.ObjectId) map[string][]info.NoteFile {
|
||||
noteImages := noteImageService.getImagesByNoteIds(noteIds);
|
||||
noteAttachs := attachService.getAttachsByNoteIds(noteIds)
|
||||
|
||||
noteFilesMap := map[string][]info.NoteFile{}
|
||||
|
||||
for _, noteId := range noteIds {
|
||||
noteIdHex := noteId.Hex()
|
||||
noteFiles := []info.NoteFile{}
|
||||
// images
|
||||
if images, ok := noteImages[noteIdHex]; ok {
|
||||
for _, image := range images {
|
||||
noteFiles = append(noteFiles, info.NoteFile{
|
||||
FileId: image.FileId.Hex(),
|
||||
Type: image.Type,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// attach
|
||||
if attachs, ok := noteAttachs[noteIdHex]; ok {
|
||||
for _, attach := range attachs {
|
||||
noteFiles = append(noteFiles, info.NoteFile{
|
||||
FileId: attach.AttachId.Hex(),
|
||||
Type: attach.Type,
|
||||
Title: attach.Title,
|
||||
IsAttach: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
noteFilesMap[noteIdHex] = noteFiles
|
||||
}
|
||||
|
||||
return noteFilesMap
|
||||
}
|
||||
|
||||
// 列出note, 排序规则, 还有分页
|
||||
// CreatedTime, UpdatedTime, title 来排序
|
||||
func (this *NoteService) ListNotes(userId, notebookId string,
|
||||
isTrash bool, pageNumber, pageSize int, sortField string, isAsc bool, isBlog bool) (count int, notes []info.Note) {
|
||||
notes = []info.Note{}
|
||||
skipNum, sortFieldR := parsePageAndSort(pageNumber, pageSize, sortField, isAsc)
|
||||
|
||||
// 不是trash的
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsTrash": isTrash}
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsTrash": isTrash, "IsDeleted": false}
|
||||
if isBlog {
|
||||
query["IsBlog"] = true
|
||||
}
|
||||
@ -121,7 +222,7 @@ func (this *NoteService) ListNoteContentByNoteIds(noteIds []bson.ObjectId) (note
|
||||
// 首先要判断Notebook是否是Blog, 是的话设为blog
|
||||
// [ok]
|
||||
|
||||
func (this *NoteService) AddNote(note info.Note) info.Note {
|
||||
func (this *NoteService) AddNote(note info.Note, fromApi bool) info.Note {
|
||||
if(note.NoteId.Hex() == "") {
|
||||
noteId := bson.NewObjectId();
|
||||
note.NoteId = noteId;
|
||||
@ -131,14 +232,19 @@ func (this *NoteService) AddNote(note info.Note) info.Note {
|
||||
note.IsTrash = false
|
||||
note.UpdatedUserId = note.UserId
|
||||
note.UrlTitle = GetUrTitle(note.UserId.Hex(), note.Title, "note")
|
||||
note.Usn = userService.IncrUsn(note.UserId.Hex())
|
||||
|
||||
// 设为blog
|
||||
notebookId := note.NotebookId.Hex()
|
||||
note.IsBlog = notebookService.IsBlog(notebookId)
|
||||
|
||||
if note.IsBlog {
|
||||
// api会传IsBlog, web不会传
|
||||
if !fromApi {
|
||||
note.PublicTime = note.UpdatedTime
|
||||
// 设为blog
|
||||
note.IsBlog = notebookService.IsBlog(notebookId)
|
||||
}
|
||||
// if note.IsBlog {
|
||||
note.PublicTime = note.UpdatedTime
|
||||
// }
|
||||
|
||||
db.Insert(db.Notes, note)
|
||||
|
||||
@ -156,7 +262,7 @@ func (this *NoteService) AddSharedNote(note info.Note, myUserId bson.ObjectId) i
|
||||
// 判断我是否有权限添加
|
||||
if shareService.HasUpdateNotebookPerm(note.UserId.Hex(), myUserId.Hex(), note.NotebookId.Hex()) {
|
||||
note.CreatedUserId = myUserId // 是我给共享我的人创建的
|
||||
return this.AddNote(note)
|
||||
return this.AddNote(note, false)
|
||||
}
|
||||
return info.Note{}
|
||||
}
|
||||
@ -176,6 +282,49 @@ func (this *NoteService) AddNoteContent(noteContent info.NoteContent) info.NoteC
|
||||
return noteContent;
|
||||
}
|
||||
|
||||
// API, abstract, desc需要这里获取
|
||||
// 不需要
|
||||
/*
|
||||
func (this *NoteService) AddNoteAndContentApi(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note {
|
||||
if(note.NoteId.Hex() == "") {
|
||||
noteId := bson.NewObjectId();
|
||||
note.NoteId = noteId;
|
||||
}
|
||||
note.CreatedTime = time.Now()
|
||||
note.UpdatedTime = note.CreatedTime
|
||||
note.IsTrash = false
|
||||
note.UpdatedUserId = note.UserId
|
||||
note.UrlTitle = GetUrTitle(note.UserId.Hex(), note.Title, "note")
|
||||
note.Usn = userService.IncrUsn(note.UserId.Hex())
|
||||
|
||||
// desc这里获取
|
||||
desc := SubStringHTMLToRaw(noteContent.Content, 50)
|
||||
note.Desc = desc;
|
||||
|
||||
// 设为blog
|
||||
notebookId := note.NotebookId.Hex()
|
||||
note.IsBlog = notebookService.IsBlog(notebookId)
|
||||
|
||||
if note.IsBlog {
|
||||
note.PublicTime = note.UpdatedTime
|
||||
}
|
||||
|
||||
db.Insert(db.Notes, note)
|
||||
|
||||
// tag1, 不需要了
|
||||
// tagService.AddTags(note.UserId.Hex(), note.Tags)
|
||||
|
||||
// recount notebooks' notes number
|
||||
notebookService.ReCountNotebookNumberNotes(notebookId)
|
||||
|
||||
// 这里, 添加到内容中
|
||||
abstract := SubStringHTML(noteContent.Content, 200, "")
|
||||
noteContent.Abstract = abstract
|
||||
this.AddNoteContent(noteContent)
|
||||
|
||||
return note
|
||||
}*/
|
||||
|
||||
// 添加笔记和内容
|
||||
// 这里使用 info.NoteAndContent 接收?
|
||||
func (this *NoteService) AddNoteAndContentForController(note info.Note, noteContent info.NoteContent, updatedUserId string) info.Note {
|
||||
@ -198,7 +347,24 @@ func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.Note
|
||||
if note.UserId != myUserId {
|
||||
note = this.AddSharedNote(note, myUserId)
|
||||
} else {
|
||||
note = this.AddNote(note)
|
||||
note = this.AddNote(note, false)
|
||||
}
|
||||
if note.NoteId != "" {
|
||||
this.AddNoteContent(noteContent)
|
||||
}
|
||||
return note
|
||||
}
|
||||
|
||||
func (this *NoteService) AddNoteAndContentApi(note info.Note, noteContent info.NoteContent, myUserId bson.ObjectId) info.Note {
|
||||
if(note.NoteId.Hex() == "") {
|
||||
noteId := bson.NewObjectId()
|
||||
note.NoteId = noteId
|
||||
}
|
||||
noteContent.NoteId = note.NoteId
|
||||
if note.UserId != myUserId {
|
||||
note = this.AddSharedNote(note, myUserId)
|
||||
} else {
|
||||
note = this.AddNote(note, true)
|
||||
}
|
||||
if note.NoteId != "" {
|
||||
this.AddNoteContent(noteContent)
|
||||
@ -207,19 +373,30 @@ func (this *NoteService) AddNoteAndContent(note info.Note, noteContent info.Note
|
||||
}
|
||||
|
||||
// 修改笔记
|
||||
func (this *NoteService) UpdateNote(userId, updatedUserId, noteId string, needUpdate bson.M) bool {
|
||||
// 这里没有判断usn
|
||||
func (this *NoteService) UpdateNote(updatedUserId, noteId string, needUpdate bson.M, usn int) (bool, string, int) {
|
||||
// 是否存在
|
||||
note := this.GetNoteById(noteId)
|
||||
if note.NoteId == "" {
|
||||
return false, "notExists", 0
|
||||
}
|
||||
|
||||
userId := note.UserId.Hex()
|
||||
// updatedUserId 要修改userId的note, 此时需要判断是否有修改权限
|
||||
if userId != updatedUserId {
|
||||
if !shareService.HasUpdatePerm(userId, updatedUserId, noteId) {
|
||||
Log("NO AUTH2")
|
||||
return false
|
||||
return false, "noAuth", 0
|
||||
} else {
|
||||
Log("HAS AUTH -----------")
|
||||
}
|
||||
}
|
||||
|
||||
if usn > 0 && note.Usn != usn {
|
||||
return false, "conflict", 0
|
||||
}
|
||||
|
||||
// 是否已自定义
|
||||
note := this.GetNoteById(noteId)
|
||||
if note.IsBlog && note.HasSelfDefined {
|
||||
delete(needUpdate, "ImgSrc")
|
||||
delete(needUpdate, "Desc")
|
||||
@ -227,8 +404,11 @@ func (this *NoteService) UpdateNote(userId, updatedUserId, noteId string, needUp
|
||||
|
||||
needUpdate["UpdatedUserId"] = bson.ObjectIdHex(updatedUserId);
|
||||
needUpdate["UpdatedTime"] = time.Now();
|
||||
afterUsn := userService.IncrUsn(userId);
|
||||
needUpdate["Usn"] = afterUsn
|
||||
|
||||
// 添加tag2
|
||||
// TODO 这个tag去掉, 添加tag另外添加, 不要这个
|
||||
if tags, ok := needUpdate["Tags"]; ok {
|
||||
tagService.AddTagsI(userId, tags)
|
||||
}
|
||||
@ -236,10 +416,55 @@ func (this *NoteService) UpdateNote(userId, updatedUserId, noteId string, needUp
|
||||
// 是否修改了isBlog
|
||||
// 也要修改noteContents的IsBlog
|
||||
if isBlog, ok := needUpdate["IsBlog"]; ok {
|
||||
db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId, bson.M{"IsBlog": isBlog})
|
||||
isBlog2 := isBlog.(bool)
|
||||
if note.IsBlog != isBlog2 {
|
||||
db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId, bson.M{"IsBlog": isBlog2})
|
||||
|
||||
// 重新发布成博客
|
||||
if !note.IsBlog {
|
||||
needUpdate["PublicTime"] = needUpdate["UpdatedTime"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, needUpdate)
|
||||
ok := db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, needUpdate)
|
||||
if !ok {
|
||||
return ok, "", 0
|
||||
}
|
||||
|
||||
// 重新获取之
|
||||
note = this.GetNoteById(noteId)
|
||||
|
||||
hasRecount := false
|
||||
|
||||
// 如果修改了notebookId, 则更新notebookId'count
|
||||
// 两方的notebook也要修改
|
||||
notebookIdI := needUpdate["NotebookId"]
|
||||
if notebookIdI != nil {
|
||||
notebookId := notebookIdI.(bson.ObjectId)
|
||||
if notebookId != "" {
|
||||
notebookService.ReCountNotebookNumberNotes(note.NotebookId.Hex())
|
||||
hasRecount = true
|
||||
notebookService.ReCountNotebookNumberNotes(notebookId.Hex())
|
||||
}
|
||||
}
|
||||
|
||||
// 不要多次更新, isTrash = false, = true都要重新统计
|
||||
if !hasRecount {
|
||||
if _, ok := needUpdate["IsTrash"]; ok {
|
||||
notebookService.ReCountNotebookNumberNotes(note.NotebookId.Hex())
|
||||
}
|
||||
}
|
||||
|
||||
return true, "", afterUsn
|
||||
}
|
||||
|
||||
// 附件修改, 增加noteIncr
|
||||
func (this *NoteService) IncrNoteUsn(noteId, userId string) int {
|
||||
afterUsn := userService.IncrUsn(userId)
|
||||
db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"UpdatedTime": time.Now(), "Usn": afterUsn})
|
||||
return afterUsn
|
||||
}
|
||||
|
||||
// 这里要判断权限, 如果userId != updatedUserId, 那么需要判断权限
|
||||
@ -254,31 +479,50 @@ func (this *NoteService) UpdateNoteTitle(userId, updatedUserId, noteId, title st
|
||||
}
|
||||
|
||||
return db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId), "Title": title, "UpdatedTime": time.Now()})
|
||||
bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId), "Title": title, "UpdatedTime": time.Now(), "Usn": userService.IncrUsn(userId)})
|
||||
}
|
||||
|
||||
// 修改笔记本内容
|
||||
// [ok] TODO perm未测
|
||||
func (this *NoteService) UpdateNoteContent(userId, updatedUserId, noteId, content, abstract string) bool {
|
||||
// hasBeforeUpdateNote 之前是否更新过note其它信息, 如果有更新, usn不用更新
|
||||
// TODO abstract这里生成
|
||||
func (this *NoteService) UpdateNoteContent(updatedUserId, noteId, content, abstract string, hasBeforeUpdateNote bool, usn int) (bool, string, int) {
|
||||
// 是否已自定义
|
||||
note := this.GetNoteById(noteId)
|
||||
if note.NoteId == "" {
|
||||
return false, "notExists", 0
|
||||
}
|
||||
userId := note.UserId.Hex()
|
||||
// updatedUserId 要修改userId的note, 此时需要判断是否有修改权限
|
||||
if userId != updatedUserId {
|
||||
if !shareService.HasUpdatePerm(userId, updatedUserId, noteId) {
|
||||
Log("NO AUTH")
|
||||
return false
|
||||
return false, "noAuth", 0
|
||||
}
|
||||
}
|
||||
|
||||
// abstract重置
|
||||
data := bson.M{"UpdatedUserId": bson.ObjectIdHex(updatedUserId),
|
||||
"Content": content,
|
||||
"Abstract": abstract,
|
||||
"UpdatedTime": time.Now()}
|
||||
|
||||
// 是否已自定义
|
||||
note := this.GetNoteById(noteId)
|
||||
if note.IsBlog && note.HasSelfDefined {
|
||||
delete(data, "Abstract")
|
||||
}
|
||||
|
||||
// usn, 修改笔记不可能单独修改内容
|
||||
afterUsn := 0
|
||||
// 如果之前没有修改note其它信息, 那么usn++
|
||||
if !hasBeforeUpdateNote {
|
||||
// 需要验证
|
||||
if usn >= 0 && note.Usn != usn {
|
||||
return false, "conflict", 0
|
||||
}
|
||||
afterUsn = userService.IncrUsn(userId)
|
||||
db.UpdateByIdAndUserIdField(db.Notes, noteId, userId, "Usn", usn)
|
||||
}
|
||||
|
||||
if db.UpdateByIdAndUserIdMap(db.NoteContents, noteId, userId, data) {
|
||||
// 这里, 添加历史记录
|
||||
noteContentHistoryService.AddHistory(noteId, userId, info.EachHistory{UpdatedUserId: bson.ObjectIdHex(updatedUserId),
|
||||
@ -289,9 +533,9 @@ func (this *NoteService) UpdateNoteContent(userId, updatedUserId, noteId, conten
|
||||
// 更新笔记图片
|
||||
noteImageService.UpdateNoteImages(userId, noteId, note.ImgSrc, content)
|
||||
|
||||
return true
|
||||
return true, "", afterUsn
|
||||
}
|
||||
return false
|
||||
return false, "", 0
|
||||
}
|
||||
|
||||
// ?????
|
||||
@ -305,7 +549,7 @@ func (this *NoteService) updateNoteImages(noteId string, content string) bool {
|
||||
// 更新tags
|
||||
// [ok] [del]
|
||||
func (this *NoteService) UpdateTags(noteId string, userId string, tags []string) bool {
|
||||
return db.UpdateByIdAndUserIdField(db.Notes, noteId, userId, "Tags", tags)
|
||||
return db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, bson.M{"Tags": tags, "Usn": userService.IncrUsn(userId)})
|
||||
}
|
||||
|
||||
func (this *NoteService) ToBlog(userId, noteId string, isBlog, isTop bool) bool {
|
||||
@ -323,6 +567,8 @@ func (this *NoteService) ToBlog(userId, noteId string, isBlog, isTop bool) bool
|
||||
} else {
|
||||
noteUpdate["HasSelfDefined"] = false
|
||||
}
|
||||
noteUpdate["Usn"] = userService.IncrUsn(userId)
|
||||
|
||||
ok := db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId, noteUpdate)
|
||||
// 重新计算tags
|
||||
go (func() {
|
||||
@ -342,7 +588,9 @@ func (this *NoteService) MoveNote(noteId, notebookId, userId string) info.Note {
|
||||
|
||||
re := db.UpdateByIdAndUserId(db.Notes, noteId, userId,
|
||||
bson.M{"$set": bson.M{"IsTrash": false,
|
||||
"NotebookId": bson.ObjectIdHex(notebookId)}})
|
||||
"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"Usn": userService.IncrUsn(userId),
|
||||
}})
|
||||
|
||||
if re {
|
||||
// 更新blog状态
|
||||
@ -364,13 +612,14 @@ func (this *NoteService) MoveNote(noteId, notebookId, userId string) info.Note {
|
||||
// 如果自己的blog状态是true, 不用改变,
|
||||
// 否则, 如果notebookId的blog是true, 则改为true之
|
||||
// 返回blog状态
|
||||
// move, copy时用
|
||||
func (this *NoteService) updateToNotebookBlog(noteId, notebookId, userId string) bool {
|
||||
if this.IsBlog(noteId) {
|
||||
return true
|
||||
}
|
||||
if notebookService.IsBlog(notebookId) {
|
||||
db.UpdateByIdAndUserId(db.Notes, noteId, userId,
|
||||
bson.M{"$set": bson.M{"IsBlog": true}})
|
||||
bson.M{"$set": bson.M{"IsBlog": true, "PublicTime": time.Now()}}) // life
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -567,7 +816,6 @@ func (this *NoteService) SearchNoteByTags(tags []string, userId string, pageNumb
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
//------------
|
||||
// 统计
|
||||
func (this *NoteService) CountNote(userId string) int {
|
||||
@ -583,4 +831,43 @@ func (this *NoteService) CountBlog(userId string) int {
|
||||
q["UserId"] = bson.ObjectIdHex(userId)
|
||||
}
|
||||
return db.Count(db.Notes, q)
|
||||
}
|
||||
}
|
||||
|
||||
// 通过标签来查询
|
||||
func (this *NoteService) CountNoteByTag(userId string, tag string) int {
|
||||
if tag == "" {
|
||||
return 0
|
||||
}
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId),
|
||||
// "IsTrash": false,
|
||||
"IsDeleted": false,
|
||||
"Tags": bson.M{"$in": []string{tag}}}
|
||||
return db.Count(db.Notes, query)
|
||||
}
|
||||
|
||||
// 删除tag
|
||||
// 返回所有note的Usn
|
||||
func (this *NoteService) UpdateNoteToDeleteTag(userId string, targetTag string) map[string]int {
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId),
|
||||
"Tags": bson.M{"$in": []string{targetTag}}}
|
||||
notes := []info.Note{}
|
||||
db.ListByQ(db.Notes, query, ¬es)
|
||||
ret := map[string]int{}
|
||||
for _, note := range notes {
|
||||
tags := note.Tags
|
||||
if tags == nil {
|
||||
continue
|
||||
}
|
||||
for i, tag := range tags {
|
||||
if tag == targetTag {
|
||||
tags = tags
|
||||
tags = append(tags[:i], tags[i+1:]...)
|
||||
break;
|
||||
}
|
||||
}
|
||||
usn := userService.IncrUsn(userId)
|
||||
db.UpdateByQMap(db.Notes, bson.M{"_id": note.NoteId}, bson.M{"Usn": usn, "Tags": tags})
|
||||
ret[note.NoteId.Hex()] = usn
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
@ -111,12 +111,24 @@ func (this *NotebookService) GetNotebookByUserIdAndUrlTitle(userId, notebookIdOr
|
||||
return notebook
|
||||
}
|
||||
|
||||
// 同步的方法
|
||||
func (this *NotebookService) GeSyncNotebooks(userId string, afterUsn, maxEntry int) ([]info.Notebook) {
|
||||
notebooks := []info.Notebook{}
|
||||
q := db.Notebooks.Find(bson.M{"UserId": bson.ObjectIdHex(userId), "Usn": bson.M{"$gt": afterUsn}});
|
||||
q.Sort("Usn").Limit(maxEntry).All(¬ebooks)
|
||||
return notebooks
|
||||
}
|
||||
|
||||
// 得到用户下所有的notebook
|
||||
// 排序好之后返回
|
||||
// [ok]
|
||||
func (this *NotebookService) GetNotebooks(userId string) info.SubNotebooks {
|
||||
userNotebooks := []info.Notebook{}
|
||||
db.Notebooks.Find(bson.M{"UserId": bson.ObjectIdHex(userId)}).All(&userNotebooks)
|
||||
orQ := []bson.M{
|
||||
bson.M{"IsDeleted": false},
|
||||
bson.M{"IsDeleted": bson.M{"$exists": false}},
|
||||
}
|
||||
db.Notebooks.Find(bson.M{"UserId": bson.ObjectIdHex(userId), "$or": orQ}).All(&userNotebooks)
|
||||
|
||||
if len(userNotebooks) == 0 {
|
||||
return nil
|
||||
@ -141,14 +153,46 @@ func (this *NotebookService) GetNotebooksByNotebookIds(notebookIds []bson.Object
|
||||
|
||||
// 添加
|
||||
// [ok]
|
||||
func (this *NotebookService) AddNotebook(notebook info.Notebook) bool {
|
||||
func (this *NotebookService) AddNotebook(notebook info.Notebook) (bool, info.Notebook) {
|
||||
notebook.UrlTitle = GetUrTitle(notebook.UserId.Hex(), notebook.Title, "notebook")
|
||||
notebook.Usn = userService.IncrUsn(notebook.UserId.Hex())
|
||||
now := time.Now()
|
||||
notebook.CreatedTime = now
|
||||
notebook.UpdatedTime = now
|
||||
err := db.Notebooks.Insert(notebook)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
return false, notebook
|
||||
}
|
||||
return true
|
||||
return true, notebook
|
||||
}
|
||||
// 更新笔记, api
|
||||
func (this *NotebookService) UpdateNotebookApi(userId, notebookId, title, parentNotebookId string, seq, usn int) (bool, string, info.Notebook) {
|
||||
if notebookId == "" {
|
||||
return false, "notebookIdNotExists", info.Notebook{}
|
||||
}
|
||||
|
||||
// 先判断usn是否和数据库的一样, 如果不一样, 则冲突, 不保存
|
||||
notebook := this.GetNotebookById(notebookId)
|
||||
// 不存在
|
||||
if notebook.NotebookId == "" {
|
||||
return false, "notExists", notebook
|
||||
} else if notebook.Usn != usn {
|
||||
return false, "conflict", notebook
|
||||
}
|
||||
notebook.Usn = userService.IncrUsn(userId);
|
||||
notebook.Title = title;
|
||||
|
||||
updates := bson.M{"Title": title, "Usn": notebook.Usn, "Seq": seq, "UpdatedTime": time.Now()};
|
||||
if(parentNotebookId != "" && bson.IsObjectIdHex(parentNotebookId)) {
|
||||
updates["ParentNotebookId"] = bson.ObjectIdHex(parentNotebookId);
|
||||
} else {
|
||||
updates["ParentNotebookId"] = "";
|
||||
}
|
||||
ok := db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates);
|
||||
if ok {
|
||||
return ok, "", this.GetNotebookById(notebookId)
|
||||
}
|
||||
return false, "", notebook
|
||||
}
|
||||
|
||||
// 判断是否是blog
|
||||
@ -174,19 +218,22 @@ func (this *NotebookService) UpdateNotebook(notebook info.Notebook) bool {
|
||||
// 更新笔记本标题
|
||||
// [ok]
|
||||
func (this *NotebookService) UpdateNotebookTitle(notebookId, userId, title string) bool {
|
||||
return db.UpdateByIdAndUserIdField(db.Notebooks, notebookId, userId, "Title", title)
|
||||
usn := userService.IncrUsn(userId)
|
||||
return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, bson.M{"Title": title, "Usn": usn})
|
||||
}
|
||||
|
||||
// 更新notebook
|
||||
func (this *NotebookService) UpdateNotebook(userId, notebookId string, needUpdate bson.M) bool {
|
||||
needUpdate["UpdatedTime"] = time.Now();
|
||||
needUpdate["Usn"] = userService.IncrUsn(userId)
|
||||
return db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, needUpdate)
|
||||
}
|
||||
|
||||
// ToBlog or Not
|
||||
func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (bool) {
|
||||
updates := bson.M{"IsBlog": isBlog, "Usn": userService.IncrUsn(userId)}
|
||||
// 笔记本
|
||||
db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, bson.M{"IsBlog": isBlog})
|
||||
db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, updates)
|
||||
|
||||
// 更新笔记
|
||||
q := bson.M{"UserId": bson.ObjectIdHex(userId),
|
||||
@ -197,6 +244,8 @@ func (this *NotebookService) ToBlog(userId, notebookId string, isBlog bool) (boo
|
||||
} else {
|
||||
data["HasSelfDefined"] = false
|
||||
}
|
||||
// usn
|
||||
data["Usn"] = userService.IncrUsn(userId)
|
||||
db.UpdateByQMap(db.Notes, q, data)
|
||||
|
||||
// noteContents也更新, 这个就麻烦了, noteContents表没有NotebookId
|
||||
@ -227,7 +276,10 @@ func (this *NotebookService) DeleteNotebook(userId, notebookId string) (bool, st
|
||||
if db.Count(db.Notes, bson.M{"NotebookId": bson.ObjectIdHex(notebookId),
|
||||
"UserId": bson.ObjectIdHex(userId),
|
||||
"IsTrash": false}) == 0 { // 不包含trash
|
||||
return db.DeleteByIdAndUserId(db.Notebooks, notebookId, userId), ""
|
||||
// 不是真删除 1/20, 为了同步笔记本
|
||||
ok := db.UpdateByQMap(db.Notebooks, bson.M{"_id": bson.ObjectIdHex(notebookId)}, bson.M{"IsDeleted": true, "Usn": userService.IncrUsn(userId)})
|
||||
return ok, ""
|
||||
// return db.DeleteByIdAndUserId(db.Notebooks, notebookId, userId), ""
|
||||
}
|
||||
return false, "笔记本下有笔记"
|
||||
} else {
|
||||
@ -235,6 +287,18 @@ func (this *NotebookService) DeleteNotebook(userId, notebookId string) (bool, st
|
||||
}
|
||||
}
|
||||
|
||||
// API调用, 删除笔记本, 不作笔记控制
|
||||
func (this *NotebookService) DeleteNotebookForce(userId, notebookId string, usn int) (bool, string) {
|
||||
notebook := this.GetNotebookById(notebookId)
|
||||
// 不存在
|
||||
if notebook.NotebookId == "" {
|
||||
return false, "notExists"
|
||||
} else if notebook.Usn != usn {
|
||||
return false, "conflict"
|
||||
}
|
||||
return db.DeleteByIdAndUserId(db.Notebooks, notebookId, userId), ""
|
||||
}
|
||||
|
||||
// 排序
|
||||
// 传入 notebookId => Seq
|
||||
// 为什么要传入userId, 防止修改其它用户的信息 (恶意)
|
||||
@ -245,7 +309,7 @@ func (this *NotebookService) SortNotebooks(userId string, notebookId2Seqs map[st
|
||||
}
|
||||
|
||||
for notebookId, seq := range notebookId2Seqs {
|
||||
if !db.UpdateByIdAndUserIdField2(db.Notebooks, bson.ObjectIdHex(notebookId), bson.ObjectIdHex(userId), "Seq", seq) {
|
||||
if !db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, bson.M{"Seq": seq, "Usn": userService.IncrUsn(userId)}) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -253,15 +317,14 @@ func (this *NotebookService) SortNotebooks(userId string, notebookId2Seqs map[st
|
||||
return true
|
||||
}
|
||||
|
||||
// 排序和设置父
|
||||
func (this *NotebookService) DragNotebooks(userId string, curNotebookId string, parentNotebookId string, siblings []string) bool {
|
||||
userIdO := bson.ObjectIdHex(userId)
|
||||
|
||||
ok := false
|
||||
// 如果没parentNotebookId, 则parentNotebookId设空
|
||||
if(parentNotebookId == "") {
|
||||
ok = db.UpdateByIdAndUserIdField2(db.Notebooks, bson.ObjectIdHex(curNotebookId), userIdO, "ParentNotebookId", "");
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": "", "Usn": userService.IncrUsn(userId)});
|
||||
} else {
|
||||
ok = db.UpdateByIdAndUserIdField2(db.Notebooks, bson.ObjectIdHex(curNotebookId), userIdO, "ParentNotebookId", bson.ObjectIdHex(parentNotebookId));
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notebooks, curNotebookId, userId, bson.M{"ParentNotebookId": bson.ObjectIdHex(parentNotebookId), "Usn": userService.IncrUsn(userId)});
|
||||
}
|
||||
|
||||
if !ok {
|
||||
@ -270,7 +333,7 @@ func (this *NotebookService) DragNotebooks(userId string, curNotebookId string,
|
||||
|
||||
// 排序
|
||||
for seq, notebookId := range siblings {
|
||||
if !db.UpdateByIdAndUserIdField2(db.Notebooks, bson.ObjectIdHex(notebookId), userIdO, "Seq", seq) {
|
||||
if !db.UpdateByIdAndUserIdMap(db.Notebooks, notebookId, userId, bson.M{"Seq": seq, "Usn": userService.IncrUsn(userId)}) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -283,7 +346,7 @@ func (this *NotebookService) DragNotebooks(userId string, curNotebookId string,
|
||||
// trashService: DeleteNote (recove不用, 都统一在MoveNote里了)
|
||||
func (this *NotebookService) ReCountNotebookNumberNotes(notebookId string) bool {
|
||||
notebookIdO := bson.ObjectIdHex(notebookId)
|
||||
count := db.Count(db.Notes, bson.M{"NotebookId": notebookIdO, "IsTrash": false})
|
||||
count := db.Count(db.Notes, bson.M{"NotebookId": notebookIdO, "IsTrash": false, "IsDeleted": false})
|
||||
Log(count)
|
||||
Log(notebookId)
|
||||
return db.UpdateByQField(db.Notebooks, bson.M{"_id": notebookIdO}, "NumberNotes", count)
|
||||
|
@ -69,3 +69,20 @@ func (this *SessionService) SetCaptcha(sessionId, captcha string) bool {
|
||||
Log(ok)
|
||||
return ok
|
||||
}
|
||||
|
||||
//-----------
|
||||
// API
|
||||
func (this *SessionService) GetUserId(sessionId string) string {
|
||||
session := this.Get(sessionId)
|
||||
// 更新updateTime, 避免过期
|
||||
db.UpdateByQMap(db.Sessions, bson.M{"SessionId": sessionId},
|
||||
bson.M{"UpdatedTime": time.Now()})
|
||||
return session.UserId
|
||||
}
|
||||
|
||||
// 登录成功后设置userId
|
||||
func (this *SessionService) SetUserId(sessionId, userId string) bool {
|
||||
this.Get(sessionId)
|
||||
ok := this.Update(sessionId, "UserId", userId)
|
||||
return ok
|
||||
}
|
||||
|
@ -294,7 +294,11 @@ func (this *ShareService) AddShareNotebook(notebookId string, perm int, userId,
|
||||
if toUserId == "" {
|
||||
return false, "无该用户", ""
|
||||
}
|
||||
return this.AddShareNotebookToUserId(notebookId, perm, userId, toUserId)
|
||||
}
|
||||
|
||||
// 第三方注册时没有email
|
||||
func (this *ShareService) AddShareNotebookToUserId(notebookId string, perm int, userId, toUserId string) (bool, string, string) {
|
||||
// 添加一条记录说明两者存在关系
|
||||
this.AddHasShareNote(userId, toUserId);
|
||||
|
||||
@ -327,7 +331,11 @@ func (this *ShareService) AddShareNote(noteId string, perm int, userId, email st
|
||||
if toUserId == "" {
|
||||
return false, "无该用户", ""
|
||||
}
|
||||
|
||||
return this.AddShareNoteToUserId(noteId, perm, userId, toUserId)
|
||||
}
|
||||
|
||||
// 第三方测试没有userId
|
||||
func (this *ShareService) AddShareNoteToUserId(noteId string, perm int, userId, toUserId string) (bool, string, string) {
|
||||
// 添加一条记录说明两者存在关系
|
||||
this.AddHasShareNote(userId, toUserId);
|
||||
|
||||
|
@ -3,9 +3,9 @@ package service
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "time"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -14,12 +14,14 @@ import (
|
||||
type TagService struct {
|
||||
}
|
||||
|
||||
/*
|
||||
func (this *TagService) GetTags(userId string) []string {
|
||||
tag := info.Tag{}
|
||||
db.Get(db.Tags, userId, &tag)
|
||||
LogJ(tag)
|
||||
return tag.Tags
|
||||
}
|
||||
*/
|
||||
|
||||
func (this *TagService) AddTagsI(userId string, tags interface{}) bool {
|
||||
if ts, ok2 := tags.([]string); ok2 {
|
||||
@ -36,4 +38,100 @@ func (this *TagService) AddTags(userId string, tags []string) bool {
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
// v2
|
||||
// 第二版标签, 单独一张表, 每一个tag一条记录
|
||||
|
||||
// 添加或更新标签, 先查下是否存在, 不存在则添加, 存在则更新
|
||||
// 都要统计下tag的note数
|
||||
// 什么时候调用? 笔记添加Tag, 删除Tag时
|
||||
// 删除note时, 都可以调用
|
||||
// 万能
|
||||
func (this *TagService) AddOrUpdateTag(userId string, tag string) info.NoteTag {
|
||||
userIdO := bson.ObjectIdHex(userId)
|
||||
noteTag := info.NoteTag{}
|
||||
db.GetByQ(db.NoteTags, bson.M{"UserId": userIdO, "Tag": tag}, ¬eTag)
|
||||
|
||||
// 存在, 则更新之
|
||||
if noteTag.TagId != "" {
|
||||
// 统计note数
|
||||
count := noteService.CountNoteByTag(userId, tag)
|
||||
noteTag.Count = count
|
||||
noteTag.UpdatedTime = time.Now()
|
||||
// noteTag.Usn = userService.IncrUsn(userId), 更新count而已
|
||||
db.UpdateByIdAndUserId(db.NoteTags, noteTag.TagId.Hex(), userId, noteTag)
|
||||
return noteTag
|
||||
}
|
||||
|
||||
// 不存在, 则创建之
|
||||
noteTag.TagId = bson.NewObjectId()
|
||||
noteTag.Count = 1
|
||||
noteTag.Tag = tag
|
||||
noteTag.UserId = bson.ObjectIdHex(userId)
|
||||
noteTag.CreatedTime = time.Now()
|
||||
noteTag.UpdatedTime = noteTag.CreatedTime
|
||||
noteTag.Usn = userService.IncrUsn(userId)
|
||||
noteTag.IsDeleted = false
|
||||
db.Insert(db.NoteTags, noteTag)
|
||||
|
||||
return noteTag
|
||||
}
|
||||
|
||||
// 得到标签, 按更新时间来排序
|
||||
func (this *TagService) GetTags(userId string) []info.NoteTag {
|
||||
tags := []info.NoteTag{}
|
||||
query := bson.M{"UserId": bson.ObjectIdHex(userId), "IsDeleted": false}
|
||||
q := db.NoteTags.Find(query);
|
||||
sortFieldR := "-UpdatedTime"
|
||||
q.Sort(sortFieldR).All(&tags)
|
||||
return tags
|
||||
}
|
||||
|
||||
// 删除标签
|
||||
// 也删除所有的笔记含该标签的
|
||||
// 返回noteId => usn
|
||||
func (this *TagService) DeleteTag(userId string, tag string) map[string]int {
|
||||
usn := userService.IncrUsn(userId)
|
||||
if db.UpdateByQMap(db.NoteTags, bson.M{"UserId": bson.ObjectIdHex(userId), "Tag": tag}, bson.M{"Usn": usn, "IsDeleted": true}) {
|
||||
return noteService.UpdateNoteToDeleteTag(userId, tag);
|
||||
}
|
||||
return map[string]int{}
|
||||
}
|
||||
|
||||
// 删除标签, 供API调用
|
||||
func (this *TagService) DeleteTagApi(userId string, tag string, usn int) (ok bool, msg string, toUsn int) {
|
||||
noteTag := info.NoteTag{}
|
||||
db.GetByQ(db.NoteTags, bson.M{"UserId": bson.ObjectIdHex(userId), "Tag": tag}, ¬eTag)
|
||||
|
||||
if noteTag.TagId == "" {
|
||||
return false, "notExists", 0
|
||||
}
|
||||
if noteTag.Usn > usn {
|
||||
return false, "conflict", 0
|
||||
}
|
||||
toUsn = userService.IncrUsn(userId)
|
||||
if db.UpdateByQMap(db.NoteTags, bson.M{"UserId": bson.ObjectIdHex(userId), "Tag": tag}, bson.M{"Usn": usn, "IsDeleted": true}) {
|
||||
return true, "", toUsn
|
||||
}
|
||||
return false, "", 0
|
||||
}
|
||||
|
||||
// 重新统计标签的count
|
||||
func (this *TagService) reCountTagCount(userId string, tags []string) {
|
||||
if tags == nil {
|
||||
return
|
||||
}
|
||||
for _, tag := range tags {
|
||||
this.AddOrUpdateTag(userId, tag);
|
||||
}
|
||||
}
|
||||
|
||||
// 同步用
|
||||
func (this *TagService) GeSyncTags(userId string, afterUsn, maxEntry int) ([]info.NoteTag) {
|
||||
noteTags := []info.NoteTag{}
|
||||
q := db.NoteTags.Find(bson.M{"UserId": bson.ObjectIdHex(userId), "Usn": bson.M{"$gt": afterUsn}});
|
||||
q.Sort("Usn").Limit(maxEntry).All(¬eTags)
|
||||
return noteTags
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func (this *TrashService) DeleteNote(noteId, userId string) bool {
|
||||
// 首先删除其共享
|
||||
if shareService.DeleteShareNoteAll(noteId, userId) {
|
||||
// 更新note isTrash = true
|
||||
if db.UpdateByIdAndUserId(db.Notes, noteId, userId, bson.M{"$set": bson.M{"IsTrash": true}}) {
|
||||
if db.UpdateByIdAndUserId(db.Notes, noteId, userId, bson.M{"$set": bson.M{"IsTrash": true, "Usn": userService.IncrUsn(userId)}}) {
|
||||
// recount notebooks' notes number
|
||||
notebookIdO := noteService.GetNotebookId(noteId)
|
||||
notebookId := notebookIdO.Hex()
|
||||
@ -44,7 +44,7 @@ func (this *TrashService) DeleteNote(noteId, userId string) bool {
|
||||
func (this *TrashService) DeleteSharedNote(noteId, userId, myUserId string) bool {
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
if shareService.HasUpdatePerm(userId, myUserId, noteId) && note.CreatedUserId.Hex() == myUserId {
|
||||
return db.UpdateByIdAndUserId(db.Notes, noteId, userId, bson.M{"$set": bson.M{"IsTrash": true}})
|
||||
return db.UpdateByIdAndUserId(db.Notes, noteId, userId, bson.M{"$set": bson.M{"IsTrash": true, "Usn": userService.IncrUsn(userId)}})
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -53,23 +53,63 @@ func (this *TrashService) DeleteSharedNote(noteId, userId, myUserId string) bool
|
||||
func (this *TrashService) recoverNote(noteId, notebookId, userId string) bool {
|
||||
re := db.UpdateByIdAndUserId(db.Notes, noteId, userId,
|
||||
bson.M{"$set": bson.M{"IsTrash": false,
|
||||
"Usn": userService.IncrUsn(userId),
|
||||
"NotebookId": bson.ObjectIdHex(notebookId)}})
|
||||
return re;
|
||||
}
|
||||
|
||||
// 删除trash
|
||||
func (this *TrashService) DeleteTrash(noteId, userId string) bool {
|
||||
note := noteService.GetNote(noteId, userId);
|
||||
if note.NoteId == "" {
|
||||
return false
|
||||
}
|
||||
// delete note's attachs
|
||||
ok := attachService.DeleteAllAttachs(noteId, userId)
|
||||
|
||||
|
||||
// 设置删除位
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"IsDeleted": true,
|
||||
"Usn": userService.IncrUsn(userId)})
|
||||
// delete note
|
||||
ok = db.DeleteByIdAndUserId(db.Notes, noteId, userId)
|
||||
// ok = db.DeleteByIdAndUserId(db.Notes, noteId, userId)
|
||||
|
||||
// delete content
|
||||
ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId)
|
||||
|
||||
// 重新统计tag's count
|
||||
// TODO 这里会改变tag's Usn
|
||||
tagService.reCountTagCount(userId, note.Tags)
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
func (this *TrashService) DeleteTrashApi(noteId, userId string, usn int) (bool, string, int) {
|
||||
note := noteService.GetNote(noteId, userId)
|
||||
|
||||
if note.NoteId == "" || note.IsDeleted {
|
||||
return false, "notExists", 0
|
||||
}
|
||||
|
||||
if note.Usn != usn {
|
||||
return false, "conflict", 0
|
||||
}
|
||||
|
||||
// delete note's attachs
|
||||
ok := attachService.DeleteAllAttachs(noteId, userId)
|
||||
|
||||
// 设置删除位
|
||||
afterUsn := userService.IncrUsn(userId)
|
||||
ok = db.UpdateByIdAndUserIdMap(db.Notes, noteId, userId,
|
||||
bson.M{"IsDeleted": true,
|
||||
"Usn": afterUsn})
|
||||
|
||||
// delete content
|
||||
ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId)
|
||||
|
||||
return ok, "", afterUsn
|
||||
}
|
||||
|
||||
// 列出note, 排序规则, 还有分页
|
||||
// CreatedTime, UpdatedTime, title 来排序
|
||||
func (this *TrashService) ListNotes(userId string,
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
// "time"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ func (this *UpgradeService) UpgradeBlog() bool {
|
||||
*/
|
||||
func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg string) {
|
||||
if configService.GetGlobalStringConfig("UpgradeBetaToBeta2") != "" {
|
||||
return false, "已升级"
|
||||
return false, "Leanote have been upgraded"
|
||||
}
|
||||
|
||||
// 1. aboutMe -> page
|
||||
@ -102,3 +102,81 @@ func (this *UpgradeService) UpgradeBetaToBeta2(userId string) (ok bool, msg stri
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Usn设置
|
||||
// 客户端 api
|
||||
|
||||
func (this *UpgradeService) moveTag() {
|
||||
usnI := 1
|
||||
tags := []info.Tag{}
|
||||
db.ListByQ(db.Tags, bson.M{}, &tags)
|
||||
for _, eachTag := range tags {
|
||||
tagTitles := eachTag.Tags
|
||||
now := time.Now()
|
||||
if tagTitles != nil && len(tagTitles) > 0 {
|
||||
for _, tagTitle := range tagTitles {
|
||||
noteTag := info.NoteTag{}
|
||||
noteTag.TagId = bson.NewObjectId()
|
||||
noteTag.Count = 1
|
||||
noteTag.Tag = tagTitle
|
||||
noteTag.UserId = eachTag.UserId
|
||||
noteTag.CreatedTime = now
|
||||
noteTag.UpdatedTime = now
|
||||
noteTag.Usn = usnI
|
||||
noteTag.IsDeleted = false
|
||||
db.Insert(db.NoteTags, noteTag)
|
||||
usnI++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *UpgradeService) setNotebookUsn() {
|
||||
usnI := 1
|
||||
notebooks := []info.Notebook{}
|
||||
db.ListByQWithFields(db.Notebooks, bson.M{}, []string{"UserId"}, ¬ebooks)
|
||||
|
||||
for _, notebook := range notebooks {
|
||||
db.UpdateByQField(db.Notebooks, bson.M{"_id": notebook.NotebookId}, "Usn", usnI)
|
||||
usnI++
|
||||
}
|
||||
}
|
||||
|
||||
func (this *UpgradeService) setNoteUsn() {
|
||||
usnI := 1
|
||||
notes := []info.Note{}
|
||||
db.ListByQWithFields(db.Notes, bson.M{}, []string{"UserId"}, ¬es)
|
||||
|
||||
for _, note := range notes {
|
||||
db.UpdateByQField(db.Notes, bson.M{"_id": note.NoteId}, "Usn", usnI)
|
||||
usnI++
|
||||
}
|
||||
}
|
||||
|
||||
// 升级为Api, beta.4
|
||||
func (this *UpgradeService) Api(userId string) (ok bool, msg string) {
|
||||
if configService.GetGlobalStringConfig("UpgradeBetaToBeta4") != "" {
|
||||
return false, "Leanote have been upgraded"
|
||||
}
|
||||
|
||||
// user
|
||||
db.UpdateByQField(db.Users, bson.M{}, "Usn", 200000)
|
||||
|
||||
// notebook
|
||||
db.UpdateByQField(db.Notebooks, bson.M{}, "IsDeleted", false)
|
||||
this.setNotebookUsn();
|
||||
|
||||
// note
|
||||
// 1-N
|
||||
db.UpdateByQField(db.Notes, bson.M{}, "IsDeleted", false)
|
||||
this.setNoteUsn();
|
||||
|
||||
// tag
|
||||
// 1-N
|
||||
/// tag, 要重新插入, 将之前的Tag表迁移到NoteTag中
|
||||
this.moveTag();
|
||||
|
||||
configService.UpdateGlobalStringConfig(userId, "UpgradeBetaToBeta4", "1")
|
||||
|
||||
return true, ""
|
||||
}
|
||||
|
@ -12,6 +12,27 @@ import (
|
||||
type UserService struct {
|
||||
}
|
||||
|
||||
// 自增Usn
|
||||
// 每次notebook,note添加, 修改, 删除, 都要修改
|
||||
func (this *UserService) IncrUsn(userId string) int {
|
||||
user := info.User{}
|
||||
query := bson.M{"_id": bson.ObjectIdHex(userId)}
|
||||
db.GetByQWithFields(db.Users, query, []string{"Usn"}, &user)
|
||||
usn := user.Usn
|
||||
usn += 1
|
||||
Log("inc Usn")
|
||||
db.UpdateByQField(db.Users, query, "Usn", usn)
|
||||
return usn
|
||||
// return db.Update(db.Notes, bson.M{"_id": bson.ObjectIdHex(noteId)}, bson.M{"$inc": bson.M{"ReadNum": 1}})
|
||||
}
|
||||
|
||||
func (this *UserService) GetUsn(userId string) int {
|
||||
user := info.User{}
|
||||
query := bson.M{"_id": bson.ObjectIdHex(userId)}
|
||||
db.GetByQWithFields(db.Users, query, []string{"Usn"}, &user)
|
||||
return user.Usn
|
||||
}
|
||||
|
||||
// 添加用户
|
||||
func (this *UserService) AddUser(user info.User) bool {
|
||||
if user.UserId == "" {
|
||||
@ -98,6 +119,8 @@ func (this *UserService) GetUserInfo(userId string) info.User {
|
||||
func (this *UserService) GetUserInfoByEmail(email string) info.User {
|
||||
user := info.User{}
|
||||
db.GetByQ(db.Users, bson.M{"Email": email}, &user)
|
||||
// Logo路径问题, 有些有http: 有些没有
|
||||
this.setUserLogo(&user)
|
||||
return user
|
||||
}
|
||||
// 得到用户信息 username
|
||||
@ -105,6 +128,8 @@ func (this *UserService) GetUserInfoByUsername(username string) info.User {
|
||||
user := info.User{}
|
||||
username = strings.ToLower(username)
|
||||
db.GetByQ(db.Users, bson.M{"Username": username}, &user)
|
||||
// Logo路径问题, 有些有http: 有些没有
|
||||
this.setUserLogo(&user)
|
||||
return user
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user