完成书签分类编辑
This commit is contained in:
parent
d390bc4387
commit
1bfdd28428
|
|
@ -153,6 +153,58 @@ db.delBookmarkTags = function(bookmard_id) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.getBookmarkIdsByTagId = function(tagId) {
|
||||||
|
var sql = "SELECT bookmark_id FROM `tags_bookmarks` WHERE `tag_id` = '" + tagId + "'";
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
client.query(sql, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
db.delTag = function(tagId) {
|
||||||
|
var sql = "DELETE FROM `tags` WHERE (`id`='" + tagId + "')";
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
client.query(sql, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(result.affectedRows);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
db.delTagBookmarks = function(tagId) {
|
||||||
|
var sql = "DELETE FROM `tags_bookmarks` WHERE (`tag_id`='" + tagId + "')";
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
client.query(sql, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(result.affectedRows);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
db.delBookmarks = function(bookmarkIds) {
|
||||||
|
var sql = "DELETE FROM `bookmarks` WHERE id IN (" + (bookmarkIds.toString() || ("-1")) + ")";
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
client.query(sql, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(result.affectedRows);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
db.addTagsBookmarks = function(tags, bookmard_id) {
|
db.addTagsBookmarks = function(tags, bookmard_id) {
|
||||||
sql = "INSERT INTO `tags_bookmarks` (`tag_id`, `bookmark_id`) VALUES";
|
sql = "INSERT INTO `tags_bookmarks` (`tag_id`, `bookmark_id`) VALUES";
|
||||||
for (var i = 0; i < tags.length; i++) {
|
for (var i = 0; i < tags.length; i++) {
|
||||||
|
|
@ -312,8 +364,8 @@ db.getTags = function(user_id) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
db.updateTag = function(tag) {
|
db.updateTagName = function(tag) {
|
||||||
console.log('updateTag');
|
console.log('updateTagName');
|
||||||
var sql = "UPDATE `tags` SET `name`='" + tag.name + "' WHERE (`id`='" + tag.id + "')";
|
var sql = "UPDATE `tags` SET `name`='" + tag.name + "' WHERE (`id`='" + tag.id + "')";
|
||||||
console.log(sql);
|
console.log(sql);
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
|
@ -327,6 +379,27 @@ db.updateTag = function(tag) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
db.updateTagsIndex = function(tagsIndex) {
|
||||||
|
console.log('updateTagsIndex');
|
||||||
|
var sql = "UPDATE tags SET sort = CASE id ";
|
||||||
|
tagsIndex.forEach((tagIndex) => {
|
||||||
|
sql += "WHEN " + tagIndex.id + " THEN " + tagIndex.index + " ";
|
||||||
|
})
|
||||||
|
var tagsId = tagsIndex.map((item) => item.id);
|
||||||
|
sql += "END WHERE id IN (" + tagsId.toString() + ")";
|
||||||
|
|
||||||
|
console.log(sql);
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
client.query(sql, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(result.affectedRows);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
db.getTagsByIds = function(tagIds) {
|
db.getTagsByIds = function(tagIds) {
|
||||||
var sql = "SELECT * FROM `tags` WHERE id in(" + (tagIds.toString() || ("-1")) + ") GROUP BY id"; // 如果是空的,那查一个不存在的就行了。
|
var sql = "SELECT * FROM `tags` WHERE id in(" + (tagIds.toString() || ("-1")) + ") GROUP BY id"; // 如果是空的,那查一个不存在的就行了。
|
||||||
console.log('db getTagsByIds = ', sql);
|
console.log('db getTagsByIds = ', sql);
|
||||||
|
|
@ -417,7 +490,7 @@ db.getBookmarksNavigate = function(tags) {
|
||||||
if (index >= 1) {
|
if (index >= 1) {
|
||||||
sql += " UNION "
|
sql += " UNION "
|
||||||
}
|
}
|
||||||
sql += "(SELECT * FROM ((SELECT t.id AS tag_id, t.`name` as tag_name, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.click_count DESC LIMIT 0, 16) UNION (SELECT t.id AS tag_id, t.`name` as tag_name, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.created_at DESC LIMIT 0, 16)) as " + t + " ORDER BY " + t + ".click_count DESC, " + t + ".created_at DESC)";
|
sql += "(SELECT * FROM ((SELECT t.id AS tag_id, t.`name` as tag_name, t.sort, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.click_count DESC LIMIT 0, 16) UNION (SELECT t.id AS tag_id, t.`name` as tag_name, t.sort, b.* FROM `tags` as t, `bookmarks`as b, `tags_bookmarks` as tb WHERE t.id = tb.tag_id AND b.id = tb.bookmark_id AND t.id = " + tag.id + " ORDER BY b.created_at DESC LIMIT 0, 16)) as " + t + " ORDER BY " + t + ".click_count DESC, " + t + ".created_at DESC)";
|
||||||
})
|
})
|
||||||
console.log(sql);
|
console.log(sql);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
@keyframes ngdialog-flyin {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ngdialog-flyout {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-40px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default {
|
||||||
|
padding-bottom: 160px;
|
||||||
|
padding-top: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default.ngdialog-closing .ngdialog-content {
|
||||||
|
animation: ngdialog-flyout .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-content {
|
||||||
|
animation: ngdialog-flyin .5s;
|
||||||
|
background: #f0f0f0;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #444;
|
||||||
|
font-family: 'Helvetica',sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
line-height: 1.5em;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 1em;
|
||||||
|
position: relative;
|
||||||
|
width: 450px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-close {
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-close:before {
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #bbb;
|
||||||
|
content: '\00D7';
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 400;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 26px;
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
text-align: center;
|
||||||
|
top: 3px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-close:hover:before,.ngdialog.ngdialog-theme-default .ngdialog-close:active:before {
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-message {
|
||||||
|
margin-bottom: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-input {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-input textarea,.ngdialog.ngdialog-theme-default .ngdialog-input input[type="text"],.ngdialog.ngdialog-theme-default .ngdialog-input input[type="password"],.ngdialog.ngdialog-theme-default .ngdialog-input input[type="email"],.ngdialog.ngdialog-theme-default .ngdialog-input input[type="url"] {
|
||||||
|
background: #fff;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
margin: 0 0 .25em;
|
||||||
|
min-height: 2.5em;
|
||||||
|
padding: .25em .67em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-input textarea:focus,.ngdialog.ngdialog-theme-default .ngdialog-input input[type="text"]:focus,.ngdialog.ngdialog-theme-default .ngdialog-input input[type="password"]:focus,.ngdialog.ngdialog-theme-default .ngdialog-input input[type="email"]:focus,.ngdialog.ngdialog-theme-default .ngdialog-input input[type="url"]:focus {
|
||||||
|
box-shadow: inset 0 0 0 2px #8dbdf1;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-buttons {
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-buttons:after {
|
||||||
|
content: '';
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-button {
|
||||||
|
border: 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
float: right;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: .8em;
|
||||||
|
letter-spacing: .1em;
|
||||||
|
line-height: 1em;
|
||||||
|
margin: 0 0 0 .5em;
|
||||||
|
padding: .75em 2em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-button:focus {
|
||||||
|
animation: ngdialog-pulse 1.1s infinite;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 568px) {
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-button:focus {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-button.ngdialog-button-primary {
|
||||||
|
background: #3288e6;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-default .ngdialog-button.ngdialog-button-secondary {
|
||||||
|
background: #e0e0e0;
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
.ngdialog.ngdialog-theme-plain {
|
||||||
|
padding-bottom: 160px;
|
||||||
|
padding-top: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-content {
|
||||||
|
background: #fff;
|
||||||
|
color: #444;
|
||||||
|
font-family: 'Helvetica Neue',sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
line-height: 1.5em;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 1em;
|
||||||
|
position: relative;
|
||||||
|
width: 450px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-content h1,.ngdialog.ngdialog-theme-plain .ngdialog-content h2,.ngdialog.ngdialog-theme-plain .ngdialog-content h3,.ngdialog.ngdialog-theme-plain .ngdialog-content h4,.ngdialog.ngdialog-theme-plain .ngdialog-content h5,.ngdialog.ngdialog-theme-plain .ngdialog-content h6,.ngdialog.ngdialog-theme-plain .ngdialog-content p,.ngdialog.ngdialog-theme-plain .ngdialog-content ul,.ngdialog.ngdialog-theme-plain .ngdialog-content li {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-close {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-close:before {
|
||||||
|
background: transparent;
|
||||||
|
color: #bbb;
|
||||||
|
content: "\00D7";
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 400;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 26px;
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
text-align: center;
|
||||||
|
top: 3px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-close:hover:before,.ngdialog.ngdialog-theme-plain .ngdialog-close:active:before {
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-message {
|
||||||
|
margin-bottom: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-input {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-input textarea,.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="text"],.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="password"],.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="email"],.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="url"] {
|
||||||
|
background: #f0f0f0;
|
||||||
|
border: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
margin: 0 0 .25em;
|
||||||
|
min-height: 2.5em;
|
||||||
|
padding: .25em .67em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-input textarea:focus,.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="text"]:focus,.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="password"]:focus,.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="email"]:focus,.ngdialog.ngdialog-theme-plain .ngdialog-input input[type="url"]:focus {
|
||||||
|
box-shadow: inset 0 0 0 2px rgba(0,0,0,0.2);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-buttons:after {
|
||||||
|
clear: both;
|
||||||
|
content: '';
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-button {
|
||||||
|
border: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
float: right;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: .8em;
|
||||||
|
letter-spacing: .1em;
|
||||||
|
line-height: 1em;
|
||||||
|
margin: 0 0 0 .5em;
|
||||||
|
padding: .75em 2em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-button:focus {
|
||||||
|
animation: ngdialog-pulse 1.1s infinite;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 568px) {
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-button:focus {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-button.ngdialog-button-primary {
|
||||||
|
background: #3288e6;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-theme-plain .ngdialog-button.ngdialog-button-secondary {
|
||||||
|
background: #e0e0e0;
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
@keyframes ngdialog-fadeout {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ngdialog-fadein {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog *,
|
||||||
|
.ngdialog *:before,
|
||||||
|
.ngdialog *:after {
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog {
|
||||||
|
position: fixed;
|
||||||
|
overflow: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
z-index: 10000;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-disabled-animation,
|
||||||
|
.ngdialog.ngdialog-disabled-animation .ngdialog-overlay,
|
||||||
|
.ngdialog.ngdialog-disabled-animation .ngdialog-content {
|
||||||
|
animation: none!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog-overlay {
|
||||||
|
position: fixed;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
animation: ngdialog-fadein 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog-no-overlay {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-closing .ngdialog-overlay {
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
animation: ngdialog-fadeout 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog-content {
|
||||||
|
background: white;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
animation: ngdialog-fadein 0.5s;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog.ngdialog-closing .ngdialog-content {
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
animation: ngdialog-fadeout 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngdialog-close:before {
|
||||||
|
font-family: 'Helvetica', Arial, sans-serif;
|
||||||
|
content: '\00D7';
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.ngdialog-open,
|
||||||
|
body.ngdialog-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
@ -54,7 +54,7 @@ code {
|
||||||
-o-text-overflow: ellipsis;
|
-o-text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: #212121;
|
color: #212121;
|
||||||
cursor: move;
|
cursor: default;
|
||||||
border: 1px dashed #3388FF;
|
border: 1px dashed #3388FF;
|
||||||
}
|
}
|
||||||
.img-fixed-size {
|
.img-fixed-size {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@
|
||||||
<link href="/css/externe/toastr.min.css" rel="stylesheet"/>
|
<link href="/css/externe/toastr.min.css" rel="stylesheet"/>
|
||||||
<link href="/css/style.css " rel="stylesheet"/>
|
<link href="/css/style.css " rel="stylesheet"/>
|
||||||
<link href="/css/externe/uploadfile.css" rel="stylesheet">
|
<link href="/css/externe/uploadfile.css" rel="stylesheet">
|
||||||
|
<link href="/css/externe/ngDialog.css" rel="stylesheet">
|
||||||
|
<link href="/css/externe/ngDialog-theme-default.css" rel="stylesheet">
|
||||||
|
<link href="/css/externe/ngDialog-theme-plain.css" rel="stylesheet">
|
||||||
<base href="/">
|
<base href="/">
|
||||||
</head>
|
</head>
|
||||||
<body ng-app="bookmarkApp">
|
<body ng-app="bookmarkApp">
|
||||||
|
|
@ -61,5 +64,7 @@
|
||||||
<script src="/scripts/externe/calendar.min.js"></script>
|
<script src="/scripts/externe/calendar.min.js"></script>
|
||||||
<script src="/scripts/externe/jquery.uploadfile.min.js"></script>
|
<script src="/scripts/externe/jquery.uploadfile.min.js"></script>
|
||||||
<script src="/scripts/externe/ng-infinite-scroll.min.js"></script>
|
<script src="/scripts/externe/ng-infinite-scroll.min.js"></script>
|
||||||
|
<script src="/scripts/externe/angular-sortable-view.min.js"></script>
|
||||||
|
<script src="/scripts/externe/ngDialog.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
var app = angular.module('bookmarkApp', ['ui.router', 'ngCookies', 'infinite-scroll']);
|
var app = angular.module('bookmarkApp', ['ui.router', 'ngCookies', 'infinite-scroll', 'angular-sortable-view', 'ngDialog']);
|
||||||
|
|
||||||
app.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
|
app.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
|
||||||
$httpProvider.interceptors.push('httpInterceptor');
|
$httpProvider.interceptors.push('httpInterceptor');
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$timeout', 'bookmarkService', 'pubSubService', function($scope, $filter, $window, $stateParams, $timeout, bookmarkService, pubSubService) {
|
app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$timeout', 'ngDialog', 'bookmarkService', 'pubSubService', function($scope, $filter, $window, $stateParams, $timeout, ngDialog, bookmarkService, pubSubService) {
|
||||||
console.log("Hello tagsCtr...", $stateParams);
|
console.log("Hello tagsCtr...", $stateParams);
|
||||||
getTags({});
|
getTags({});
|
||||||
|
|
||||||
const perPageItems = 20;
|
const perPageItems = 20;
|
||||||
|
var dialog = null;
|
||||||
$scope.loadBookmarks = false;
|
$scope.loadBookmarks = false;
|
||||||
$scope.tags = []; // 书签数据
|
$scope.tags = []; // 书签数据
|
||||||
|
$scope.tagsIndex = []; // 书签索引
|
||||||
$scope.bookmarkClicked = false;
|
$scope.bookmarkClicked = false;
|
||||||
$scope.bookmarks = [];
|
$scope.bookmarks = [];
|
||||||
$scope.bookmarkCount = 0;
|
$scope.bookmarkCount = 0;
|
||||||
|
|
@ -13,6 +15,7 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
|
||||||
$scope.inputPage = '';
|
$scope.inputPage = '';
|
||||||
$scope.currentTagId = ($stateParams && $stateParams.tagId) || '';
|
$scope.currentTagId = ($stateParams && $stateParams.tagId) || '';
|
||||||
$scope.edit = false;
|
$scope.edit = false;
|
||||||
|
$scope.waitDelTag = {};
|
||||||
|
|
||||||
pubSubService.subscribe('MenuCtr.tags', $scope, function(event, data) {
|
pubSubService.subscribe('MenuCtr.tags', $scope, function(event, data) {
|
||||||
console.log('subscribe MenuCtr.tags', data);
|
console.log('subscribe MenuCtr.tags', data);
|
||||||
|
|
@ -136,7 +139,7 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
|
||||||
name: tag.name,
|
name: tag.name,
|
||||||
}
|
}
|
||||||
|
|
||||||
bookmarkService.updateTag(params)
|
bookmarkService.updateTagName(params)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.retCode == 0) {
|
if (data.retCode == 0) {
|
||||||
toastr.success(tag.name + ' 更新成功!', "提示");
|
toastr.success(tag.name + ' 更新成功!', "提示");
|
||||||
|
|
@ -152,10 +155,36 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.delTag = function(tag) {
|
$scope.delTag = function(tag) {
|
||||||
if (tag.name == "未分类") {
|
console.log('delTag..........')
|
||||||
toastr.warning('这个是系统默认分类,暂时不允许删除!', "警告");
|
$scope.waitDelTag = $.extend(true, {}, tag); // 利用jQuery执行深度拷贝
|
||||||
return;
|
dialog = ngDialog.open({
|
||||||
|
template: './views/dialog-del-tag.html',
|
||||||
|
className: 'ngdialog-theme-default',
|
||||||
|
scope: $scope
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.confirmDelTag = function(tagId, tagName) {
|
||||||
|
console.log(tagId);
|
||||||
|
ngDialog.close(dialog);
|
||||||
|
var params = {
|
||||||
|
del: tagName == '未分类' ? false : true,
|
||||||
|
id: tagId,
|
||||||
|
}
|
||||||
|
bookmarkService.delTag(params)
|
||||||
|
.then((data) => {
|
||||||
|
if (data.retCode == 0) {
|
||||||
|
toastr.success('分类删除成功!将自动更新分类信息', "提示");
|
||||||
|
getTags({});
|
||||||
|
} else {
|
||||||
|
toastr.error('分类删除失败!', "提示");
|
||||||
|
getTags({});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
toastr.error('分类删除失败!错误提示:' + JSON.stringify(err), "提示");
|
||||||
|
getTags({});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.backTag = function(tag) {
|
$scope.backTag = function(tag) {
|
||||||
|
|
@ -163,16 +192,63 @@ app.controller('tagsCtr', ['$scope', '$filter', '$window', '$stateParams', '$tim
|
||||||
tag.name = tag.oldName;
|
tag.name = tag.oldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.storeTagIndex = function() {
|
||||||
|
$scope.tagsIndex = [];
|
||||||
|
$scope.tags.forEach((tag, index) => {
|
||||||
|
$scope.tagsIndex[index] = {
|
||||||
|
id: tag.id,
|
||||||
|
index: index,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log('storeTagIndex');
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.updateTagIndex = function() {
|
||||||
|
// 要开个timer,因为释放鼠标模型还没更新
|
||||||
|
setTimeout(function() {
|
||||||
|
var needUpdate = false;
|
||||||
|
for (var i = 0; i < $scope.tags.length; i++) {
|
||||||
|
if ($scope.tags[i].id != $scope.tagsIndex[i].id) {
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
$scope.tagsIndex[i] = {
|
||||||
|
id: $scope.tags[i].id,
|
||||||
|
index: i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needUpdate) {
|
||||||
|
bookmarkService.updateTagsIndex($scope.tagsIndex)
|
||||||
|
.then((data) => {
|
||||||
|
if (data.retCode == 0) {
|
||||||
|
toastr.success('分类排序更新成功!', "提示");
|
||||||
|
} else {
|
||||||
|
toastr.error('分类排序更新失败!', "提示");
|
||||||
|
getTags({});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
toastr.error('分类排序更新失败!错误提示:' + JSON.stringify(err), "提示");
|
||||||
|
getTags({});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log('updateTagIndex needUpdate = ' + needUpdate)
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
function getTags(params) {
|
function getTags(params) {
|
||||||
bookmarkService.getTags(params)
|
bookmarkService.getTags(params)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
$scope.tags = []
|
$scope.tags = []
|
||||||
|
var find = false;
|
||||||
data.forEach((tag) => {
|
data.forEach((tag) => {
|
||||||
tag.edit = false;
|
tag.edit = false;
|
||||||
tag.oldName = tag.name;
|
tag.oldName = tag.name;
|
||||||
$scope.tags.push(tag);
|
$scope.tags.push(tag);
|
||||||
|
if (tag.id == $scope.currentTagId) {
|
||||||
|
find = true; // 如果是删了分类返回来,那么要重新默认选中第一个分类
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
if (!find) $scope.currentTagId = null;
|
||||||
if (!$scope.currentTagId && $scope.tags.length > 0) {
|
if (!$scope.currentTagId && $scope.tags.length > 0) {
|
||||||
$scope.currentTagId = $scope.tags[0].id;
|
$scope.currentTagId = $scope.tags[0].id;
|
||||||
$scope.tags[0].bookmarkClicked = true;
|
$scope.tags[0].bookmarkClicked = true;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -221,16 +221,42 @@ app.factory('bookmarkService', ['$http', '$q', function($http, $q) {
|
||||||
});
|
});
|
||||||
return def.promise;
|
return def.promise;
|
||||||
},
|
},
|
||||||
updateTag: function(params) {
|
updateTagName: function(params) {
|
||||||
var def = $q.defer();
|
var def = $q.defer();
|
||||||
$http.post('/api/updateTag/', {
|
$http.post('/api/updateTagName/', {
|
||||||
params: params
|
params: params
|
||||||
})
|
})
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
def.resolve(data);
|
def.resolve(data);
|
||||||
})
|
})
|
||||||
.error(function(data) {
|
.error(function(data) {
|
||||||
def.reject('updateTag error');
|
def.reject('updateTagName error');
|
||||||
|
});
|
||||||
|
return def.promise;
|
||||||
|
},
|
||||||
|
updateTagsIndex: function(params) {
|
||||||
|
var def = $q.defer();
|
||||||
|
$http.post('/api/updateTagsIndex/', {
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
.success(function(data) {
|
||||||
|
def.resolve(data);
|
||||||
|
})
|
||||||
|
.error(function(data) {
|
||||||
|
def.reject('updateTagsIndex error');
|
||||||
|
});
|
||||||
|
return def.promise;
|
||||||
|
},
|
||||||
|
delTag: function(params) {
|
||||||
|
var def = $q.defer();
|
||||||
|
$http.post('/api/delTag/', {
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
.success(function(data) {
|
||||||
|
def.resolve(data);
|
||||||
|
})
|
||||||
|
.error(function(data) {
|
||||||
|
def.reject('delTag error');
|
||||||
});
|
});
|
||||||
return def.promise;
|
return def.promise;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h3>删除提示</h3>
|
||||||
|
<p ng-show="ngDialogId">您确认要删除分类:
|
||||||
|
<code>{{ waitDelTag.name }}</code>吗?
|
||||||
|
</p>
|
||||||
|
<p>如果删除该分类,那么该分类下的所有书签都会删掉哦!</p>
|
||||||
|
<p ng-show="waitDelTag.name == '未分类'">
|
||||||
|
<code>未分类</code>为系统默认分类,只允许删除该分类下面的书签,不允许删除该分类信息</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-primary" ng-click="confirmDelTag(waitDelTag.id, waitDelTag.name)">确定删除</button>
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-secondary" ng-click="closeThisDialog('button')">取消</button>
|
||||||
|
</div>
|
||||||
|
|
@ -9,10 +9,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui container" ng-show="edit">
|
<div class="ui container" ng-show="edit" ng-mousedown="storeTagIndex()" ng-mouseup="updateTagIndex()">
|
||||||
<p>操作说明:拖拽分类即可进行排序(正在开发中...)</p>
|
<p>操作说明:拖拽分类即可进行排序(正在开发中...)</p>
|
||||||
<div class="ui six stackable cards">
|
<div class="ui six stackable cards" sv-root sv-part="tags">
|
||||||
<div class="card" ng-repeat="tag in tags">
|
<div class="card" ng-repeat="tag in tags" sv-element>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="header" ng-if="!tag.edit">{{ tag.name }}</div>
|
<div class="header" ng-if="!tag.edit">{{ tag.name }}</div>
|
||||||
<div class="ui large fluid transparent input" style="height:19px;" ng-if="tag.edit">
|
<div class="ui large fluid transparent input" style="height:19px;" ng-if="tag.edit">
|
||||||
|
|
@ -21,9 +21,9 @@
|
||||||
<i class="mail forward icon" style="cursor:pointer;" ng-click="backTag(tag)" title="放弃更新"></i>
|
<i class="mail forward icon" style="cursor:pointer;" ng-click="backTag(tag)" title="放弃更新"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" style="cursor: move">
|
<div class="content" style="cursor: move" sv-handle>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p>书签:{{ tag.cnt }}个</p>
|
<p>书签:{{ tag.cnt || 0 }}个</p>
|
||||||
<p>{{ tag.last_use }}</p>
|
<p>{{ tag.last_use }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,7 @@ api.get('/bookmarks', function(req, res) {
|
||||||
var tag = {
|
var tag = {
|
||||||
id: result && result[0] && result[0].tag_id,
|
id: result && result[0] && result[0].tag_id,
|
||||||
name: result && result[0] && result[0].tag_name,
|
name: result && result[0] && result[0].tag_name,
|
||||||
|
sort: result && result[0] && result[0].sort,
|
||||||
click: 0,
|
click: 0,
|
||||||
bookmarks: []
|
bookmarks: []
|
||||||
};
|
};
|
||||||
|
|
@ -241,11 +242,13 @@ api.get('/bookmarks', function(req, res) {
|
||||||
data.push({
|
data.push({
|
||||||
id: tag.id,
|
id: tag.id,
|
||||||
name: tag.name,
|
name: tag.name,
|
||||||
|
sort: tag.sort,
|
||||||
click: tag.click,
|
click: tag.click,
|
||||||
bookmarks: tag.bookmarks
|
bookmarks: tag.bookmarks
|
||||||
});
|
});
|
||||||
tag.id = bookmark.tag_id;
|
tag.id = bookmark.tag_id;
|
||||||
tag.name = bookmark.tag_name;
|
tag.name = bookmark.tag_name;
|
||||||
|
tag.sort = bookmark.sort;
|
||||||
tag.click = 0;
|
tag.click = 0;
|
||||||
tag.bookmarks = [];
|
tag.bookmarks = [];
|
||||||
}
|
}
|
||||||
|
|
@ -255,8 +258,18 @@ api.get('/bookmarks', function(req, res) {
|
||||||
if (result && result.length > 0) {
|
if (result && result.length > 0) {
|
||||||
data.push(tag);
|
data.push(tag);
|
||||||
}
|
}
|
||||||
data.sort((a, b) => b.click - a.click);
|
data.sort((a, b) => {
|
||||||
// console.log(JSON.stringify(data));
|
if (a.sort == b.sort) return b.click - a.click;
|
||||||
|
return a.sort - b.sort;
|
||||||
|
});
|
||||||
|
var temp = data.map(item => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
sort: item.sort,
|
||||||
|
click: item.click,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log(JSON.stringify(temp));
|
||||||
res.json(data);
|
res.json(data);
|
||||||
})
|
})
|
||||||
.catch((err) => console.log('bookmarks navigate err', err));
|
.catch((err) => console.log('bookmarks navigate err', err));
|
||||||
|
|
@ -614,8 +627,8 @@ api.post('/addTags', function(req, res) {
|
||||||
.catch((err) => console.log('addTags err', err));
|
.catch((err) => console.log('addTags err', err));
|
||||||
});
|
});
|
||||||
|
|
||||||
api.post('/updateTag', function(req, res) {
|
api.post('/updateTagName', function(req, res) {
|
||||||
console.log('hello updateTag', JSON.stringify(req.query), JSON.stringify(req.body));
|
console.log('hello updateTagName', JSON.stringify(req.query), JSON.stringify(req.body));
|
||||||
if (!req.session.user) {
|
if (!req.session.user) {
|
||||||
res.send(401);
|
res.send(401);
|
||||||
return;
|
return;
|
||||||
|
|
@ -630,7 +643,7 @@ api.post('/updateTag', function(req, res) {
|
||||||
return Promise.resolve(-1);
|
return Promise.resolve(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return db.updateTag(tag);
|
return db.updateTagName(tag);
|
||||||
})
|
})
|
||||||
.then((affectedRows) => {
|
.then((affectedRows) => {
|
||||||
var msg = "";
|
var msg = "";
|
||||||
|
|
@ -657,6 +670,71 @@ api.post('/updateTag', function(req, res) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
api.post('/updateTagsIndex', function(req, res) {
|
||||||
|
console.log('hello updateTagsIndex', JSON.stringify(req.query), JSON.stringify(req.body));
|
||||||
|
if (!req.session.user) {
|
||||||
|
res.send(401);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var tagsIndex = req.body.params;
|
||||||
|
|
||||||
|
db.updateTagsIndex(tagsIndex)
|
||||||
|
.then((affectedRows) => {
|
||||||
|
var msg = "";
|
||||||
|
if (affectedRows == tagsIndex.length) {
|
||||||
|
msg = " 排序更新成功";
|
||||||
|
} else {
|
||||||
|
msg += " 排序更新失败";
|
||||||
|
}
|
||||||
|
res.json({
|
||||||
|
retCode: (affectedRows == tagsIndex.length) ? 0 : 1,
|
||||||
|
msg: msg,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log('updateTagsIndex err', err);
|
||||||
|
res.json({
|
||||||
|
retCode: 1,
|
||||||
|
msg: "排序更新失败: " + JSON.stringify(err),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
api.post('/delTag', function(req, res) {
|
||||||
|
console.log('hello delTag', JSON.stringify(req.query), JSON.stringify(req.body));
|
||||||
|
if (!req.session.user) {
|
||||||
|
res.send(401);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var tag = req.body.params;
|
||||||
|
var needDelTag = tag.del || false;
|
||||||
|
var bookmarksId = []
|
||||||
|
db.getBookmarkIdsByTagId(tag.id)
|
||||||
|
.then((_bookmarksId) => {
|
||||||
|
bookmarksId = _bookmarksId.map((item) => item.bookmark_id);
|
||||||
|
return db.delTagBookmarks(tag.id); // 先删掉分类跟书签的映射
|
||||||
|
})
|
||||||
|
.then((affectedRows) => db.delBookmarks(bookmarksId)) // 再删掉该分类下面的书签
|
||||||
|
.then((affectedRows) => {
|
||||||
|
if (needDelTag) {
|
||||||
|
return db.delTag(tag.id);
|
||||||
|
}
|
||||||
|
return Promise.resolve(1);
|
||||||
|
}) // 再删掉分类
|
||||||
|
.then((affectedRows) => {
|
||||||
|
res.json({
|
||||||
|
retCode: affectedRows == 1 ? 0 : 1,
|
||||||
|
})
|
||||||
|
}) // 再删掉该分类下面的书签
|
||||||
|
.catch((err) => {
|
||||||
|
console.log('delTag err', err);
|
||||||
|
res.json({
|
||||||
|
retCode: 1,
|
||||||
|
msg: "删除分类失败: " + JSON.stringify(err),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
api.post('/getArticle', function(req, res) {
|
api.post('/getArticle', function(req, res) {
|
||||||
var params = req.body.params;
|
var params = req.body.params;
|
||||||
var url = params.url;
|
var url = params.url;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue