tag 基本ok, TODO tag sync

This commit is contained in:
life
2015-02-06 00:28:33 +08:00
parent 4f5dabe839
commit ec4e790449
7 changed files with 339 additions and 50 deletions

99
node_modules/note.js generated vendored
View File

@@ -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;

89
node_modules/tag.js generated vendored
View File

@@ -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;

28
node_modules/web.js generated vendored Normal file
View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);
});

View File

@@ -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
// 过时

View File

@@ -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('<span class="?">?<i title="' + getMsg("delete") + '">X</i></span>', classes, text);
tag = tt('<span class="?" data-tag="?">?<i title="' + getMsg("delete") + '">X</i></span>', classes, text, text);
// 避免重复
var isExists = false;
$("#tags").children().each(function() {
if (isColor) {
var tagHtml = $("<div></div>").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('<li data-tag="?"><a> <span class="?">?</span></li>', text, classes, text));
$("#tagNav").append(tt('<li data-tag="?"><a> <span class="?">? (?)</span> <span class="tag-delete">X</span></li>', tag, classes, text, noteTag.Count));
}
}
};
// 添加的标签重新render到左边, 放在第一个位置
// 重新render
Tag.addTagNav = function(newTag) {
var me = this;
for(var i in me.tags) {
var noteTag = me.tags[i];
if(noteTag.Tag == newTag.Tag) {
me.tags.splice(i, 1);
break;
}
}
me.tags.unshift(newTag);
me.renderTagNav(me.tags);
};
// 事件
$(function() {
@@ -248,7 +309,7 @@ $(function() {
Tag.appendTag({
classes : a.attr("class"),
text : a.text()
});
}, true);
});
// 这是个问题, 为什么? 捕获不了事件?, input的blur造成
/*
@@ -263,14 +324,29 @@ $(function() {
*/
$("#tags").on("click", "i", function() {
$(this).parent().remove();
reRenderTags();
Tag.removeTag($(this).parent());
});
//----------
//
function deleteTag() {
$li = $(this).closest('li');
var tag = $.trim($li.data("tag"));
if(confirm("Are you sure ?")) {
TagService.deleteTag(tag, function(re) {
// re = {NoteId => note}
if(typeof re == "object" && re.Ok !== false) {
Note.deleteNoteTag(re, tag);
$li.remove();
}
});
};
}
//-------------
// nav 标签搜索
function searchTag() {
var tag = $.trim($(this).data("tag"));
var $li = $(this).closest('li');
var tag = $.trim($li.data("tag"));
// tag = Tag.mapCn2En[tag] || tag;
// 学习changeNotebook
@@ -282,7 +358,9 @@ $(function() {
// 也会把curNoteId清空
Note.clearAll();
$("#tagSearch").html($(this).html()).show();
$("#tagSearch").html($li.html()).show();
$("#tagSearch .tag-delete").remove();
showLoading();
ajaxGet("/note/searchNoteByTags", {tags: [tag]}, function(notes) {
hideLoading();
@@ -298,6 +376,8 @@ $(function() {
}
});
}
$("#myTag .folderBody").on("click", "li", searchTag);
$("#minTagNav").on("click", "li", searchTag);
$("#myTag .folderBody").on("click", "li .label", searchTag);
// $("#minTagNav").on("click", "li", searchTag);
$("#myTag .folderBody").on("click", "li .tag-delete", deleteTag);
});