Compare commits
1 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
6daa88b148 |
27
Dockerfile
|
|
@ -1,27 +0,0 @@
|
|||
FROM luchenqun/ubuntu-mysql-node
|
||||
LABEL maintainer="luchenqun@qq.com"
|
||||
|
||||
RUN mkdir -p /app
|
||||
COPY src /app/src
|
||||
COPY view /app/view
|
||||
COPY package.json /app/package.json
|
||||
COPY production.js /app/production.js
|
||||
COPY schema.sql /app/schema.sql
|
||||
|
||||
WORKDIR /app
|
||||
RUN USER=`sed -n '4,4p' /etc/mysql/debian.cnf | awk 'BEGIN { FS = "= " } ; { print $2 }'` \
|
||||
&& sed -i "s/test/${USER}/" /app/src/config/adapter.js \
|
||||
&& PASSWORD=`sed -n '5,5p' /etc/mysql/debian.cnf | awk 'BEGIN { FS = "= " } ; { print $2 }'` \
|
||||
&& sed -i "s/123456/${PASSWORD}/g" /app/src/config/adapter.js \
|
||||
&& npm install --production \
|
||||
&& touch /usr/local/bin/start.sh \
|
||||
&& chmod 777 /usr/local/bin/start.sh \
|
||||
&& echo "#!/bin/bash" >> /usr/local/bin/start.sh \
|
||||
&& echo "service mysql restart" >> /usr/local/bin/start.sh \
|
||||
&& echo "mysql -u root < /app/schema.sql" >> /usr/local/bin/start.sh \
|
||||
&& echo "node /app/production.js" >> /usr/local/bin/start.sh
|
||||
|
||||
EXPOSE 3306
|
||||
EXPOSE 2000
|
||||
|
||||
ENTRYPOINT ["start.sh"]
|
||||
46
README.md
|
|
@ -1,9 +1,9 @@
|
|||
# 在线书签管理工具
|
||||

|
||||

