diff --git a/node_modules/note.js b/node_modules/note.js index 086871be..838f27fc 100644 --- a/node_modules/note.js +++ b/node_modules/note.js @@ -5,13 +5,15 @@ var File = require('file'); var Evt = require('evt'); var User = require('user'); var Notebook = require('notebook'); -var Tag = require('tag'); +// var Tag = require('tag'); // var Api = require('api'); var Server = require('server'); var Common = require('common'); +var Web = require('web'); var Notes = db.notes; var Api = null; // require('api') +var Tag = null; function log(o) { console.log(o); @@ -45,6 +47,7 @@ var Note = { noteOrContent.UpdatedTime = date; noteOrContent['IsDirty'] = true; // 已修改 + noteOrContent['LocalIsDelete'] = false; // 新建笔记, IsNew还是保存着 if(noteOrContent.IsNew) { @@ -63,10 +66,12 @@ var Note = { // 重新统计笔记本的笔记数量 Notebook.reCountNotebookNumberNotes(noteOrContent.NotebookId); + /* // 标签 if(noteOrContent.Tags && noteOrContent.Tags.length > 0) { Tag.addTags(noteOrContent.Tags); } + */ } }); // 更新笔记 @@ -87,25 +92,20 @@ var Note = { } if(needUpdate) { updates['IsDirty'] = true; + updates['LocalIsDelete'] = false; updates.UpdatedTime = date; // Set an existing field's value Notes.update({NoteId: noteOrContent.NoteId}, { $set: updates }, {}, function (err, numReplaced) { if(err) { - log(err); callback && callback(false); } else { callback && callback(noteOrContent); - // 标签 - if(noteOrContent.Tags && noteOrContent.Tags.length > 0) { - Tag.addTags(noteOrContent.Tags); - } } }); } } }, - // 获取笔记列表 getNotes: function(notebookId, callback) { var me = this; @@ -146,11 +146,33 @@ var Note = { } }); }, + // 彻底删除笔记, 如果有tags, 则需要更新tags's count deleteTrash: function(noteId, callback) { + var me = this; + me.getNote(noteId, function(note) { + if(note) { + note.LocalIsDelete = true; + note.IsDirty = true; + + // TODO 删除附件 + + Notes.update({_id: note._id}, {$set: {IsDirty: true, LocalIsDelete: true}}, function(err, n) { + if(n) { + // 如果有tags, 则重新更新tags' count + me.updateTagCount(note.Tags); + } + }); + } else { + callback(false); + } + }); + Notes.update({NoteId: noteId}, {$set: {IsDirty: true, LocalIsDelete: true}}, function(err, n) { if(err || !n) { callback(false); } else { + + callback(true); } }); @@ -933,6 +955,69 @@ var Note = { } } }, + + // 根据标签得到笔记数量 + countNoteByTag: function(title, callback) { + var userId = User.getCurActiveUserId(); + Notes.count({UserId: userId, LocalIsDelete: false , Tags: {$in: [title]}}, function(err, cnt) { + callback && callback(cnt); + }); + }, + // 彻底删除笔记时调用 + updateTagCount: function(tags) { + if(!tags) { + return; + } + var tagUpdate = {}; // + if(!Tag) { + Tag = require('tag'); + } + + var userId = User.getCurActiveUserId(); + for(var i in tags) { + var title = tags[i]; + (function(t) { + me.countNoteByTag(t, function(cnt) { + Tag.updateTagCount(t, cnt); + }); + })(title); + } + }, + // 删除包含title的笔记 + updateNoteToDeleteTag: function(title, callback) { + var updates = {}; // noteId => + var userId = User.getCurActiveUserId(); + console.log('updateNoteToDeleteTag--'); + Notes.find({UserId: userId, LocalIsDelete: false , Tags: {$in: [title]}}, function(err, notes) { + console.log(notes); + if(!err && notes && notes.length > 0) { + for(var i in notes) { + var note = notes[i]; + var tags = note.Tags; + // 删除之 + for(var j in tags) { + if(tags[j] == title) { + tags = tags.splice(j, 1); + break; + } + } + note.Tags = tags; + note.IsDirty = true; + updates[note.NoteId] = note; + Notes.update({_id: note._id}, {$set: {Tags: tags, IsDirty: true}}, function(err) { + console.log("??"); + console.log(err); + callback(updates); + }); + } + } else { + console.log('updateNoteToDeleteTag'); + console.log(err); + callback({}); + } + }); + + } }; module.exports = Note; \ No newline at end of file diff --git a/node_modules/tag.js b/node_modules/tag.js index 4a3eabcc..b4198d0b 100644 --- a/node_modules/tag.js +++ b/node_modules/tag.js @@ -1,18 +1,88 @@ var db = require('db'); var Common = require('common'); var User = require('user'); +var Note = require('note'); +var Web = require('web'); var Tags = db.tags; /* TagId -UserId +ServerTagId Title -NumberNotes +Usn +IsDirty CreatedTime UpdatedTime -Usn +Count 笔记数 + */ // 笔记本服务 var Tag = { + + // 添加或更新标签 + addOrUpdateTag: function(title, callback) { + var userId = User.getCurActiveUserId(); + Tags.findOne({UserId: userId, Tag: title}, function(err, tag) { + // 存在, 则更新该tag下的笔记数量 + // 已存的, 不更新IsDirty + if(!err && tag) { + Note.countNoteByTag(title, function(cnt) { + tag.Count = cnt; + Tags.update({UserId: userId, Title: title}, {$set: {Count: cnt, UpdatedTime: new Date()}}, function() { + console.log('已存在tag' + title); + callback(tag); + }); + }); + } else { + var date = new Date(); + Tags.insert({ + TagId: Common.objectId(), + UserId: userId, + Tag: title, + IsDirty: true, // 新添加的 + Count: 1, + LocalIsDelete: false, + CreatedTime: date, + UpdatedTime: date + }, function(err, doc) { + if(err) { + callback && callback({Ok: false, Inserted: false}); + } else { + callback && callback(doc); + } + }); + } + }); + }, + getTags: function(callback) { + Tags.find({UserId: User.getCurActiveUserId(), LocalIsDelete: false}, function(err, tags) { + if(err) { + callback && callback(false); + } else { + callback && callback(tags); + } + }); + }, + + // 删除标签, 更新为LocaleIsDelete = true + deleteTag: function(title, callback) { + var me = this; + Tags.update({UserId: User.getCurActiveUserId(), Tag: title}, {$set: {LocalIsDelete: true, UpdatedTime: new Date()}}, function() { + }); + // 笔记本 + Note.updateNoteToDeleteTag(title, function(updates) { + callback(updates); + }); + }, + + // 更新标签的数量, 在彻底删除笔记时调用 + updateTagCount: function(title, count) { + // 更新Tag's Count + Tags.update({UserId: userId, Tag: title}, {$set: {Count: cnt}}); + // 更新web + Web.updateTagCount({Tag: title, Count: cnt}); + }, + + /* // 添加多个标签 addTags: function(titles) { for(var i in titles) { @@ -22,7 +92,7 @@ var Tag = { }, // 添加标签, 先查询是否存在 addTag: function(title, callback) { - userId = User.getCurActiveUserId(); + var userId = User.getCurActiveUserId(); Tags.count({UserId: userId, Title: title}, function(err, count) { if(count) { callback && callback({Ok: false, IsExists: true}); @@ -56,15 +126,6 @@ var Tag = { } }); }, - // 得到标签 - getTags: function(callback) { - Tags.find({UserId: User.getCurActiveUserId()}, function(err, tags) { - if(err) { - callback && callback(false); - } else { - callback && callback(tags); - } - }); - } + */ }; module.exports = Tag; \ No newline at end of file diff --git a/node_modules/web.js b/node_modules/web.js new file mode 100644 index 00000000..8d52a5db --- /dev/null +++ b/node_modules/web.js @@ -0,0 +1,28 @@ +var fs = require('fs'); + +// noteJS端与web端的接口 +// web -> Node -> Web -> web +// 该Node相当于一个转发的接口, Node -> web +// 为什么要这样? 因为Note操作Tag, 而Note的操作由note.js引起, 这样会返回很多数据, 包括note, tags, 给前端来处理 +// 为什么不分开到各个Note, Tag nodejs中来调用Web呢? 这样避免过多的嵌套 +var Web = { + Notebook: null, + Note: null, + Tag: null, + + // 注入前端变量 + set: function(notebook, note, tag) { + var me = this; + me.Notebook = notebook; + me.Note = note; + me.Tag = tag; + }, + + // 删除笔记时, 更新左侧导航标签的count + // TODO test + updateTagCount: function(tag) { + var me = this; + me.Tag.updateTagCount(tag); + } +}; +module.exports = Web; diff --git a/public/js/app/note.js b/public/js/app/note.js index 82d16e51..29bd8c4e 100644 --- a/public/js/app/note.js +++ b/public/js/app/note.js @@ -257,10 +257,10 @@ Note.curHasChanged = function(force) { } } - if(!arrayEqual(cacheNote.Tags, tags)) { - hasChanged.hasChanged = true; - hasChanged.Tags = tags; - } + // if(!arrayEqual(cacheNote.Tags, tags)) { + hasChanged.hasChanged = true; + hasChanged.Tags = tags; + // } // 比较text, 因为note Nav会添加dom会导致content改变 if((force && cacheNote.Content != content) || (!force && (/**/(!cacheNote.IsMarkdown && $(cacheNote.Content).text() != contentText) || (cacheNote.IsMarkdown && cacheNote.Content != contentText)) /**/) ) { @@ -393,7 +393,7 @@ Note.getImgSrc = function(content) { // 定时保存传false Note.saveInProcess = {}; // noteId => bool, true表示该note正在保存到服务器, 服务器未响应 Note.savePool = {}; // 保存池, 以后的保存先放在pool中, id => note -Note.curChangedSaveIt = function(force) { +Note.curChangedSaveIt = function(force, callback) { var me = this; // 如果当前没有笔记, 不保存 if(!Note.curNoteId || Note.isReadOnly) { @@ -440,10 +440,14 @@ Note.curChangedSaveIt = function(force) { Pjax.changeNote(ret); } showMsg(getMsg("saveSuccess"), 1000); + + callback && callback(); }); return hasChanged; } + + callback && callback(); return false; }; @@ -1447,7 +1451,33 @@ Note.copyNote = function(target, data, isShared) { // 增加数量 Notebook.incrNotebookNumberNotes(notebookId) -} +}; + + +// 删除笔记标签 +// item = {noteId => usn} +Note.deleteNoteTag = function(item, tag) { + if(!item) { + return; + } + for(var noteId in item) { + var note = Note.getNote(noteId); + if(note) { + note.Tags = note.Tags || []; + for(var i in note.Tags) { + if(note.Tags[i] == tag) { + note.Tags.splice(i, 1); + continue; + } + } + // 如果当前笔记是展示的笔记, 则重新renderTags + if(noteId == Note.curNoteId) { + Tag.renderTags(note.Tags); + } + } + } +}; + // 这里速度不慢, 很快 Note.getContextNotebooks = function(notebooks) { diff --git a/public/js/app/page.js b/public/js/app/page.js index f5231d8f..c0650878 100644 --- a/public/js/app/page.js +++ b/public/js/app/page.js @@ -1314,6 +1314,9 @@ function incrSync() { // 实始化页面 // 判断是否登录 function initPage() { + // 注入前端变量 + WebService.set(Notebook, Note, Tag); + function _init() { $(function() { // 获取笔记本 @@ -1338,7 +1341,7 @@ function initPage() { } // 标签 - Service.tagService.getTags(function(tags) { + TagService.getTags(function(tags) { Tag.renderTagNav(tags); }); diff --git a/public/js/app/service.js b/public/js/app/service.js index a3710bae..d530d771 100644 --- a/public/js/app/service.js +++ b/public/js/app/service.js @@ -18,9 +18,11 @@ var SyncService = Service.syncServie; var NoteService = Service.noteService; var NotebookService = Service.notebookService; var TagService = Service.tagService; +var WebService = require('web'); var ServerService = require('server'); var FileService = require('file'); + // 分发服务 // route = /note/notebook // 过时 diff --git a/public/js/app/tag.js b/public/js/app/tag.js index 695bd7bb..3f604d08 100644 --- a/public/js/app/tag.js +++ b/public/js/app/tag.js @@ -33,8 +33,8 @@ Tag.t = $("#tags"); Tag.getTags = function() { var tags = []; Tag.t.children().each(function(){ - var text = $(this).text(); - text = text.substring(0, text.length - 1); // 把X去掉 + var text = $(this).data('tag'); + // text = text.substring(0, text.length - 1); // 把X去掉 text = Tag.mapCn2En[text] || text; tags.push(text); }); @@ -59,7 +59,7 @@ Tag.renderTags = function(tags) { var tag = tags[i]; Tag.appendTag(tag); } -} +}; // tag最初状态 function revertTagStatus() { @@ -117,7 +117,7 @@ Tag.renderReadOnlyTags = function(tags) { // 添加tag // tag = {classes:"label label-red", text:"红色"} // tag = life -Tag.appendTag = function(tag) { +Tag.appendTag = function(tag, save) { var isColor = false; var classes, text; @@ -140,21 +140,25 @@ Tag.appendTag = function(tag) { classes = "label label-default"; } } - + var rawText = text; if(LEA.locale == "zh") { text = Tag.mapEn2Cn[text] || text; + rawText = Tag.mapCn2En[rawText] || rawText; } - tag = tt('?X', classes, text); + tag = tt('?X', classes, text, text); // 避免重复 + var isExists = false; $("#tags").children().each(function() { if (isColor) { var tagHtml = $("
").append($(this).clone()).html(); if (tagHtml == tag) { $(this).remove(); + isExists = true; } } else if (text + "X" == $(this).text()) { $(this).remove(); + isExists = true; } }); @@ -167,8 +171,23 @@ Tag.appendTag = function(tag) { } // 笔记已污染 - Note.curNoteIsDirtied(); -} + if(save) { + Note.curNoteIsDirtied(); + + // 如果之前不存, 则添加之 + if(!isExists) { + Note.curChangedSaveIt(true, function() { + TagService.addOrUpdateTag(rawText, function(ret) { + console.log("---") + console.log(ret); + if(typeof ret == 'object' && ret.Ok !== false) { + Tag.addTagNav(ret); + } + }); + }); + } + } +}; // 为了颜色间隔, add, delete时调用 function reRenderTags() { @@ -184,23 +203,65 @@ function reRenderTags() { i++; } }); -} +}; + +// 删除tag +Tag.removeTag = function($target) { + var tag = $target.data('tag'); + $target.remove(); + reRenderTags(); + /* + if(LEA.locale == "zh") { + tag = Tag.mapCn2En[tag] || tag; + } + */ + Note.curChangedSaveIt(true, function() { + TagService.addOrUpdateTag(tag, function(ret) { + console.log(".."); + console.log(ret); + if(typeof ret == 'object' && ret.Ok !== false) { + Tag.addTagNav(ret); + } + }); + }); +}; //----------- // 左侧nav en -> cn +Tag.tags = []; Tag.renderTagNav = function(tags) { + var me = this; tags = tags || []; + Tag.tags = tags; + $("#tagNav").html(''); for(var i in tags) { - var tag = tags[i].Title; - if(tag == "red" || tag == "blue" || tag == "yellow" || tag == "green") { - continue; + var noteTag = tags[i]; + var tag = noteTag.Tag; + var text = tag; + /* + if(LEA.locale == "zh") { + var text = Tag.mapEn2Cn[tag] || text; } - var text = Tag.mapEn2Cn[tag] || tag; + */ var classes = Tag.classes[tag] || "label label-default"; - $("#tagNav").append(tt('