From b65a997cc88ec9601dc9e676eb72c0af86401348 Mon Sep 17 00:00:00 2001 From: life Date: Mon, 26 Jan 2015 00:37:29 +0800 Subject: [PATCH] todo note send changes --- node_modules/api.js | 104 ++++++++++++++++++++++++++++++++- node_modules/note.js | 52 +++++++++++++++++ node_modules/notebook.js | 17 ++++++ node_modules/sync.js | 119 +++++++++++++++++++++++++++++--------- public/js/app/notebook.js | 18 +++--- 5 files changed, 274 insertions(+), 36 deletions(-) diff --git a/node_modules/api.js b/node_modules/api.js index 79c75356..ef9cc584 100644 --- a/node_modules/api.js +++ b/node_modules/api.js @@ -249,7 +249,6 @@ var Api = { callback(false); } }); - }); }, // 更新 @@ -316,6 +315,107 @@ var Api = { } catch(e) {} } }); - } + }, + + //--------- + // note + //-------- + + // 获取笔记 + getNote: function(noteId, callback) { + + }, + + // 添加 + addNote: function(note, callback) { + var me = this; + // note.NotebookId是本的, 要得到远程的 + Notebook.getServerNotebookIdByNotebookId(notebook.NotebookId, function(serverNotebookId) { + var data = { + title: note.Title, + notebookId: serverNotebookId + } + log('add note'); + log(data); + needle.post(me.getUrl('note/addNote'), data, {}, function(err, resp) { + if(err) { + return callback(false); + } + var ret = resp.body; + log(ret); + if(Common.isOk(ret)) { + callback(ret); + } else { + callback(false); + } + }); + }); + }, + // 更新 + updateNote: function(note, callback) { + var me = this; + Notebook.getServerNotebookIdByNotebookId(notebook.NotebookId, function(serverNotebookId) { + var data = { + noteId: note.ServerNoteId, + notebookId: serverNotebookId || "", + title: note.Title, + usn: note.Usn, + isTrash: note.IsTrash + } + log('update note'); + log(data); + needle.post(me.getUrl('note/updateNote'), data, {}, function(err, resp) { + if(err) { + log('err'); + log(err); + return callback(false); + } + var ret = resp.body; + log('update note ret:'); + log(ret); + if(Common.isOk(ret)) { + callback(ret); + } else { + callback(false); + } + }); + }); + }, + + // 删除 + deleteNote: function(note, callback) { + var me = this; + var data = {noteId: note.ServerNoteId, usn: note.Usn}; + log('delete notebook'); + needle.post(me.getUrl('note/deleteNote'), data, {}, function(err, resp) { + if(err) { + return callback(false); + } + var ret = resp.body; + log('delete note ret'); + log(ret); + if(Common.isOk(ret)) { + // 以后不要再发了 + Note.setNotDirty(note.NoteId); + callback(ret); + } else { + callback(false); + try { + log('delete note conflict'); + // 代表冲突了, 那么本地的删除无效, 设为IsDirty为false, 不删除 + // 待以后同步 + if(ret.Msg == 'conflict') { + log('delete note conflict: setNotDirtyNotDelete'); + Note.setNotDirtyNotDelete(note.NoteId); + } else { + log('delete note conflict: setNotDirty'); + Note.setNotDirty(note.NoteId); + } + + } catch(e) {} + } + }); + }, + }; module.exports = Api; diff --git a/node_modules/note.js b/node_modules/note.js index a7bd4333..06347a45 100644 --- a/node_modules/note.js +++ b/node_modules/note.js @@ -329,6 +329,7 @@ var Note = { }); }, + // 服务器上的数据 // 为冲突更新, note已有有NoteId, ServerNoteId, 但NotebookId是服务器端的 updateNoteForceForConflict: function(note, callback) { var me = this; @@ -391,6 +392,7 @@ var Note = { var conflictNotes = noteSyncInfo.conflicts; log('fix note conflicts'); + // 这里为什么要同步? 因为fixConflicts后要进行send changes, 这些有冲突的不能发送changes if(conflictNotes) { async.eachSeries(conflictNotes, function(note, cb) { var noteId = note.NoteId; @@ -417,6 +419,45 @@ var Note = { callback && callback(); } + // 发送改变的冲突 + // 复制一份 + // [待测] + var changeConflicts = noteSyncInfo.changeConflicts; + for(var i in changeConflicts) { + var note = changeConflicts[i]; // note是本地的note + // 复制一份 + me.copyNoteForConfict(note.NoteId, function(newNote) { + if(newNote) { + // 更新之前的, 要先从服务器上得到服务版的 + // 这里的note是本地的, 所以将服务器上的覆盖它 + if(!Api) { + Api = require('api'); + } + Api.getNote(note.ServerNoteId, function(serverNote) { + serverNote.ServerNoteId = serverNote.NoteId; + serverNote.NoteId = note.NoteId; + me.updateNoteForceForConflict(serverNote, function(err, note2) { + if(!err) { + // 前端来处理, 全量sync时不用前端一个个处理 + noteWeb && noteWeb.fixSyncConflict(note2, newNote); + } + }); + }); + } else { + } + }); + } + + // 服务器没有, 但是是发送更新的, 所以需要作为添加以后再send changes + if(noteSyncInfo.changeNeedAdds) { + var needAddNotes = noteSyncInfo.changeNeedAdds; + for(var i in needAddNotes) { + log('need add '); + var note = needAddNotes[i]; + me.setIsNew(note.NoteId); + } + } + // 处理添加的 var addNotes = noteSyncInfo.adds; log('has add...'); @@ -431,6 +472,17 @@ var Note = { // 处理删除的 noteWeb.deleteSync(noteSyncInfo.deletes); + }, + // 在send delete笔记时成功 + setNotDirty: function(noteId) { + NB.update({NoteId: noteId}, {$set:{IsDirty: false}}) + }, + // 在send delete笔记时有冲突, 设为不删除 + setNotDirtyNotDelete: function(noteId) { + NB.update({NoteId: noteId}, {$set:{IsDirty: false, LocalIsDelete: false}}) + }, + setIsNew: function(noteId) { + Notes.update({NoteId: noteId}, {$set:{LocalIsNew: true, IsDirty: true}}) } }; diff --git a/node_modules/notebook.js b/node_modules/notebook.js index 08f788f7..35219da4 100644 --- a/node_modules/notebook.js +++ b/node_modules/notebook.js @@ -257,8 +257,11 @@ var Notebook = { // 这里的notebook是服务器传过来的数据, 需要fix下, updateNotebookForce: function(notebook, notebookLocal, callback) { var me = this; + notebook.IsDirty = false; notebook.LocalIsNew = false; + notebook.LocalIsDelete = false; + var serverNotebookId = notebook.NotebookId; me.getNotebookIdByServerNotebookId(notebook.ParentNotebookId, function(parentNotebookId) { notebook.ParentNotebookId = parentNotebookId; @@ -344,15 +347,26 @@ var Notebook = { callback && callback(); }); + // 服务器没有, 但是是发送更新的, 所以需要作为添加 + if(notebookSyncInfo.changeNeedAdds) { + var needAddNotebooks = notebookSyncInfo.changeNeedAdds; + for(var i in needAddNotebooks) { + var notebook = needAddNotebooks[i]; + me.setIsNew(notebook.NotebookId); + } + } + // 处理添加的 var adds = notebookSyncInfo.adds; log('has add...'); log(adds); notebookWeb.addSync(adds); + log('has changeAdds') log(notebookSyncInfo.changeAdds) notebookWeb.addChange(notebookSyncInfo.changeAdds); + log('has updates...'); log(notebookSyncInfo); log(notebookSyncInfo.updates); @@ -370,6 +384,9 @@ var Notebook = { // 在send delete笔记时有冲突 setNotDirtyNotDelete: function(notebookId) { NB.update({NotebookId: notebookId}, {$set:{IsDirty: false, LocalIsDelete: false}}) + }, + setIsNew: function(notebookId) { + NB.update({NotebookId: notebookId}, {$set:{LocalIsNew: true, IsDirty: true}}) } }; module.exports = Notebook; \ No newline at end of file diff --git a/node_modules/sync.js b/node_modules/sync.js index 6dd0a2b8..4eac4406 100644 --- a/node_modules/sync.js +++ b/node_modules/sync.js @@ -17,8 +17,8 @@ function log(o) { var Sync = { // 同步的信息, 返回给调用者 _syncInfo: { - notebook: {changeAdds: [], adds: [], deletes: [], updates: []}, - note: {changeAdds: [], adds: [], deletes: [], updates: [], conflicts: []}, + notebook: {changeAdds: [], changeConflicts: [], adds: [], deletes: [], updates: []}, + note: {changeAdds: [], changeConflicts: [], adds: [], deletes: [], updates: [], conflicts: []}, tag: {} }, /* @@ -58,9 +58,9 @@ var Sync = { // 同步信息 me._syncInfo = { - notebook: {ok: false, changeAdds: [], adds: [], deletes: [], updates: []}, - note: {ok: false, adds: [], changeAdds: [], deletes: [], updates: [], conflicts: []}, - tag: {ok: false, adds: [], changeAdds: [], deletes: [], updates: [], conflicts: []}, + notebook: {ok: false, changeAdds: [], changeConflicts: [], changeNeedAdds: [], adds: [], deletes: [], updates: []}, + note: {ok: false, adds: [], changeAdds: [], changeConflicts: [], changeNeedAdds: [], deletes: [], updates: [], conflicts: []}, + tag: {ok: false, adds: [], changeAdds: [], changeConflicts: [], changeNeedAdds: [], deletes: [], updates: [], conflicts: []}, }; // 发送改变信息 @@ -467,8 +467,12 @@ var Sync = { // 没有更新成功 if(!newNotebook.NotebookId) { if(newNotebook.Msg == 'conflict') { + // 没用, 前端不会处理的, 按理不会出现这种情况, 因为先sync me._syncInfo.notebook.conflicts.push(newNotebook); - // me._sendInfo.notebook.conflicts.push(newNotebook); + } else if(newNotebook.Msg == 'notExists') { + // 服务器端没有, 那么要作为添加 + // 可能服务器上已删除, 此时应该要作为添加而不是更新 + me._syncInfo.notebook.changeNeedAdds.push(notebook); } } else { @@ -476,28 +480,14 @@ var Sync = { Notebook.updateNotebookForceForSendChange(notebook.NotebookId, newNotebook); if(notebook.LocalIsNew) { - newNotebook.OldNotebookId = notebook.NotebookId; - // 把之前本持的LocalNotebookId存起来 - newNotebook.LocalNotebookId = notebook.NotebookId; + // 没用 me._syncInfo.notebook.changeAdds.push(newNotebook); - // me._sendInfo.notebook.adds.push(newNotebook); } else { + // 没用 me._syncInfo.notebook.updates.push(newNotebook); - // me._sendInfo.notebook.updates.push(newNotebook); - } - } - // 如果之前都很正常 - if(!me._needIncrSyncAgain) { - // 检查是否有问题 - if(User.getLastSyncUsn() + 1 == newNotebook.Usn) { - // 更新到本地lastSyncUsn - User.updateLastSyncUsn(newNotebook.Usn); - } else { - // newNotebook.Usn > User.getLastSyncUsn + 1, 表示服务器端在本次同步后, sendChanges之前有更新 - // 那么, 还需要来一次incrSync, 之后 - me._needIncrSyncAgain = true; } } + me.checkNeedIncSyncAgain(newNotebook.Usn); cb(); }); }, function() { @@ -507,10 +497,87 @@ var Sync = { }); }, + checkNeedIncSyncAgain: function(usn) { + var me = this; + // 如果之前都很正常 + if(!me._needIncrSyncAgain) { + // 检查是否有问题 + if(User.getLastSyncUsn() + 1 == usn) { + // 更新到本地lastSyncUsn + User.updateLastSyncUsn(usn); + } else { + // newNote.Usn > User.getLastSyncUsn + 1, 表示服务器端在本次同步后, sendChanges之前有更新 + // 那么, 还需要来一次incrSync, 之后 + me._needIncrSyncAgain = true; + } + } + }, + // 发送笔记改变 - sendNoteChanges: function(callback) { - log('send note changes'); - callback && callback(); + // 发送笔记本的更改 + sendNoteChanges: function(callback) { + var me = this; + // 获取所有笔记本的更改 + Note.getDirtyNotes(function(notes) { + log('dirty notes'); + log(notes); + if(!notes) { + callback && callback(); + } else { + // 调api, 所有执行后再callback(); + // 一个一个同步执行, 因为要有 + async.eachSeries(notes, function(note, cb) { + var api = Api.updateNote; + if(note.LocalIsNew) { + api = Api.addNote; + } else if(note.LocalIsDelete) { + api = Api.deleteNote; + } + + api.call(Api, note, function(newNote) { + // 更新失败 + if(!newNote) { + return cb(); + } + + // 删除操作 + if(note.LocalIsDelete) { + return cb(); + } + + // 更新成功, 是否有冲突? + // newNote是服务器上的笔记 + // 没有更新成功, 那么要处理冲突 + if(!newNote.NoteId) { + if(newNote.Msg == 'conflict') { + me._syncInfo.note.changeConflicts.push(note); + } else if(newNote.Msg == 'notExists') { + // 可能服务器上已删除, 此时应该要作为添加而不是更新 + me._syncInfo.note.changeNeedAdds.push(note); + } + } + // 更新成功, 修改到本地 + else { + // 更新 + Note.updateNoteForceForSendChange(note.NoteId, newNote); + + if(note.LocalIsNew) { + newNote.ServerNoteId = newNote.NoteId; + newNote.NoteId = note.NoteId; + me._syncInfo.note.changeAdds.push(newNote); + } else { + me._syncInfo.note.updates.push(newNote); + } + + me.checkNeedIncSyncAgain(newNote.Usn); + } + cb(); + }); + }, function() { + callback && callback(); + }); + } + }); }, // 发送标签改变 sendTagChanges: function(callback) { diff --git a/public/js/app/notebook.js b/public/js/app/notebook.js index 804e374f..e021d118 100644 --- a/public/js/app/notebook.js +++ b/public/js/app/notebook.js @@ -787,6 +787,9 @@ Notebook.doUpdateNotebookTitle = function(notebookId, newTitle) { Notebook.renderUpdateNoteTitle = function(notebookId, newTitle) { var self = this; // 修改缓存 + if(!Notebook.cache[notebookId]) { + return; + } Notebook.cache[notebookId].Title = newTitle; // 改变nav Notebook.changeNav(); @@ -1040,13 +1043,6 @@ Notebook.addSync = function(notebooks) { // 不用做任何操作 Notebook.addChange = function(notebooks) { return; - var me = this; - if(isEmpty(notebooks)) { - return; - } - for(var i in notebooks) { - var notebook = notebooks[i]; - } }; // 更新 // 不对移动做修改, 只修改标题 @@ -1058,7 +1054,13 @@ Notebook.updateSync = function(notebooks) { log("update notebook sync"); for(var i in notebooks) { var notebook = notebooks[i]; - me.renderUpdateNoteTitle(notebook.NotebookId, notebook.Title); + // 更新可以是本笔记本删除后, 更新的服务器版 + if(me.cache[notebook.NotebookId]) { + me.renderUpdateNoteTitle(notebook.NotebookId, notebook.Title); + } else { + Notebook.setCache(notebook); + me.tree.addNodes(me.tree.getNodeByTId(notebook.ParentNotebookId), {Title: notebook.Title, NotebookId: notebook.NotebookId, IsNew: true}, true, true, false); + } } };