|
||||
|
||||
1 在线体验(demo)
|
||||
-------------
|
||||
[在线书签管理系统](http://b.lucq.fun/ "在线书签管理系统"),体验账号:test。密码:123456。
|
||||
[在线书签管理系统](http://mybookmark.cn/ "在线书签管理系统"),体验账号:test。密码:123456。
|
||||
|
||||
2 为什么要做个网络书签
|
||||
------------------
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
- [x] 新增备忘录功能,有时候随手要做点纪录,就方便了。任意界面按快捷键A增加备忘录。双击备忘录可查看详情!亦可分享备忘。
|
||||
- [x] 在设置的全局链接,可设置快捷键,用来在任何页面,快速打开设置的链接。
|
||||
- [x] 增加[Chrome插件](https://chrome.google.com/webstore/detail/%E4%B9%A6%E7%AD%BE%E5%BF%AB%E9%80%9F%E6%B7%BB%E5%8A%A0/lmmobgephofdffmaednjooplcpbgbjle),可在任意界面快速添加书签至系统。如果你无法访问该插件,可以按照[Chrome如何安装插件(开发版本/自制)](https://jingyan.baidu.com/article/f3ad7d0f58d6b609c3345b80.html)方法安装插件,插件请到[bookmark-plugin](https://github.com/luchenqun/bookmark-plugin)下载。
|
||||
- [x] 适配手机平板,手机端请访问[mb.lucq.fun](http://mb.lucq.fun/)。
|
||||
- [x] 适配手机平板,手机端请访问[m.mybookmark.cn](http://m.mybookmark.cn/)。
|
||||
|
||||
|
||||
4 主要用到的软件与模块说明
|
||||
|
|
@ -48,7 +48,6 @@
|
|||
my-bookmark/
|
||||
├── development.js # 开发环境下的入口文件
|
||||
├── logs/ # 日志目录
|
||||
├── Dockerfile # Dockerfile 构建文件
|
||||
├── nginx.conf # nginx 配置文件
|
||||
├── package.json # 项目依赖包
|
||||
├── pm2.json # pm2 配置文件
|
||||
|
|
@ -79,6 +78,8 @@ my-bookmark/
|
|||
│ └── index.js # 后台测试文件
|
||||
├── update.sql # MySQL更新文件
|
||||
├── view/ # 网站主页显示文件夹
|
||||
│ └── index_index.html # 网站主页
|
||||
├── www # 网站实现文件夹
|
||||
│ ├── 404.html # 默认404页面
|
||||
│ ├── css/ # 样式表文件夹
|
||||
│ │ ├── externe/ # 外部引入引来的css文件
|
||||
|
|
@ -91,35 +92,13 @@ my-bookmark/
|
|||
│ │ ├── directives/ # 所有的AngularJS指令
|
||||
│ │ ├── externe/ # 外部引入的JS文件
|
||||
│ │ └── services/ # 所有的AngularJS服务文件
|
||||
│ ├── views/ # 页面实现文件
|
||||
│ └── index.html # 网站主页
|
||||
│ └── views/ # 页面实现文件
|
||||
└── README.md # 项目工程说明文件
|
||||
```
|
||||
|
||||
6 Docker安装部署
|
||||
6 安装部署指南
|
||||
-------------
|
||||
此部署方式适合新手。
|
||||
|
||||
如果你的Linux环境中没有安装Docker环境。那么请先执行如下命令安装Docker环境。
|
||||
```
|
||||
curl -fsSL get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh --mirror Aliyun
|
||||
```
|
||||
|
||||
安装好docker环境之后,执行命令 `docker run -d -p 2000:2000 -p 3306:3306 luchenqun/mybookmark` 安装并启动应用即可。然后在浏览器输入: `http://你的IP:2000/` 即可访问书签应用。安装好的环境默认了一个账号`test`,密码为`123456`。
|
||||
|
||||
如果MySQL需要远程访问,那么你需要进入容器之后更新 `/etc/mysql/mysql.conf.d/mysqld.cnf`,将绑定地址 `127.0.0.1` 改为 `0.0.0.0`。然后执行命令`service mysql restart`重启数据库服务。安装后的 MySQL默认有两个账户,一个是root账户,无密码。一个是在文件`/etc/mysql/debian.cnf`有个账号密码。当然这些账号都是只能在本地访问的,你需要手动创建一个可供远程访问的账号。
|
||||
|
||||
另外,有人做了arm架构的docker,如果有需要的请按如下命令执行安装
|
||||
```
|
||||
docker run -itd --name mybookmark -p 2000:2000 -p 3306:3306 740162752/bookmark
|
||||
```
|
||||
|
||||
7 安装部署指南
|
||||
-------------
|
||||
这种适合动手能力比较强的人员。
|
||||
|
||||
1、安装MySQL数据库。如果不会,请戳教程[MySQL 数据库安装教程](http://baidu.lucq.fun/?q=TXlTUUwg5pWw5o2u5bqT5a6J6KOF5pWZ56iL "mysql 数据库安装教程")。有点需要注意的是,MySQL的版本至少要是5.6。否则执行schema.sql文件会出错。
|
||||
1、安装MySQL数据库。如果不会,请戳教程[MySQL 数据库安装教程](http://baidu.luchenqun.com/?mysql%20%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B "mysql 数据库安装教程")。有点需要注意的是,MySQL的版本至少要是5.6。否则执行schema.sql文件会出错。
|
||||
2、新建一个数据库名,使用MySQL将根目录下面的schema.sql文件执行一遍,创建数据库表格。有个问题尤其要注意:**数据库一定要使用UTF-8的编码**,否则执行一些汉字的sql语句会出错!如果是Ubuntu,大概过程如下。
|
||||
```
|
||||
mysql -u root -p // 使用root账号进入mysql数据库。按回车之后输入安装时候root的密码。
|
||||
|
|
@ -130,19 +109,18 @@ use mybookmarks; //选择刚创建的数据库。
|
|||
source /home/lcq/schema.sql; // 执行schema.sql文件创建数据库表格。注意,将路径换为你schema.sql所在路径。
|
||||
```
|
||||
3、如果你是全新部署,你可忽略此步骤。如果之前部署过此应用,那么需要执行update.sql文件需要升级。注意:升级之前,请务必备份数据库!确认是否需要运行此升级sql文件也很简单,看一下你之前的数据库mybookmarks下面有没有`tags_bookmarks`这个数据表。如果有,那么需要执行。执行方法还是如上类似`source /home/lcq/update.sql;`。
|
||||
4、安装Node.js。Node.js版本至少要求12.0以上。不会的话,请按照上面步骤1提供的方法自行解决。
|
||||
4、安装Node.js。Node.js版本至少要求12.0以上。不会的话,请按照上面步骤1、3提供的方法自行解决。
|
||||
5、克隆代码`git clone git@github.com:luchenqun/my-bookmark.git`,切换到项目根目录下面,执行`npm install`安装package。
|
||||
6、在根目录,更新`pm2.json`文件,只需要更新`cwd`项即可。该项为你项目所在的路径。更新`src/config/adapter.js`下面`exports.model`关于你的MySQL的账号密码信息。注意,该账号必须要有写数据库的权限!
|
||||
7、如果上面的都做好了,执行命令`npm install pm2 -g`安装pm2模块。再执行命令`pm2 startOrReload pm2.json`。以后如果项目代码有升级,更新代码之后,执行此命令即可重启该应用。
|
||||
8、在浏览器里面输入:`http://你的IP:2000/`。
|
||||
8、在浏览器里面输入:127.0.0.1:2000。
|
||||
9、如果需要域名部署的话,推荐使用nginx作为HTTP和反向代理服务器,根目录有一份`nginx.conf`文件,你只需要更新`root`项即可使用。相关知识,请自行百度。
|
||||
|
||||
|
||||
8 其他说明
|
||||
7 其他说明
|
||||
---------
|
||||
1、我没有做浏览器兼容测试,只在Google Chrome下面进行了测试开发。
|
||||
|
||||
9 开源许可证
|
||||
8 开源许可证
|
||||
-----------
|
||||
[MIT License](http://www.opensource.org/licenses/MIT)
|
||||
你可以随意使用此项目,无需通知我,因为我可能很忙没时间。注意,手机版当前没开源
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
server {
|
||||
listen 80;
|
||||
server_name b.lucq.fun;
|
||||
server_name book.mybookmark.cn;
|
||||
root /var/www/my-bookmark;
|
||||
set $node_port 2000;
|
||||
set $node_port 8360;
|
||||
|
||||
index index.js index.html index.htm;
|
||||
if ( -f $request_filename/index.html ){
|
||||
|
|
|
|||
23
schema.sql
|
|
@ -1,8 +1,6 @@
|
|||
CREATE DATABASE IF NOT EXISTS mybookmarks DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 创建mybookmarks数据库
|
||||
USE mybookmarks;
|
||||
|
||||
-- 用户信息表
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
drop table if exists users;
|
||||
CREATE TABLE `users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, -- id
|
||||
`username` varchar(255) NOT NULL, -- 用户名
|
||||
`password` varchar(255) NOT NULL, -- 密码
|
||||
|
|
@ -11,14 +9,15 @@ CREATE TABLE IF NOT EXISTS `users` (
|
|||
`lastLogin` datetime DEFAULT now(), -- 最后一次登录时间
|
||||
`searchHistory` varchar(512) DEFAULT NULL, -- 历史搜索记录
|
||||
`avatar` varchar(512) DEFAULT NULL, -- 头像地址
|
||||
`quickUrl` varchar(2048) DEFAULT '{\"B\":\"https://www.baidu.com/\",\"G\":\"https://www.google.com.hk/\",\"H\":\"https://github.com/\"}', -- 全局快捷地址
|
||||
`quickUrl` varchar(2048) DEFAULT '{\"B\":\"https://www.baidu.com/\",\"G\":\"https://www.google.com.hk/\",\"V\":\"https://www.v2ex.com/\",\"L\":\"http://luchenqun.com/\",\"H\":\"https://github.com/\",\"Q\":\"http://www.iqiyi.com/\",\"J\":\"https://www.jd.com/\"}', -- 全局快捷地址
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `username` (`username`),
|
||||
UNIQUE KEY `email` (`email`)
|
||||
);
|
||||
|
||||
-- 书签表
|
||||
CREATE TABLE IF NOT EXISTS `bookmarks` (
|
||||
drop table if exists bookmarks;
|
||||
CREATE TABLE `bookmarks` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, -- id
|
||||
`userId` int(11) NOT NULL, -- 用户id
|
||||
`tagId` int(11) NOT NULL, -- 分类id (只允许一个书签对应一个分类)
|
||||
|
|
@ -34,7 +33,8 @@ CREATE TABLE IF NOT EXISTS `bookmarks` (
|
|||
);
|
||||
|
||||
-- 书签分类表
|
||||
CREATE TABLE IF NOT EXISTS `tags` (
|
||||
drop table if exists tags;
|
||||
CREATE TABLE `tags` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, -- id
|
||||
`userId` int(11) NOT NULL, -- 用户id
|
||||
`name` varchar(32) NOT NULL, -- 标签
|
||||
|
|
@ -47,7 +47,8 @@ CREATE TABLE IF NOT EXISTS `tags` (
|
|||
);
|
||||
|
||||
-- 建议留言
|
||||
CREATE TABLE IF NOT EXISTS `advices` (
|
||||
drop table if exists advices;
|
||||
CREATE TABLE `advices` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, -- id
|
||||
`userId` int(11) NOT NULL, -- 用户id
|
||||
`comment` text NOT NULL, -- 评论
|
||||
|
|
@ -58,7 +59,8 @@ CREATE TABLE IF NOT EXISTS `advices` (
|
|||
);
|
||||
|
||||
-- 热门表
|
||||
CREATE TABLE IF NOT EXISTS `hot_bookmarks` (
|
||||
drop table if exists hot_bookmarks;
|
||||
CREATE TABLE `hot_bookmarks` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, -- id(articleId)
|
||||
`title` varchar(255) DEFAULT NULL, -- 标题(title)
|
||||
`url` varchar(1024) DEFAULT NULL, -- 链接(url)
|
||||
|
|
@ -72,7 +74,8 @@ CREATE TABLE IF NOT EXISTS `hot_bookmarks` (
|
|||
);
|
||||
|
||||
-- 备忘录
|
||||
CREATE TABLE IF NOT EXISTS `notes` (
|
||||
drop table if exists notes;
|
||||
CREATE TABLE `notes` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT, -- id
|
||||
`userId` int(11) NOT NULL, -- 用户id
|
||||
`content` text NOT NULL, -- 备忘内容
|
||||
|
|
|
|||
|
|
@ -1,18 +1 @@
|
|||
// invoked in worker
|
||||
const { execSync } = require('child_process');
|
||||
const os = require("os");
|
||||
think.beforeStartServer(async () => {
|
||||
if (os.platform().startsWith("linux")) {
|
||||
try {
|
||||
execSync('service mysql start', { stdio: ['inherit', 'inherit', 'inherit'] });
|
||||
} catch (error) {
|
||||
console.log("beforeStartServer", error);
|
||||
}
|
||||
}
|
||||
|
||||
const username = 'test';
|
||||
let user = await think.model("users").where({ username }).find();
|
||||
if (think.isEmpty(user)) {
|
||||
await think.model("users").add({ username, password: 'e10adc3949ba59abbe56e057f20f883e', email: 'ilovejiajia@qq.com' });
|
||||
}
|
||||
})
|
||||
|
|
@ -66,7 +66,7 @@ exports.session = {
|
|||
tokenName: 'authorization', // if tokenType not 'cookie', this will be token name, 'jwt' is default 后端字母要小写
|
||||
sign: {
|
||||
// sign options is not required
|
||||
expiresIn: '2592000s' // 30天过期
|
||||
expiresIn: '604800s' // 7天过期
|
||||
},
|
||||
verify: {
|
||||
// verify options is not required
|
||||
|
|
|
|||
|
|
@ -22,11 +22,7 @@ module.exports = [{
|
|||
let data = JSON.parse(body).data;
|
||||
let list = data.list;
|
||||
let dataList = [];
|
||||
for (let item of list) {
|
||||
if (item.images_upd.indexOf(',http') >= 0) {
|
||||
item.images_upd = item.images_upd.split(',http')[0];
|
||||
}
|
||||
|
||||
for (const item of list) {
|
||||
dataList.push({
|
||||
id: item.articleId,
|
||||
title: item.title,
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ module.exports = [
|
|||
handle: 'resource',
|
||||
enable: true,
|
||||
options: {
|
||||
root: path.join(think.ROOT_PATH, 'view'),
|
||||
publicPath: /^\/(scripts|css|views|images|admin\.jpg|favicon\.ico)/
|
||||
root: path.join(think.ROOT_PATH, 'www'),
|
||||
publicPath: /^\/(scripts|css|views|images|favicon\.ico)/
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ module.exports = class extends Base {
|
|||
username: user.username
|
||||
});
|
||||
user.token = token;
|
||||
await this.model('users').where({ id: user.id }).update({ lastLogin: ['exp', 'NOW()'] });
|
||||
this.json({ code: 0, data: user, msg: "登陆成功" });
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
@ -211,17 +210,6 @@ module.exports = class extends Base {
|
|||
let bookmark = this.post();
|
||||
bookmark.userId = this.ctx.state.user.id;
|
||||
try {
|
||||
let bookmarkFind = await this.model('bookmarks').where({ userId: this.ctx.state.user.id, url: bookmark.url }).find();
|
||||
if (!think.isEmpty(bookmarkFind)) {
|
||||
await this.model('bookmarks').where({
|
||||
userId: this.ctx.state.user.id,
|
||||
id: bookmarkFind.id
|
||||
}).update({
|
||||
createdAt: ['exp', 'NOW()']
|
||||
});
|
||||
this.json({ code: 0, data: bookmarkFind, msg: `书签 ${bookmark.title} 已存在,更新创建日期!` });
|
||||
return
|
||||
}
|
||||
// 没有分类的直接放未分类里面
|
||||
if (!bookmark.tagId) {
|
||||
const name = "未分类";
|
||||
|
|
@ -237,10 +225,6 @@ module.exports = class extends Base {
|
|||
}
|
||||
}
|
||||
let data = await this.model("bookmarks").add(bookmark);
|
||||
await this.model('tags').where({
|
||||
userId: this.ctx.state.user.id,
|
||||
id: bookmark.tagId
|
||||
}).update({ lastUse: think.datetime(new Date()) });
|
||||
this.json({ code: 0, data, msg: `书签 ${bookmark.title} 添加成功` });
|
||||
} catch (error) {
|
||||
this.json({ code: 1, data: '', msg: error.toString() });
|
||||
|
|
@ -281,13 +265,13 @@ module.exports = class extends Base {
|
|||
if (page == 0 && tagId == -1) {
|
||||
let count = await this.model('bookmarks').where(condition).count('id');
|
||||
let totalPages = Math.ceil(count / pageSize);
|
||||
// 按照 1:1取数据
|
||||
let length = Math.ceil(pageSize / 2);
|
||||
// 按照 2:2:1取数据
|
||||
let length = Math.ceil(pageSize * 2 / 5);
|
||||
let bookmarks = await this.model('bookmarks').where(condition).order('createdAt DESC').limit(0, length).select(); // 这个取一半
|
||||
|
||||
// 取最近点击部分数据
|
||||
let cnt = 0;
|
||||
let bookmarks2 = await this.model('bookmarks').where(condition).order('lastClick DESC').limit(0, pageSize * 4).select(); // 这个多取一点,有可能跟上面的重复了
|
||||
let bookmarks2 = await this.model('bookmarks').where(condition).order('lastClick DESC').limit(0, pageSize * 2).select(); // 这个多取一点,有可能跟上面的重复了
|
||||
for (const bookmark of bookmarks2) {
|
||||
let find = bookmarks.find(item => item.id == bookmark.id);
|
||||
if (!find) {
|
||||
|
|
@ -297,6 +281,16 @@ module.exports = class extends Base {
|
|||
}
|
||||
}
|
||||
|
||||
// 取点击次数最多部分
|
||||
let bookmarks3 = await this.model('bookmarks').where(condition).order('clickCount DESC').limit(0, pageSize * 2).select(); // 这个多取一点,有可能跟上面的重复了
|
||||
for (const bookmark of bookmarks3) {
|
||||
let find = bookmarks.find(item => item.id == bookmark.id);
|
||||
if (!find) {
|
||||
bookmarks.push(bookmark);
|
||||
if (bookmarks.length >= pageSize) break;
|
||||
}
|
||||
}
|
||||
|
||||
data = {
|
||||
count,
|
||||
totalPages,
|
||||
|
|
@ -346,7 +340,7 @@ module.exports = class extends Base {
|
|||
}
|
||||
|
||||
try {
|
||||
let data = await this.model(tableName).where(condition).order('createdAt DESC').page(this.get('page') || 1, this.get('pageSize') || 20).countSelect();
|
||||
let data = await this.model(tableName).where(condition).page(this.get('page') || 1, this.get('pageSize') || 20).countSelect();
|
||||
if (tableName == "bookmarks") {
|
||||
let ids = [];
|
||||
for (let bookmark of data.data) {
|
||||
|
|
@ -426,193 +420,94 @@ module.exports = class extends Base {
|
|||
// path: 'C:\\Users\\lucq\\AppData\\Local\\Temp\\upload_4ae3b14dacaa107076d3bddd471ebe39.html',
|
||||
// name: 'exportbookmark-lcq-20200402084709.html',
|
||||
// type: 'text/html',
|
||||
|
||||
const getRootFolder = function (body) {
|
||||
let h3 = body.find("h3").first();
|
||||
// let isChrome = typeof h3.attr("personal_toolbar_folder") === "string";
|
||||
// let isIE = typeof h3.attr("item_id") === "string";
|
||||
// let isFireFox = h3.text() === "Mozilla Firefox";
|
||||
let isSafari = typeof h3.attr("folded") === "string";
|
||||
return isSafari ? body : body.children("dl").first();
|
||||
};
|
||||
|
||||
const parseByString = function (content) {
|
||||
let $ = cheerio.load(content, { decodeEntities: false });
|
||||
let body = $("body");
|
||||
let root = [];
|
||||
let rdt = getRootFolder(body).children("dt");
|
||||
let parseNode = function (node) {
|
||||
let eq0 = node.children().eq(0);
|
||||
let title = eq0.html() || "无标题";
|
||||
let type = "site";
|
||||
let href = "";
|
||||
let attrCreatedAt = "";
|
||||
let attrLastClick = "";
|
||||
let attrClickCount = "";
|
||||
|
||||
let children = [];
|
||||
switch (eq0[0].name) {
|
||||
case "h3":
|
||||
// folder
|
||||
type = "folder";
|
||||
let dl = node.children("dl").first();
|
||||
let dts = dl.children();
|
||||
let ls = dts.toArray().map(function (ele) { return ele.name !== "dt" ? null : parseNode($(ele)); });
|
||||
children = ls.filter(function (item) { return item !== null; });
|
||||
case "a":
|
||||
// site
|
||||
href = eq0.attr("href") || "";
|
||||
attrCreatedAt = eq0.attr("add_date");
|
||||
attrLastClick = eq0.attr("last_click");
|
||||
attrClickCount = eq0.attr("click_count");
|
||||
}
|
||||
// 处理name
|
||||
if (title.length > 255) {
|
||||
title = title.substring(255);
|
||||
}
|
||||
title = title.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/gi, "");
|
||||
|
||||
return {
|
||||
title,
|
||||
type,
|
||||
url: href,
|
||||
createdAt: think.datetime(attrCreatedAt ? parseInt(attrCreatedAt) * 1000 : new Date()),
|
||||
lastClick: think.datetime(attrLastClick ? parseInt(attrLastClick) * 1000 : new Date()),
|
||||
clickCount: attrClickCount ? parseInt(attrClickCount) : 1,
|
||||
children: children
|
||||
};
|
||||
};
|
||||
rdt.each(function (_, item) {
|
||||
let node = $(item);
|
||||
let child = parseNode(node);
|
||||
root.push(child);
|
||||
});
|
||||
return root;
|
||||
};
|
||||
|
||||
const parseByPath = function (path) {
|
||||
var content = fs.readFileSync(path, 'utf-8');
|
||||
return parseByString(content);
|
||||
};
|
||||
|
||||
const userId = this.ctx.state.user.id;
|
||||
|
||||
const flatBookmarks = (originBookmarks, tagName, bookmarks) => {
|
||||
for (let bookmark of originBookmarks) {
|
||||
if (bookmark.type == "site") {
|
||||
bookmarks.push({
|
||||
title: bookmark.title,
|
||||
url: bookmark.url,
|
||||
createdAt: bookmark.createdAt,
|
||||
lastClick: bookmark.lastClick,
|
||||
tagName,
|
||||
clickCount: bookmark.clickCount,
|
||||
userId
|
||||
});
|
||||
} else if (bookmark.type == "folder") {
|
||||
flatBookmarks(bookmark.children, tagName == '未分类' ? bookmark.title : tagName, bookmarks);
|
||||
}
|
||||
}
|
||||
}
|
||||
const file = this.file("file");
|
||||
|
||||
let bookmarks = [];
|
||||
|
||||
const file = this.file("file");
|
||||
let fileName = 'uploadbookmark-' + this.ctx.state.user.username + '-' + think.datetime(new Date(), "YYYYMMDDHHmmss") + '.html';
|
||||
let now = new Date().getTime();
|
||||
let fileName = 'uploadbookmark-' + this.ctx.state.user.username + '-' + now + '.html';
|
||||
if (file) {
|
||||
const filePath = path.join(think.ROOT_PATH, `runtime/upload/${fileName}`);
|
||||
await fs.ensureDir(path.dirname(filePath));
|
||||
await fs.move(file.path, filePath);
|
||||
let originBookmarks = parseByPath(filePath);
|
||||
Array.isArray(originBookmarks) && originBookmarks.length >= 0 && (originBookmarks[0].title = "未分类");
|
||||
flatBookmarks(originBookmarks, originBookmarks[0].title, bookmarks); // 传上来的树级目录改为只有一级目录
|
||||
let data = await fs.readFile(filePath);
|
||||
let $ = cheerio.load(data.toString());
|
||||
|
||||
let anchors = $("dl").find("a");
|
||||
anchors.each(async (i, e) => {
|
||||
let url = $(e).attr("href");
|
||||
let title = $(e).text() || "无标题";
|
||||
if (title.length > 255) {
|
||||
title = title.substring(255);
|
||||
}
|
||||
title = title.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/gi, "");
|
||||
let attrCreatedAt = $(e).attr("add_date");
|
||||
let attrLastClick = $(e).attr("last_click");
|
||||
let attrClickCount = $(e).attr("click_count");
|
||||
let createdAt = think.datetime(attrCreatedAt ? parseInt(attrCreatedAt) * 1000 : new Date());
|
||||
let lastClick = think.datetime(attrLastClick ? parseInt(attrLastClick) * 1000 : new Date());
|
||||
let clickCount = attrClickCount ? parseInt(attrClickCount) : 1;
|
||||
|
||||
// 只允许用一个标签
|
||||
let tagName = "未分类";
|
||||
$(e).parents("dl").each(function (ii, ee) {
|
||||
let folder = $(ee).prev();
|
||||
let temp = folder.text().replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' ');
|
||||
if (temp != "Bookmarks" && temp != "书签栏" && temp != "" && temp != undefined) { tagName = temp; }
|
||||
});
|
||||
bookmarks.push({ title, url, createdAt, lastClick, tagName, clickCount, userId: this.ctx.state.user.id })
|
||||
});
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
let repeat = 0;
|
||||
let fail = 0;
|
||||
let failStr = "";
|
||||
let tags = await this.model("tags").where({ userId: this.ctx.state.user.id }).select();
|
||||
let tags = await this.model('tags').where({ userId: this.ctx.state.user.id }).select();
|
||||
for (let bookmark of bookmarks) {
|
||||
let find = await this.model("bookmarks").where({ userId: this.ctx.state.user.id, url: bookmark.url }).find();
|
||||
let find = await this.model('bookmarks').where({ userId: this.ctx.state.user.id, url: bookmark.url }).find();
|
||||
if (think.isEmpty(find)) {
|
||||
let tag = tags.find((item) => item.name == bookmark.tagName);
|
||||
let tag = tags.find(item => item.name == bookmark.tagName);
|
||||
if (tag) {
|
||||
bookmark.tagId = tag.id;
|
||||
} else {
|
||||
bookmark.tagId = await this.model("tags").add({ userId: this.ctx.state.user.id, name: bookmark.tagName });
|
||||
tags.push({
|
||||
id: bookmark.tagId,
|
||||
name: bookmark.tagName,
|
||||
});
|
||||
name: bookmark.tagName
|
||||
})
|
||||
}
|
||||
delete bookmark.tagName;
|
||||
try {
|
||||
await this.model("bookmarks").add(bookmark);
|
||||
} catch (error) {
|
||||
fail++;
|
||||
failStr += bookmark.title + ",";
|
||||
}
|
||||
await this.model("bookmarks").add(bookmark);
|
||||
count++;
|
||||
} else {
|
||||
repeat++;
|
||||
}
|
||||
}
|
||||
this.json({ code: 0, data: count, msg: `书签传入${bookmarks.length}个,重复书签${repeat}个,${fail}个导入失败:${failStr},成功导入${count}个。` });
|
||||
this.json({ code: 0, data: count, msg: `书签传入${bookmarks.length}个,重复书签${repeat}个,成功导入${count}个。` });
|
||||
}
|
||||
|
||||
// 书签备份
|
||||
async bookmarkBackupAction() {
|
||||
const sample =
|
||||
`<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
DO NOT EDIT! -->
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<TITLE>Bookmarks</TITLE>
|
||||
<H1>Bookmarks</H1>
|
||||
<DL><p>
|
||||
<DT><H3 ADD_DATE="1606958496" LAST_MODIFIED="1622450430" PERSONAL_TOOLBAR_FOLDER="true">书签栏</H3>
|
||||
<DL><p>
|
||||
<DT><H3 ADD_DATE="1622427860" LAST_MODIFIED="1622450436">JavaScript</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="https://github.com/luchenqun/my-bookmark/issues" ADD_DATE="1622427872">Issues · luchenqun/my-bookmark</A>
|
||||
<DT><A HREF="https://mail.google.com/mail/u/0/#inbox" ADD_DATE="1622450430">收件箱 - lcq530485521@gmail.com - Gmail</A>
|
||||
</DL><p>
|
||||
</DL><p>
|
||||
</DL><p>`
|
||||
|
||||
let init = '<TITLE>Bookmarks</TITLE><H1>Bookmarks</H1><DL id="0"></DL>';
|
||||
let $ = cheerio.load(init, {
|
||||
decodeEntities: false,
|
||||
xmlMode: true,
|
||||
});
|
||||
let time = (date) => parseInt(new Date(date).getTime() / 1000); // 日期转时间
|
||||
let now = new Date();
|
||||
let left = `<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
DO NOT EDIT! -->
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<TITLE>Bookmarks</TITLE>
|
||||
<H1>Bookmarks</H1>
|
||||
<DL><p>
|
||||
<DT><H3 ADD_DATE="${time(now)}" LAST_MODIFIED="${time(now)}" PERSONAL_TOOLBAR_FOLDER="true">书签栏</H3>
|
||||
<DL><p>\n`;
|
||||
let middle = '';
|
||||
let right = ` </DL><p>
|
||||
</DL><p>`;
|
||||
|
||||
let tags = await this.model('tags').where({ userId: this.ctx.state.user.id }).order('sort ASC, lastUse DESC').select();
|
||||
for (const tag of tags) {
|
||||
let tagStr = ` <DT><H3 ADD_DATE="${time(tag.lastUse)}" LAST_MODIFIED="${time(tag.lastUse)}">${tag.name}</H3>\n <DL><p>\n`;
|
||||
$('#0').append(`<DT><H3>${tag.name}</H3></DT><DL id="${tag.id}"></DL>`);
|
||||
let bookmarks = await this.model('bookmarks').where({ tagId: tag.id }).select();
|
||||
for (const bookmark of bookmarks) {
|
||||
tagStr += ` <DT><A HREF="${bookmark.url}" ADD_DATE="${time(bookmark.createdAt)}" LAST_CLICK="${time(bookmark.lastClick)}" CLICK_COUNT="${bookmark.clickCount}">${bookmark.title}</A>\n`
|
||||
$('#' + tag.id).append(`<DT><A HREF="${bookmark.url}" ADD_DATE="${time(bookmark.createdAt)}" LAST_CLICK="${time(bookmark.lastClick)}" CLICK_COUNT="${bookmark.clickCount}" >${bookmark.title}</A></DT>`)
|
||||
}
|
||||
tagStr += ` </DL><p>\n`;
|
||||
middle += bookmarks.length > 0 ? tagStr : '';
|
||||
}
|
||||
let fileName = 'exportbookmark-' + this.ctx.state.user.username + '-' + think.datetime(new Date(), "YYYYMMDDHHmmss") + '.html';
|
||||
let now = new Date().getTime()
|
||||
let fileName = 'exportbookmark-' + this.ctx.state.user.username + '-' + now + '.html';
|
||||
let filePath = path.join(think.ROOT_PATH, 'runtime', 'backup', fileName);
|
||||
|
||||
await fs.ensureFile(filePath);
|
||||
await fs.writeFile(filePath, left + middle + right);
|
||||
await fs.writeFile(filePath, $.xml());
|
||||
this.json({ code: 0, data: fileName });
|
||||
|
||||
setTimeout(async () => {
|
||||
|
|
@ -707,9 +602,6 @@ module.exports = class extends Base {
|
|||
async adviceAddAction() {
|
||||
let advice = this.post();
|
||||
advice.userId = this.ctx.state.user.id;
|
||||
if (this.ctx.state.user.username == 'test') {
|
||||
return this.json({ code: 400, data: '', msg: `Test user forbid advice!` });
|
||||
}
|
||||
try {
|
||||
let res = await this.model("advices").add(advice);
|
||||
this.json({ code: 0, data: res, msg: `留言 添加成功` });
|
||||
|
|
@ -801,29 +693,24 @@ module.exports = class extends Base {
|
|||
|
||||
async noteShareAction() {
|
||||
let id = this.get("id");
|
||||
let json = this.get("json");
|
||||
let note = await this.model('notes').where({ id, public: 1 }).find();
|
||||
if (json) {
|
||||
this.json(JSON.parse(note.content))
|
||||
} else {
|
||||
let body = think.isEmpty(note) ? "备忘为非公开或者已删除!" : note.content;
|
||||
this.body = `<body style="margin:0px;height:100%;">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
|
||||
<script>
|
||||
if(screen && screen.availWidth <= 1024) {
|
||||
setTimeout(() => {
|
||||
document.getElementById("note-div").style.width = "100%";
|
||||
document.getElementById("note-div").style["background-color"] = "#F3F4F5";
|
||||
document.getElementById("note").style.width = "95%";
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<div id="note-div" style="text-align:center;">
|
||||
<pre id="note" style="background-color:RGB(243,244,245); padding:0px 10px 0px 10px; margin:0px; width:60%; min-height:100%;display: inline-block;text-align: left; font-size: 15px; font-family:italic arial,sans-serif;word-wrap: break-word;white-space: pre-wrap;">\n\n${body}\n\n</pre>
|
||||
</div>
|
||||
</body>`;
|
||||
}
|
||||
let body = think.isEmpty(note) ? "备忘为非公开或者已删除!" : note.content;
|
||||
this.body = `<body style="margin:0px;height:100%;">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
|
||||
<script>
|
||||
if(screen && screen.availWidth <= 1024) {
|
||||
setTimeout(() => {
|
||||
document.getElementById("note-div").style.width = "100%";
|
||||
document.getElementById("note-div").style["background-color"] = "#F3F4F5";
|
||||
document.getElementById("note").style.width = "95%";
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<div id="note-div" style="text-align:center;">
|
||||
<pre id="note" style="background-color:RGB(243,244,245); padding:0px 10px 0px 10px; margin:0px; width:60%; min-height:100%;display: inline-block;text-align: left; font-size: 15px; font-family:italic arial,sans-serif;word-wrap: break-word;white-space: pre-wrap;">\n\n${body}\n\n</pre>
|
||||
</div>
|
||||
</body>`;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const Base = require('./base.js');
|
||||
|
||||
module.exports = class extends Base {
|
||||
async indexAction() {
|
||||
await this.display("index.html");
|
||||
}
|
||||
};
|
||||
const Base = require('./base.js');
|
||||
|
||||
module.exports = class extends Base {
|
||||
indexAction() {
|
||||
return this.display();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,14 +37,6 @@
|
|||
var text = e.text.length >= 180 ? e.text.substr(0, 180) + "..." : e.text;
|
||||
toastr.error(text + "<br/>复制失败", "提示");
|
||||
});
|
||||
|
||||
if (window.location.hostname.indexOf("mybookmark.cn") >= 0) {
|
||||
toastr.warning("域名【mybookmark.cn】将于2021年11月份到期,届时将不再续费无法访问。后续将使用新域名【http://b.lucq.fun】为您提供服务。5分钟后会自动跳转到新的域名。", "提示");
|
||||
$(".js-domain").removeClass("hidden");
|
||||
setTimeout(function () {
|
||||
window.location = "http://b.lucq.fun/#/tags";
|
||||
}, 5 * 60 * 1000);
|
||||
}
|
||||
};
|
||||
let resizeContainer = () => {
|
||||
let count = 1;
|
||||
|
|
@ -61,25 +53,18 @@
|
|||
</head>
|
||||
|
||||
<body ng-app="bookmarkApp">
|
||||
<div class="ui container" id="js-container" style="position: absolute; left: 86;width: 70%;">
|
||||
<div class="ui error hidden message js-domain" style="margin-bottom: 3px">
|
||||
<div class="header">域名更换提示!</div>
|
||||
<ul class="list">
|
||||
<li>域名【mybookmark.cn】将于2021年11月份到期,届时将不再续费无法访问。目前已使用新域名【<a href="http://b.lucq.fun/">http://b.lucq.fun</a>】为您提供服务。</li>
|
||||
<li>5分钟后会自动跳转到新的域名。<a href="http://b.lucq.fun/">立即跳转</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ui container" id="js-container" style="position: absolute;left: 86;">
|
||||
<!-- directive:菜单 -->
|
||||
<menus></menus>
|
||||
<div class="ui container" style="width: 100%; height: 2px"></div>
|
||||
<div class="ui container" style="width: 100%; height: 2px;"></div>
|
||||
<div class="ui container">
|
||||
<div ui-view></div>
|
||||
</div>
|
||||
<div class="ui container" style="width: 100%; height: 2px"></div>
|
||||
<div class="foot">
|
||||
<div class="ui segment container" style="text-align: center">我爱佳佳与这个世界 | <a href="http://mb.lucq.fun/">移动设备访问</a> | 联系我(QQ群:1026967226) | <a href="http://beian.miit.gov.cn/" target="_blank">粤ICP备18032994号</a> | <a href="https://github.com/luchenqun/my-bookmark" target="_blank">网站源码</a> | V2.0.0 | <span>加载失败,请按 Ctrl + Shift + R 强制刷新!(●'◡'●)</span><br /></div>
|
||||
<div class="ui container" style="width: 100%; height: 10px;"></div>
|
||||
<div class="foot" style="margin-bottom: 10px;">
|
||||
<div class="ui segment container" style="text-align: center;">我爱佳佳与这个世界 | <a href="http://m.mybookmark.cn/">移动设备访问</a> | 联系我(QQ群:1026967226) | <a href="http://beian.miit.gov.cn/" target="_blank">粤ICP备18032994号</a> | <a href="https://github.com/luchenqun/my-bookmark" target="_blank">网站源码</a> | V2.0.0 | <span>加载失败,请按 Ctrl + Shift + R 强制刷新!(●'◡'●)</span><br /></div>
|
||||
<!-- 主要用来配合clipboard.min.js复制文本的 -->
|
||||
<div id="clipboard" data-clipboard-text="i love this world and jiajia!" style="opacity: 0; cursor: default">
|
||||
<div id="clipboard" data-clipboard-text="i love this world and jiajia!" style="opacity: 0; cursor: default;">
|
||||
<span>Copy</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -124,10 +109,5 @@
|
|||
<script src="scripts/externe/md5.js"></script>
|
||||
<script src="scripts/externe/pnglib.js"></script>
|
||||
<script src="scripts/externe/identicon.js"></script>
|
||||
<style>
|
||||
.ui.container {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
<div class="ui segment js-note-card" style="padding: 14px 0px 0px 0px" ng-show="!loading || tags.length > 0">
|
||||
<div class="ui container" style="padding-left: 14px">
|
||||
<div class="ui label" style="margin: 3px 15px 8px 0px; cursor: default" ng-class="{green:tag.clicked}" ng-repeat="tag in tags" ng-click="clickTag(tag.id)" ng-show="tag.noteCount || add">{{ tag.name }} ({{ tag.noteCount || 0 }})</div>
|
||||
<div class="ui label" style="margin: 3px 15px 8px 0px; cursor: default" ng-click="showAddNote()" data-tooltip="点击添加备忘。你也可以在任意界面按快捷键A(不区分大小写)增加备忘录。">
|
||||
<i class="plus icon" style="margin-right: 0px"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui container" style="padding-left: 14px; padding-bottom: 14px" ng-show="add">
|
||||
<div class="ui form">
|
||||
<div class="required field">
|
||||
<label>内容</label>
|
||||
<textarea rows="12" placeholder="" ng-model="content" id="noteedit"></textarea>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="actions">
|
||||
<div class="ui cancel button" ng-click="add=false;">取消</div>
|
||||
<div class="ui green button" ng-click="addNote(false)" ng-show="!edit">确定</div>
|
||||
<div class="ui green button" ng-click="updateNote()" ng-show="edit">更新</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider" ng-show="notes.length > 0" style="margin: 0px"></div>
|
||||
<div class="ui hidden info message js-note" ng-if="(!add) && notes.length == 0" style="margin-left: 14px; margin-right: 14px">
|
||||
<i class="close icon" ng-click="closeNote()"></i>
|
||||
<div class="content">
|
||||
<div class="header">系统提示!</div>
|
||||
<ul class="list">
|
||||
<li>您可以在任意界面按快捷键A(不区分大小写)增加备忘录。双击备忘录可查看详情!</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui vertical segment" ng-repeat="note in notes" ng-click="noteClick(note)" ng-mouseover="setHoverNote(note)" ng-mouseleave="setHoverNote(null)" id="{{note.id}}" style="margin: 0px; padding: 10px 0px">
|
||||
<pre class="note-content" title="单击查看详情,C复制,D删除,E编辑" style="margin: 0px; padding-left: 14px; padding-right: 14px" ng-if="!note.detail">{{ note.brief }}</pre>
|
||||
<pre class="note-content" style="margin: 0px; font-size: 16px; padding: 60px 14px" ng-if="note.detail">{{ note.content }}</pre>
|
||||
<div class="ui right aligned grid" ng-show="note.detail">
|
||||
<div class="sixteen wide column" style="margin: 0px 20px 0px 0px; padding: 20px 0px 0px 0px">
|
||||
<div class="extra content" ng-show="true" ng-mouseleave="note.edit=false;" style="height: 50px">
|
||||
<div class="ui mini label" ng-click="clickTag(note.tagId)" style="margin: 3px 0px 0px 10px; cursor: default">{{ note.tagName || "未分类" }}</div>
|
||||
<span style="margin: 0 8px">
|
||||
<span title="添加于{{note.createdAt}}" class="need_to_be_rendered" data-timeago="{{ note.createdAt }}"></span>
|
||||
<span style="margin-left: -3px">添加</span>
|
||||
</span>
|
||||
<i ng-if="note.public == 0" class="black lock icon" title="点击公开备忘" ng-click="updatePublic(note, 1)"></i>
|
||||
<i ng-if="note.public == 1" class="black open lock icon" title="点击不公开备忘" ng-click="updatePublic(note, 0)"></i>
|
||||
<img class="ui mini spaced image" style="width: 16px; height: 16px; margin: 0 8px" ng-src="./images/delete.png" ng-click="delNote(note.id, note.content)" title="删除备忘" />
|
||||
<label for="noteedit">
|
||||
<img class="ui mini spaced image" style="width: 16px; height: 16px; margin: 0 8px" ng-src="./images/edit-bookmark.png" ng-click="editNote(note.id, note.content, note.tagId)" title="编辑备忘" />
|
||||
</label>
|
||||
<img class="ui mini spaced image" id="noteid{{note.id}}" style="width: 16px; height: 16px; margin: 0 8px" ng-src="./images/copy.png" id="url{{bookmark.id}}" ng-click="copy(note.content)" title="复制备忘" />
|
||||
<i class="black share alternate icon" title="复制分享地址" ng-click="share(note)"></i>
|
||||
<i class="black chevron up icon" title="收起详情" ng-click="noteClick(note, true, $event)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 20px" ng-show="notes.length === 0"></div>
|
||||
<div class="ui grid" ng-show="totalItems>0" style="margin: 0px; padding: 0px 14px">
|
||||
<div class="eight wide column" style="padding-top: 26px"><span ng-show="searchWord">通过搜索关键字"{{searchWord}}"(点击菜单"备忘录"重新查看所有),</span>共找到备忘一共约{{totalItems}}个</div>
|
||||
<div class="eight wide column">
|
||||
<pagination></pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui massive text centered inline loader js-hot-loader" style="margin: 10px 0px;" ng-class="{active:loading, disabled:!loading}">正在加载中...</div>
|
||||
|
|
@ -1,84 +1,84 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>提示-404</title>
|
||||
<style type="text/css">
|
||||
html {
|
||||
background: none;
|
||||
background-color: #f0eeee;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#header {
|
||||
width: 952px;
|
||||
margin: 0 auto;
|
||||
height: 120px;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
position: static;
|
||||
}
|
||||
|
||||
#content {
|
||||
font-family: "微软雅黑";
|
||||
background: url("images/404.png") no-repeat 122px 0px;
|
||||
width: 952px;
|
||||
margin: 0 auto;
|
||||
font-size: 18px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#content p {
|
||||
padding: 180px 0 0 426px;
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
#content p a.backhome {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#content p a.backhome span {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#totalSecond {
|
||||
color: #f00;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div id="content" style="height: 530px">
|
||||
<p>
|
||||
对不起,您的风筝已掉线,请时光倒流回前一秒。<br />
|
||||
<span id="totalSecond">5</span>秒后自动
|
||||
<a href="https://b.lucq.fun" class="backhome"><span>返回首页</span></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script language="javascript" type="text/javascript">
|
||||
var second = document.getElementById("totalSecond").textContent;
|
||||
// 判断是IE浏览器还是Firefox浏览器,采用相应措施取得秒数
|
||||
if (navigator.appName.indexOf("Explorer") > -1) {
|
||||
second = document.getElementById("totalSecond").innerText;
|
||||
} else {
|
||||
second = document.getElementById("totalSecond").textContent;
|
||||
}
|
||||
setInterval(function () {
|
||||
if (second < 0) {
|
||||
location.href = document.location.origin;
|
||||
} else {
|
||||
if (navigator.appName.indexOf("Explorer") > -1) {
|
||||
document.getElementById("totalSecond").innerText = second--;
|
||||
} else {
|
||||
document.getElementById("totalSecond").textContent = second--;
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>提示-404</title>
|
||||
<style type="text/css">
|
||||
html {
|
||||
background: none;
|
||||
background-color: #f0eeee;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#header {
|
||||
width: 952px;
|
||||
margin: 0 auto;
|
||||
height: 120px;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
position: static;
|
||||
}
|
||||
|
||||
#content {
|
||||
font-family: "微软雅黑";
|
||||
background: url("images/404.png") no-repeat 122px 0px;
|
||||
width: 952px;
|
||||
margin: 0 auto;
|
||||
font-size: 18px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#content p {
|
||||
padding: 180px 0 0 426px;
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
#content p a.backhome {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#content p a.backhome span {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#totalSecond {
|
||||
color: #f00;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div id="content" style="height: 530px;">
|
||||
<p>
|
||||
对不起,您的风筝已掉线,请时光倒流回前一秒。<br />
|
||||
<span id="totalSecond">5</span>秒后自动
|
||||
<a href="https://mybookmark.cn" class="backhome"><span>返回首页</span></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script language="javascript" type="text/javascript">
|
||||
var second = document.getElementById("totalSecond").textContent;
|
||||
// 判断是IE浏览器还是Firefox浏览器,采用相应措施取得秒数
|
||||
if (navigator.appName.indexOf("Explorer") > -1) {
|
||||
second = document.getElementById("totalSecond").innerText;
|
||||
} else {
|
||||
second = document.getElementById("totalSecond").textContent;
|
||||
}
|
||||
setInterval(function() {
|
||||
if (second < 0) {
|
||||
location.href = document.location.origin;
|
||||
} else {
|
||||
if (navigator.appName.indexOf("Explorer") > -1) {
|
||||
document.getElementById("totalSecond").innerText = second--;
|
||||
} else {
|
||||
document.getElementById("totalSecond").textContent = second--;
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 496 KiB After Width: | Height: | Size: 496 KiB |
|
Before Width: | Height: | Size: 382 KiB After Width: | Height: | Size: 382 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
|
@ -1,195 +1,191 @@
|
|||
body {
|
||||
background-image: url("../images/bg.png");
|
||||
background-repeat: repeat;
|
||||
background-position: top left;
|
||||
background-attachment: scroll;
|
||||
padding-top: 3px;
|
||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
|
||||
font-size: 0.875em;
|
||||
font-weight: bold;
|
||||
padding: 1px 6px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.bookmark {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #212121;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.bookmarkTitle {
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
display: -webkit-box;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.bookmarkNormalHover {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #212121;
|
||||
background: #f5f5f5;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.bookmarkOperaterHover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tags {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.bookmarkEditHover {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #212121;
|
||||
cursor: default;
|
||||
border: 1px dashed #3388ff;
|
||||
}
|
||||
|
||||
.bookmarkInfo {
|
||||
cursor: url("../images/detail.ico"), auto;
|
||||
}
|
||||
|
||||
.img-fixed-size {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
td {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.js-navigate-bookmark a {
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.ui.menu .selected.item {
|
||||
background: rgba(1, 1, 1, 0.05);
|
||||
}
|
||||
|
||||
img.operator {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.js-bookmark-info .content img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.hot-image {
|
||||
max-width: 100%;
|
||||
max-height: 160px;
|
||||
min-height: 160px;
|
||||
background-color: yellow;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sourceName {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
max-width: 55px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.favCount {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
font-size: 12px;
|
||||
color: #bfc0c6;
|
||||
}
|
||||
|
||||
.urlSpan {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ui.sortable.table thead th.forbid_sorted:hover {
|
||||
cursor: default;
|
||||
background: #f9fafb;
|
||||
}
|
||||
|
||||
.ui.selection.list .list > .item,
|
||||
.ui.selection.list > .item {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.js-p-info p {
|
||||
margin-bottom: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.note-content {
|
||||
font: 15px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
white-space: pre-wrap;
|
||||
white-space: -moz-pre-wrap;
|
||||
white-space: -pre-wrap;
|
||||
white-space: -o-pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.fontgreen {
|
||||
color: RGB(33, 186, 69);
|
||||
}
|
||||
|
||||
.fontred {
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.js-history-word:hover {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.js-weixin-content img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.js-search-input {
|
||||
font-size: 14px;
|
||||
}
|
||||
body {
|
||||
background-image: url("../images/bg.png");
|
||||
background-repeat: repeat;
|
||||
background-position: top left;
|
||||
background-attachment: scroll;
|
||||
padding-top: 50px;
|
||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
|
||||
font-size: 0.875em;
|
||||
font-weight: bold;
|
||||
padding: 1px 6px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.bookmark {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #212121;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.bookmarkTitle {
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
display: -webkit-box;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.bookmarkNormalHover {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #212121;
|
||||
background: #f5f5f5;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.bookmarkOperaterHover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tags {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.bookmarkEditHover {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #212121;
|
||||
cursor: default;
|
||||
border: 1px dashed #3388ff;
|
||||
}
|
||||
|
||||
.bookmarkInfo {
|
||||
cursor: url("../images/detail.ico"), auto;
|
||||
}
|
||||
|
||||
.img-fixed-size {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
td {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.js-navigate-bookmark a {
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.ui.menu .selected.item {
|
||||
background: rgba(1, 1, 1, 0.05);
|
||||
}
|
||||
|
||||
img.operator {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.js-bookmark-info .content img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.hot-image {
|
||||
max-width: 100%;
|
||||
max-height: 160px;
|
||||
min-height: 160px;
|
||||
background-color: yellow;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sourceName {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
max-width: 55px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.favCount {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
font-size: 12px;
|
||||
color: #bfc0c6;
|
||||
}
|
||||
|
||||
.urlSpan {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ui.sortable.table thead th.forbid_sorted:hover {
|
||||
cursor: default;
|
||||
background: #f9fafb;
|
||||
}
|
||||
|
||||
.ui.selection.list .list > .item,
|
||||
.ui.selection.list > .item {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.js-p-info p {
|
||||
margin-bottom: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.note-content {
|
||||
font: 15px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
white-space: pre-wrap;
|
||||
white-space: -moz-pre-wrap;
|
||||
white-space: -pre-wrap;
|
||||
white-space: -o-pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.fontgreen {
|
||||
color: RGB(33, 186, 69);
|
||||
}
|
||||
|
||||
.fontred {
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.js-history-word:hover {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.js-weixin-content img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 705 B After Width: | Height: | Size: 705 B |
|
Before Width: | Height: | Size: 687 B After Width: | Height: | Size: 687 B |
|
Before Width: | Height: | Size: 662 B After Width: | Height: | Size: 662 B |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 536 B After Width: | Height: | Size: 536 B |
|
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
|
Before Width: | Height: | Size: 291 B After Width: | Height: | Size: 291 B |
|
Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 438 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 347 B |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 425 B |
|
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 345 B |
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 249 B |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
|
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 371 B |
|
Before Width: | Height: | Size: 389 B After Width: | Height: | Size: 389 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 529 B |
|
Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 438 B |
|
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 320 B |
|
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 266 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 522 B |
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 318 B |
|
Before Width: | Height: | Size: 777 B After Width: | Height: | Size: 777 B |
|
Before Width: | Height: | Size: 623 B After Width: | Height: | Size: 623 B |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 805 B After Width: | Height: | Size: 805 B |
|
Before Width: | Height: | Size: 808 B After Width: | Height: | Size: 808 B |
|
Before Width: | Height: | Size: 507 B After Width: | Height: | Size: 507 B |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
|
@ -1,11 +1,8 @@
|
|||
app.controller('adviceCtr', ['$scope', '$state', '$timeout', '$window', 'pubSubService', 'dataService', function ($scope, $state, $timeout, $window, pubSubService, dataService) {
|
||||
app.controller('adviceCtr', ['$scope', '$state', '$timeout', 'pubSubService', 'dataService', function ($scope, $state, $timeout, pubSubService, dataService) {
|
||||
console.log("Hello adviceCtr");
|
||||
console.log($window.location.hostname);
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
|
||||
|
|
@ -12,6 +12,31 @@ app.controller('bookmarkInfoCtr', ['$scope', '$state', '$timeout', '$sce', '$win
|
|||
bookmark.favicon_url = 'https://favicon.lucq.fun/?url=' + bookmark.url;
|
||||
$scope.bookmark = bookmark;
|
||||
$scope.bookmark.description = $sce.trustAsHtml(bookmark.description);
|
||||
$scope.content = $sce.trustAsHtml(bookmark.content) || '';
|
||||
if (!$scope.content) {
|
||||
$timeout(function () {
|
||||
$('.ui.modal.js-bookmark-info').modal("refresh");
|
||||
$("p").css("word-wrap", "break-word");
|
||||
}, 500);
|
||||
$scope.loading = true;
|
||||
try {
|
||||
let data = get("article", { url: bookmark.url });
|
||||
$scope.content = data.content ? $sce.trustAsHtml(data.content) : $sce.trustAsHtml('<p>数据获取失败,可能是服务器不允许获取,或者是https网站!</p>');
|
||||
setTimeout(function () {
|
||||
$('.ui.modal.js-bookmark-info').modal && $('.ui.modal.js-bookmark-info').modal("refresh");
|
||||
}, 100);
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
$scope.loading = false;
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
$('.ui.modal.js-bookmark-info').modal && $('.ui.modal.js-bookmark-info').modal("refresh");
|
||||
}, 10);
|
||||
setTimeout(function () {
|
||||
$('.modals').animate({ scrollTop: 0 }, 100);
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.jumpToUrl = async function (url, id) {
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
app.controller('bookmarksCtr', ['$scope', '$state', '$stateParams', '$filter', '$window', '$timeout', '$document', 'ngDialog', 'pubSubService', 'dataService', function ($scope, $state, $stateParams, $filter, $window, $timeout, $document, ngDialog, pubSubService, dataService) {
|
||||
console.log("Hello bookmarksCtr...", $stateParams);
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
$state.go('tags');
|
||||
}]);
|
||||
|
|
@ -105,7 +105,7 @@ app.controller('editCtr', ['$scope', '$state', '$timeout', '$document', 'ngDialo
|
|||
}
|
||||
|
||||
$scope.showAddTag = function () {
|
||||
if ($scope.tags.length < 50) {
|
||||
if ($scope.tags.length < 30) {
|
||||
console.log('showAddTag..........')
|
||||
$scope.newTag = "";
|
||||
dialog = ngDialog.open({
|
||||
|
|
@ -114,14 +114,14 @@ app.controller('editCtr', ['$scope', '$state', '$timeout', '$document', 'ngDialo
|
|||
scope: $scope
|
||||
});
|
||||
} else {
|
||||
toastr.error('标签个数总数不能超过50个!不允许再添加新分类,如有需求,请联系管理员。', "提示");
|
||||
toastr.error('标签个数总数不能超过30个!不允许再添加新分类,如有需求,请联系管理员。', "提示");
|
||||
}
|
||||
}
|
||||
|
||||
$scope.addTag = async function (tag) {
|
||||
console.log(tag);
|
||||
if ($scope.tags.length >= 50) {
|
||||
toastr.error('标签个数总数不能超过50个!不允许再添加新分类,如有需求,请联系管理员。', "提示");
|
||||
if ($scope.tags.length >= 30) {
|
||||
toastr.error('标签个数总数不能超过30个!不允许再添加新分类,如有需求,请联系管理员。', "提示");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -188,9 +188,7 @@ app.controller('editCtr', ['$scope', '$state', '$timeout', '$document', 'ngDialo
|
|||
});
|
||||
$scope.public = (bookmark && bookmark.id) || '1';
|
||||
$('.ui.checkbox.js-public').checkbox((bookmark && bookmark.public && bookmark.public == '1') ? 'set checked' : 'set unchecked')
|
||||
$timeout(function () {
|
||||
$scope.loadTags = false;
|
||||
}, 10);
|
||||
$scope.loadTags = false;
|
||||
});
|
||||
|
||||
pubSubService.subscribe('TagCtr.storeBookmark', $scope, function (event, bookmark) {
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
app.controller('homeCtr', ['$scope', '$stateParams', '$filter', '$state', '$window', 'pubSubService', 'dataService', function ($scope, $stateParams, $filter, $state, $window, pubSubService, dataService) {
|
||||
console.log('Hello homeCtr......');
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
app.controller('hotCtr', ['$scope', '$state', '$sce', '$filter', '$window', '$timeout', '$document', 'pubSubService', 'dataService', function ($scope, $state, $sce, $filter, $window, $timeout, $document, pubSubService, dataService) {
|
||||
console.log("Hello hotCtr...");
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
const pageSize = 40;
|
||||
|
|
@ -167,7 +165,7 @@ app.controller('hotCtr', ['$scope', '$state', '$sce', '$filter', '$window', '$ti
|
|||
bookmark.snap = articl.pic || defaultSnap;
|
||||
bookmark.clickCount = articl.likenum;
|
||||
bookmark.createdAt = timeagoInstance.format(articl.addtime * 1000, 'zh_CN');
|
||||
bookmark.content = articl.content.replace(/https:\/\/mmbiz.qpic.cn/gi, "https://favicon.lucq.fun/qpic?url=https://mmbiz.qpic.cn").replace(/http:\/\/mmbiz.qpic.cn/gi, "https://favicon.lucq.fun/qpic?url=https://mmbiz.qpic.cn");
|
||||
bookmark.content = articl.content.replace(/https:\/\/mmbiz.qpic.cn/gi, "http://img01.store.sogou.com/net/a/04/link?appid=100520029&url=https://mmbiz.qpic.cn").replace(/http:\/\/mmbiz.qpic.cn/gi, "http://img01.store.sogou.com/net/a/04/link?appid=100520029&url=https://mmbiz.qpic.cn");
|
||||
bookmark.content = $sce.trustAsHtml(bookmark.content);
|
||||
$scope.bookmarks.push(bookmark);
|
||||
})
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
app.controller('loginCtr', ['$scope', '$filter', '$state', '$http', '$cookieStore', '$window', 'pubSubService', 'dataService', function ($scope, $filter, $state, $http, $cookieStore, $window, pubSubService, dataService) {
|
||||
console.log("Hello loginCtr...");
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
|
||||
|
|
@ -72,7 +70,7 @@ app.controller('loginCtr', ['$scope', '$filter', '$state', '$http', '$cookieStor
|
|||
toastr.error('账号只能是数字字母,且长度必须为3到12位', "错误");
|
||||
return;
|
||||
}
|
||||
if (!/^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test($scope.emailRegister)) {
|
||||
if (!/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test($scope.emailRegister)) {
|
||||
toastr.error('邮箱格式输入有误', "错误");
|
||||
return;
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ app.controller('menuCtr', ['$scope', '$stateParams', '$state', '$window', '$time
|
|||
} else if (searchOption == 3) {
|
||||
$window.open('https://stackoverflow.com/search?q=' + encodeURIComponent(keyword), '_blank');
|
||||
} else if (searchOption == 4) {
|
||||
$window.open('http://www.baidu.com/s?tn=b.lucq.fun&ch=3&ie=utf-8&wd=' + encodeURIComponent(keyword), '_blank');
|
||||
$window.open('http://www.baidu.com/s?tn=mybookmark.cn&ch=3&ie=utf-8&wd=' + encodeURIComponent(keyword), '_blank');
|
||||
} else if (searchOption == 5) {
|
||||
console.log('search note, word = ', keyword);
|
||||
$state.go('note', { keyword }, { reload: true })
|
||||
|
|
@ -200,7 +200,7 @@ app.controller('menuCtr', ['$scope', '$stateParams', '$state', '$window', '$time
|
|||
"#/bookmarks": dataService.LoginIndexBookmarks,
|
||||
"#/tags": dataService.LoginIndexTags,
|
||||
"#/note": dataService.LoginIndexNote,
|
||||
"#/hot": $scope.login ? dataService.LoginIndexHot : dataService.NotLoginIndexHot,
|
||||
"#/weixin-article": $scope.login ? dataService.LoginIndexHot : dataService.NotLoginIndexHot,
|
||||
"#/settings": dataService.LoginIndexSettings,
|
||||
"#/advice": dataService.LoginIndexAdvice,
|
||||
"#/": $scope.login ? dataService.LoginIndexBookmarks : dataService.NotLoginIndexHome,
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
app.controller('noteCtr', ['$scope', '$state', '$stateParams', '$filter', '$window', '$timeout', '$document', 'ngDialog', 'pubSubService', 'dataService', function ($scope, $state, $stateParams, $filter, $window, $timeout, $document, ngDialog, pubSubService, dataService) {
|
||||
console.log("Hello noteCtr...", $stateParams);
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
|
||||
|
|
@ -365,7 +363,6 @@ app.controller('noteCtr', ['$scope', '$state', '$stateParams', '$filter', '$wind
|
|||
|
||||
$timeout(() => {
|
||||
$scope.loading = false;
|
||||
tags.sort((a, b) => a.sort - b.sort);
|
||||
$scope.tags = tags;
|
||||
getNotes();
|
||||
})
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
app.controller('searchCtr', ['$scope', '$state', '$stateParams', '$filter', '$window', '$timeout', '$document', 'ngDialog', 'pubSubService', 'dataService', function ($scope, $state, $stateParams, $filter, $window, $timeout, $document, ngDialog, pubSubService, dataService) {
|
||||
console.log("Hello searchCtr...", $stateParams);
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
app.controller('settingsCtr', ['$scope', '$stateParams', '$filter', '$state', '$window', '$timeout', 'pubSubService', 'dataService', function ($scope, $stateParams, $filter, $state, $window, $timeout, pubSubService, dataService) {
|
||||
console.log('Hello settingsCtr......', $stateParams);
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
app.controller('tagsCtr', ['$scope', '$filter', '$state', '$window', '$stateParams', '$timeout', '$document', 'ngDialog', 'pubSubService', 'dataService', function ($scope, $filter, $state, $window, $stateParams, $timeout, $document, ngDialog, pubSubService, dataService) {
|
||||
console.log("Hello tagsCtr...", $stateParams);
|
||||
if (dataService.smallDevice()) {
|
||||
if ($window.location.hostname.indexOf("b.lucq.fun") >= 0) {
|
||||
$window.location = "http://mb.lucq.fun/#/tags";
|
||||
return;
|
||||
}
|
||||
$window.location = "http://m.mybookmark.cn/#/tags";
|
||||
return;
|
||||
}
|
||||
pubSubService.publish('Menus.active');
|
||||
|
||||
|
|
@ -29,7 +27,6 @@ app.controller('tagsCtr', ['$scope', '$filter', '$state', '$window', '$statePara
|
|||
$scope.bookmarks = [];
|
||||
$scope.totalPages = 0;
|
||||
$scope.currentPage = 0;
|
||||
$scope.pageSize = 80;
|
||||
$scope.inputPage = '';
|
||||
$scope.currentTagId = ($stateParams && $stateParams.tagId) || (-1);
|
||||
$scope.editMode = false;
|
||||
|
|
@ -48,7 +45,7 @@ app.controller('tagsCtr', ['$scope', '$filter', '$state', '$window', '$statePara
|
|||
showType && ($scope.showType = showType);
|
||||
$scope.loading = true;
|
||||
|
||||
let pageSize = ($scope.showMode == 'item') ? $scope.pageSize : 20;
|
||||
let pageSize = ($scope.showMode == 'item') ? 50 : 20;
|
||||
|
||||
for (let tag of $scope.tags) {
|
||||
tag.bookmarkClicked = (tag.id == $scope.currentTagId);
|
||||
|
|
@ -88,10 +85,6 @@ app.controller('tagsCtr', ['$scope', '$filter', '$state', '$window', '$statePara
|
|||
clearInterval(id);
|
||||
}
|
||||
}, 10);
|
||||
} else if ($scope.showMode == 'item' && bookmarks.length > $scope.pageSize / 2 && $scope.currentTagId == -1) {
|
||||
$timeout(() => {
|
||||
$("#" + bookmarks[bookmarks.length / 2 - 1].id).after(`<div class="ui divider" style="width:100%;margin:0px 15px -1px 15px"></div>`);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
$timeout(function () {
|
||||
|
|
@ -280,7 +273,7 @@ app.controller('tagsCtr', ['$scope', '$filter', '$state', '$window', '$statePara
|
|||
|
||||
$scope.addTag = async function (tag) {
|
||||
console.log(tag);
|
||||
if ($scope.tags.length >= 50) {
|
||||
if ($scope.tags.length >= 30) {
|
||||
toastr.error('标签个数总数不能超过30个!不允许再添加新分类,如有需求,请联系管理员。', "提示");
|
||||
return;
|
||||
}
|
||||
|
|
@ -373,8 +366,7 @@ app.controller('tagsCtr', ['$scope', '$filter', '$state', '$window', '$statePara
|
|||
bookmarkCount: '...',
|
||||
bookmarkClicked: false,
|
||||
name: '全部',
|
||||
show: 1,
|
||||
sort: -1
|
||||
show: 1
|
||||
})
|
||||
|
||||
let find = false;
|
||||
|
|
@ -392,8 +384,6 @@ app.controller('tagsCtr', ['$scope', '$filter', '$state', '$window', '$statePara
|
|||
tags[0].bookmarkClicked = true;
|
||||
}
|
||||
|
||||
tags.sort((a, b) => a.sort - b.sort);
|
||||
|
||||
$timeout(() => {
|
||||
$scope.loading = false;
|
||||
$scope.tags = tags;
|
||||