diff --git a/database/db.js b/database/db.js
index 56e9e52..5c571f3 100644
--- a/database/db.js
+++ b/database/db.js
@@ -679,6 +679,20 @@ db.getTagsBookmarks = function(bookmark_ids) {
});
}
+db.getActiveUsers = function() {
+ var sql = " (SELECT username, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_login, '%Y-%m-%d %H:%i:%s') as last_login, email FROM users ORDER BY last_login DESC LIMIT 0, 5) UNION (SELECT username, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as created_at, DATE_FORMAT(last_login, '%Y-%m-%d %H:%i:%s') as last_login, email FROM users ORDER BY created_at DESC LIMIT 0, 5)";
+ console.log('getActiveUsers', sql);
+
+ return new Promise(function(resolve, reject) {
+ client.query(sql, (err, result) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(result);
+ }
+ });
+ });
+}
db.getBookmarks = function() {
var sql = "SELECT id, snap_state FROM `bookmarks`"; // 如果是空的,那查一个不存在的就行了。
console.log('getBookmarks', sql);
diff --git a/public/scripts/controllers/bookmarks-controller.js b/public/scripts/controllers/bookmarks-controller.js
index cb9c910..0032b64 100644
--- a/public/scripts/controllers/bookmarks-controller.js
+++ b/public/scripts/controllers/bookmarks-controller.js
@@ -71,7 +71,13 @@ app.controller('bookmarksCtr', ['$scope', '$state', '$stateParams', '$filter', '
ngDialog.close(dialog);
bookmarkService.delBookmark(params)
.then((data) => {
- $("#" + bookmarkId).remove();
+ $("#" + bookmarkId).transition({
+ animation: animation(),
+ duration: 500,
+ onComplete: function() {
+ $("#" + bookmarkId).remove();
+ }
+ });
toastr.success($scope.waitDelBookmark.title + ' 书签删除成功!', "提示");
})
.catch((err) => {
diff --git a/public/scripts/controllers/edit-controller.js b/public/scripts/controllers/edit-controller.js
index 1b8c58c..fb36ac9 100644
--- a/public/scripts/controllers/edit-controller.js
+++ b/public/scripts/controllers/edit-controller.js
@@ -101,7 +101,7 @@ app.controller('editCtr', ['$scope', '$state', '$timeout', 'bookmarkService', 'p
$('.ui.modal.js-add-bookmark').modal('hide');
pubSubService.publish('EditCtr.inserBookmarsSuccess', data);
if (data.title) {
- toastr.success('[ ' + data.title + ' ] 添加成功', "提示");
+ toastr.success('[ ' + data.title + ' ] 添加成功,将自动重新更新书签!', "提示");
} else {
toastr.error('[ ' + params.title + ' ] 添加失败', "提示");
}
@@ -115,7 +115,7 @@ app.controller('editCtr', ['$scope', '$state', '$timeout', 'bookmarkService', 'p
.then((data) => {
$('.ui.modal.js-add-bookmark').modal('hide');
pubSubService.publish('EditCtr.inserBookmarsSuccess', data);
- toastr.success('[ ' + params.title + ' ] 更新成功', "提示");
+ toastr.success('[ ' + params.title + ' ] 更新成功,将自动重新更新书签!', "提示");
})
.catch((err) => {
console.log('updateBookmark err', err);
diff --git a/public/scripts/controllers/search-controller.js b/public/scripts/controllers/search-controller.js
index e1740fb..19ef82e 100644
--- a/public/scripts/controllers/search-controller.js
+++ b/public/scripts/controllers/search-controller.js
@@ -85,7 +85,13 @@ app.controller('searchCtr', ['$scope', '$state', '$stateParams', '$filter', '$wi
ngDialog.close(dialog);
bookmarkService.delBookmark(params)
.then((data) => {
- $("#" + bookmarkId).remove();
+ $("#" + bookmarkId).transition({
+ animation: animation(),
+ duration: 500,
+ onComplete: function() {
+ $("#" + bookmarkId).remove();
+ }
+ });
toastr.success($scope.waitDelBookmark.title + ' 书签删除成功!', "提示");
})
.catch((err) => {
@@ -109,7 +115,7 @@ app.controller('searchCtr', ['$scope', '$state', '$stateParams', '$filter', '$wi
}
$scope.copy = function(id, url) {
- var clipboard = new Clipboard('#searchurl'+id, {
+ var clipboard = new Clipboard('#searchurl' + id, {
text: function() {
return url;
}
@@ -208,17 +214,21 @@ app.controller('searchCtr', ['$scope', '$state', '$stateParams', '$filter', '$wi
});
}
- function transition() {
+ function animation() {
var data = ['scale', 'fade', 'fade up', 'fade down', 'fade left', 'fade right', 'horizontal flip',
'vertical flip', 'drop', 'fly left', 'fly right', 'fly up', 'fly down', 'swing left', 'swing right', 'swing up',
'swing down', 'browse', 'browse right', 'slide down', 'slide up', 'slide left', 'slide right'
];
var t = data[parseInt(Math.random() * 1000) % data.length];
+ return t;
+ }
+
+ function transition() {
var className = 'js-table-search';
$('.' + className).transition('hide');
$('.' + className).transition({
- animation: t,
+ animation: animation(),
duration: 500,
});
}
diff --git a/public/scripts/controllers/settings-controller.js b/public/scripts/controllers/settings-controller.js
index 1f2b24f..0e24ead 100644
--- a/public/scripts/controllers/settings-controller.js
+++ b/public/scripts/controllers/settings-controller.js
@@ -4,12 +4,36 @@ app.controller('settingsCtr', ['$scope', '$stateParams', '$filter', '$state', '$
$scope.passwordOrgin = "";
$scope.passwordNew1 = "";
$scope.passwordNew2 = "";
-
+ $scope.user = {};
+ $scope.tagCnt = 0;
+ $scope.bookmarkCnt = 0;
$scope.form[($stateParams && $stateParams.formIndex) || 0] = true;
$scope.changeForm = function(index) {
$scope.form = $scope.form.map(() => false);
$scope.form[index] = true;
+
+ if (index == 1) {
+ bookmarkService.userInfo({})
+ .then((data) => {
+ $scope.user = data;
+ })
+ .catch((err) => {
+ toastr.error('获取信息失败。错误信息:' + JSON.stringify(err), "错误");
+ });
+
+ bookmarkService.getTags({})
+ .then((data) => {
+ $scope.tagCnt = data.length;
+ $scope.bookmarkCnt = 0;
+ data.forEach((tag) => {
+ $scope.bookmarkCnt += tag.cnt;
+ })
+ })
+ .catch((err) => {
+ console.log('getTags err', err);
+ });
+ }
}
$scope.resetPassword = function() {
diff --git a/public/scripts/controllers/tags-controller.js b/public/scripts/controllers/tags-controller.js
index 1d57fa4..ab4c646 100644
--- a/public/scripts/controllers/tags-controller.js
+++ b/public/scripts/controllers/tags-controller.js
@@ -91,6 +91,7 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
$scope.delBookmark = function(bookmark) {
$scope.waitDelBookmark = $.extend(true, {}, bookmark); // 利用jQuery执行深度拷贝
+ console.log(JSON.stringify(bookmark));
dialog = ngDialog.open({
template: './views/dialog-del-bookmark.html',
className: 'ngdialog-theme-default',
@@ -105,7 +106,21 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
ngDialog.close(dialog);
bookmarkService.delBookmark(params)
.then((data) => {
- $("#" + bookmarkId).remove();
+ $("#" + bookmarkId).transition({
+ animation: animation(),
+ duration: 500,
+ onComplete: function() {
+ $("#" + bookmarkId).remove();
+ }
+ });
+ // 更新分类里面含有书签的数量
+ $scope.tags.forEach((t1) => {
+ $scope.waitDelBookmark.tags.forEach((t2) => {
+ if (t1.id == t2.id) {
+ t1.cnt--;
+ }
+ })
+ })
toastr.success($scope.waitDelBookmark.title + ' 书签删除成功!', "提示");
})
.catch((err) => {
@@ -150,7 +165,17 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
if (!$scope.editMode) {
getTags({});
} else {
+ $('.js-edit').transition('hide'); // 没装完逼之前,不允许切换编辑模式,否则动画模式乱了。
$('.js-tags-table').transition('hide');
+ $('.stackable.cards .card').transition('hide');
+ $('.stackable.cards .card').transition({
+ animation: animation(),
+ reverse: 'auto', // default setting
+ interval: 50,
+ onComplete: function() {
+ $('.js-edit').transition('show');
+ }
+ });
}
updateEditPos();
}
@@ -200,7 +225,6 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
}
$scope.confirmDelTag = function(tagId, tagName) {
- console.log(tagId);
ngDialog.close(dialog);
var params = {
del: tagName == '未分类' ? false : true,
@@ -209,8 +233,25 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
bookmarkService.delTag(params)
.then((data) => {
if (data.retCode == 0) {
- toastr.success('[ ' + tagName + ' ]分类删除成功!将自动更新分类信息', "提示");
- getTags({});
+ toastr.success('[ ' + tagName + ' ]分类删除成功!', "提示");
+ var index = -1;
+ $scope.tags.forEach((tag, i) => {
+ if (tag.id == tagId) {
+ index = i;
+ }
+ })
+ if (index !== -1) {
+ $("#tag" + tagId).transition({
+ animation: animation(),
+ duration: 500,
+ onComplete: function() {
+ $("#tag" + tagId).remove();
+ $scope.tags.splice(index, 1);
+ }
+ });
+ } else {
+ getTags({});
+ }
} else {
toastr.error('[ ' + tagName + ' ]分类删除失败!', "提示");
getTags({});
@@ -386,17 +427,21 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
}
}
- function transition() {
+ function animation() {
var data = ['scale', 'fade', 'fade up', 'fade down', 'fade left', 'fade right', 'horizontal flip',
'vertical flip', 'drop', 'fly left', 'fly right', 'fly up', 'fly down', 'swing left', 'swing right', 'swing up',
'swing down', 'browse', 'browse right', 'slide down', 'slide up', 'slide left', 'slide right'
];
var t = data[parseInt(Math.random() * 1000) % data.length];
+ return t;
+ }
+
+ function transition() {
var className = 'js-tags-table';
$('.' + className).transition('hide');
$('.' + className).transition({
- animation: t,
+ animation: animation(),
duration: 500,
});
}
diff --git a/public/scripts/services/bookmark-service.js b/public/scripts/services/bookmark-service.js
index ea9865a..aca1d75 100644
--- a/public/scripts/services/bookmark-service.js
+++ b/public/scripts/services/bookmark-service.js
@@ -90,6 +90,19 @@ app.factory('bookmarkService', ['$http', '$q', function($http, $q) {
});
return def.promise;
},
+ userInfo: function(params) {
+ var def = $q.defer();
+ $http.get('/api/userInfo/', {
+ params: params
+ })
+ .success(function(data) {
+ def.resolve(data);
+ })
+ .error(function(data) {
+ def.reject('userInfo error');
+ });
+ return def.promise;
+ },
/**
* @func
* @desc 根据显示页数的索引,获取书签的数据
diff --git a/public/views/settings.html b/public/views/settings.html
index 428b59c..66ea704 100644
--- a/public/views/settings.html
+++ b/public/views/settings.html
@@ -28,9 +28,59 @@
-
+
+
+
{{user.created_at.substring(0, 4)}}
+ {{user.created_at.substring(5, 10)}}
+
+
注册时间
+
+
+
+
{{user.last_login.substring(0, 4)}}
+ {{user.last_login.substring(5, 10)}}
+
+
最近登陆
+
+
+
+
+
+ {{ tagCnt }}
+
+
分类数目
+
+
+
+
+ {{ bookmarkCnt }}
+
+
书签数目
+
+
+
+
+
+ |
+ 用户活跃度排名
+ |
+
+
+ | 用户名 |
+ 邮箱 |
+ 注册时间 |
+ 最后登陆 |
+
+
+
+
+ | {{ activeUser.username }} |
+ {{ activeUser.email }} |
+ {{ activeUser.created_at }} |
+ {{ activeUser.last_login }} |
+
+
+
-
-
-
每个浏览器上面都会有个书签可以供你收藏你以后可能还要用到的网址。但是这个书签有以下几个缺点我没法忍受(由于浏览器我只用Google Chrome,下面的观点我都是基于该浏览器):
-
1、各个浏览器之间无法同步。
-
2、容易丢失。因为这个东西是不强制注册账号的,你只要一重装电脑忘记备份了,你的书签就没有了。还有一个,如果你使用Chrome浏览器,由于Google被ZF封杀,你要是不翻墙,书签是没法同步的。
-
3、搜索不方便,只能搜索关键字,无法按照特定条件,比如搜索特定的加入时间,特定的类型搜索。
-
4、查阅不方便。一旦一个分类目录你收藏的过多,尼玛你在那个目录下面找起来想死的心都有。
-
5、无法查看别人收藏的书签。
-
6、在别人的电脑上无法查看我收藏的书签。
-
7、如果公用一台电脑,那么收藏夹里面会收藏其他人的网址。
-
PS:注册在登录界面的右下角。
-
-
1、需要注册账号用户。(初步完成)
-
2、网站展示有三种展示方式:导航,列表,卡片。其中导航以分类展示,分类顺序可以在书签分类下面拖动编辑。按照点击的次数从高到低在每个分类里面提取16个书签,再按照最近添加的书签提取前面的16个书签,然后合并起来。列表以表格展示,显示书签详细类容,按照点击次数优先显示,点击次数相同,则按添加顺序优先。卡片以卡片方式显示,按照最近添加优先显示。(完成)
-
3、在书签分类里面,可以更新分类,删除分类,新增分类,对分类显示进行排序。(完成)
-
4、可以按照指定添加时间段,指定分类目录,指定网址关键字等进行查询。(完成)
-
5、添加书签的时候,会自动获取title,供用户编辑。(完成)
-
6、可以导入Chrome的书签导出文件,暂时做在设置里面。(完成)
-
7、书签可以作为公有或者私有,公有可供所有人搜索。(暂时可以通过用户名进行搜索,待优化)
-
8、可以将搜索到其他用户的书签转存为自己的书签。(已完成)
-
9、可以将书签导出来,然后导入到浏览器。(未完成)
-
-
微信跟扣扣:530485521,记得备注加:书签。
-
-
1、该代码我托管在Github上my-bookmark。git地址:git@github.com:luchenqun/my-bookmark.git。我不做Web开发,这玩意儿主要是我自己用Chrome浏览器收藏网址不好用而写的。如果你需要源码,你尽可随意使用此项目无需通知我。
-
2、使用到的东西有:NodeJS(做后台) + Express(做Web框架) + AngularJS(有了这个就不要用jQuery了) + Semantic UI(有了这个,界面不会太丑) + MySql(做后台数据库) + MongoDb(做session)。对了,用到的sql表,在schema.sql里面。
-
PS:暂时还没有README.md文件,等整理完公司的一个项目,会添加!
-
+
+
+
+
+
每个浏览器上面都会有个书签可以供你收藏你以后可能还要用到的网址。但是这个书签有以下几个缺点我没法忍受(由于浏览器我只用Google Chrome,下面的观点我都是基于该浏览器):
+
1、各个浏览器之间无法同步。
+
2、容易丢失。因为这个东西是不强制注册账号的,你只要一重装电脑忘记备份了,你的书签就没有了。还有一个,如果你使用Chrome浏览器,由于Google被ZF封杀,你要是不翻墙,书签是没法同步的。
+
3、搜索不方便,只能搜索关键字,无法按照特定条件,比如搜索特定的加入时间,特定的类型搜索。
+
4、查阅不方便。一旦一个分类目录你收藏的过多,尼玛你在那个目录下面找起来想死的心都有。
+
5、无法查看别人收藏的书签。
+
6、在别人的电脑上无法查看我收藏的书签。
+
7、如果公用一台电脑,那么收藏夹里面会收藏其他人的网址。
+
PS:注册在登录界面的右下角。
+
+
1、需要注册账号用户。(初步完成)
+
2、网站展示有三种展示方式:导航,列表,卡片。其中导航以分类展示,分类顺序可以在书签分类下面拖动编辑。按照点击的次数从高到低在每个分类里面提取16个书签,再按照最近添加的书签提取前面的16个书签,然后合并起来。列表以表格展示,显示书签详细类容,按照点击次数优先显示,点击次数相同,则按添加顺序优先。卡片以卡片方式显示,按照最近添加优先显示。(完成)
+
3、在书签分类里面,可以更新分类,删除分类,新增分类,对分类显示进行排序。(完成)
+
4、可以按照指定添加时间段,指定分类目录,指定网址关键字等进行查询。(完成)
+
5、添加书签的时候,会自动获取title,供用户编辑。(完成)
+
6、可以导入Chrome的书签导出文件,暂时做在设置里面。(完成)
+
7、书签可以作为公有或者私有,公有可供所有人搜索。(暂时可以通过用户名进行搜索,待优化)
+
8、可以将搜索到其他用户的书签转存为自己的书签。(已完成)
+
9、可以将书签导出来,然后导入到浏览器。(未完成)
+
+
微信跟扣扣:530485521,记得备注加:书签。
+
+
1、该代码我托管在Github上my-bookmark。git地址:git@github.com:luchenqun/my-bookmark.git。我不做Web开发,这玩意儿主要是我自己用Chrome浏览器收藏网址不好用而写的。如果你需要源码,你尽可随意使用此项目无需通知我。
+
2、使用到的东西有:NodeJS(做后台) + Express(做Web框架) + AngularJS(有了这个就不要用jQuery了) + Semantic UI(有了这个,界面不会太丑) + MySql(做后台数据库) + MongoDb(做session)。对了,用到的sql表,在schema.sql里面。
+
PS:暂时还没有README.md文件,等整理完公司的一个项目,会添加!
+
diff --git a/public/views/tags.html b/public/views/tags.html
index 79cd8b0..bc86439 100644
--- a/public/views/tags.html
+++ b/public/views/tags.html
@@ -1,9 +1,10 @@