├── .DS_Store ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── app.js ├── db ├── WiredTiger ├── WiredTiger.lock ├── WiredTiger.turtle ├── WiredTiger.wt ├── WiredTigerLAS.wt ├── _mdb_catalog.wt ├── collection-0--4065603976777118248.wt ├── collection-0--4163166641293810810.wt ├── collection-0-3081478506285748160.wt ├── collection-2--4065603976777118248.wt ├── collection-2-3081478506285748160.wt ├── collection-4-3081478506285748160.wt ├── diagnostic.data │ ├── metrics.2018-01-02T01-55-30Z-00000 │ ├── metrics.2018-01-03T07-06-00Z-00000 │ ├── metrics.2018-01-05T00-59-05Z-00000 │ ├── metrics.2018-01-05T23-39-09Z-00000 │ ├── metrics.2018-01-06T13-06-30Z-00000 │ └── metrics.interim ├── index-1--4065603976777118248.wt ├── index-1--4163166641293810810.wt ├── index-1-3081478506285748160.wt ├── index-3--4065603976777118248.wt ├── index-3-3081478506285748160.wt ├── index-5-3081478506285748160.wt ├── index-6-3081478506285748160.wt ├── journal │ ├── WiredTigerLog.0000000005 │ ├── WiredTigerPreplog.0000000001 │ └── WiredTigerPreplog.0000000002 ├── mongod.lock ├── sizeStorer.wt └── storage.bson ├── models ├── Category.js ├── Content.js └── User.js ├── package-lock.json ├── package.json ├── public ├── .DS_Store ├── css │ ├── bootstrap-theme.min.css │ ├── bootstrap.min.css │ ├── main.css │ └── util.css ├── font │ ├── iconfont.eot │ ├── iconfont.svg │ ├── iconfont.ttf │ └── iconfont.woff ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── image │ ├── .DS_Store │ ├── banner.jpg │ ├── logo.png │ └── test.jpg └── js │ ├── bootstrap.min.js │ ├── jquery-1.8.3.min.js │ ├── main.js │ └── markdown.js ├── router ├── admin.js ├── api.js └── main.js ├── schemas ├── categorise.js ├── contents.js └── users.js ├── static ├── .DS_Store ├── README_img │ ├── WechatIMG5212.jpeg │ ├── WechatIMG5213.jpeg │ ├── WechatIMG5214.jpeg │ └── WechatIMG5215.jpeg └── fePage │ ├── .DS_Store │ ├── .idea │ ├── .name │ ├── dictionaries │ │ └── James.xml │ ├── encodings.xml │ ├── fePage.iml │ ├── misc.xml │ ├── modules.xml │ └── workspace.xml │ ├── css │ ├── main.css │ └── util.css │ ├── detail.html │ ├── font │ ├── iconfont.eot │ ├── iconfont.svg │ ├── iconfont.ttf │ └── iconfont.woff │ ├── image │ ├── .DS_Store │ ├── banner.jpg │ ├── logo.png │ └── test.jpg │ ├── index.html │ └── js │ ├── jquery-1.8.3.min.js │ └── main.js └── view ├── admin ├── category_add.html ├── category_edit.html ├── category_index.html ├── content_add.html ├── content_edit.html ├── content_index.html ├── error.html ├── index.html ├── layout.html ├── page.html ├── success.html └── user_index.html ├── index.html └── main ├── detail.html └── index.html /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 JamesSky 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 项目描述 2 | =========================== 3 | 这是一个基于node的博客,拥有博客基本的前后台功能,在static下有静态模版文件 4 | 5 | **** 6 | ## 启动方式 7 | 下载到本地后,cd到当前目录,安装package.json所需依赖包,然后启动入口文件 8 | ```javascript 9 | node app.js 10 | ``` 11 | 12 | ## 项目使用条件 13 | - [x] nodejs环境 14 | - [x] mongodb 15 | 16 | ## 页面所拥有功能如下 17 | ``` 18 | 后台: 19 | 1.后台用户管理; 20 | 2.博客分类及增删改查; 21 | 3.博客文章及增删改查(文章内容支持markdown); 22 | 23 | 前台: 24 | 1.导航; 25 | 2.文章及分页; 26 | 3.登录注册; 27 | 4.文章页; 28 | 5.评论功能 29 | 30 | ``` 31 | 32 | ## 涉及技术 33 | ``` 34 | mongodb 35 | swig模版 36 | express 37 | 38 | ``` 39 | 40 | ## 页面效果 41 | 42 | * 首页 43 | ![首页](./static/README_img/WechatIMG5212.jpeg) 44 | 45 | * 文章页 46 | ![文章页](./static/README_img/WechatIMG5213.jpeg) 47 | 48 | * 文章页评论 49 | ![文章页评论](./static/README_img/WechatIMG5214.jpeg) 50 | 51 | * 后台界面 52 | ![后台界面](./static/README_img/WechatIMG5215.jpeg) 53 | 54 | 55 | ## License 56 | [MIT](/LICENSE) 57 | 58 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 页面入口文件 3 | */ 4 | 5 | const express = require('express'); 6 | // 引入模版文件 7 | const swig = require('swig'); 8 | // 引入body-parse,处理传递过来的数据 9 | const bodyParse = require('body-parser'); 10 | // user表 11 | const User = require('./models/User'); 12 | const app = express(); 13 | // cookies 14 | const Cookies = require('cookies'); 15 | // 加载数据库模块 16 | const mongoose = require("mongoose"); 17 | // 设置静态文件托管,如果访问/pub,则转到public下找资源文件,并不解析为html 18 | app.use('/public',express.static(`${__dirname}/public`)); 19 | // 设置模版引擎 20 | app.engine('html',swig.renderFile); 21 | // 设置模版文件存放目录 第一个参数固定为views 22 | app.set('views','./view'); 23 | // 注册模版引擎,第一个参数固定为view engine 24 | app.set('view engine','html'); 25 | // 在开发过程中取消模版的缓存 26 | swig.setDefaults({cache: false}); 27 | // 设置body-parse 28 | app.use( bodyParse.urlencoded({extended: true}) ); 29 | // 设置cookies 30 | app.use((req, res, next)=>{ 31 | req.cookies = new Cookies(req, res); 32 | req.userInfo = {}; 33 | if( req.cookies.get('userInfo') ){ 34 | try { 35 | req.userInfo = JSON.parse( req.cookies.get('userInfo') ); 36 | User.findById(req.userInfo._id).then((userInfo)=>{ 37 | req.userInfo.isAdmin = Boolean( userInfo.isAdmin ); 38 | next(); 39 | }); 40 | } catch (error) { 41 | next(); 42 | } 43 | }else{ 44 | next(); 45 | } 46 | }); 47 | // 访问后台页面 48 | app.use('/admin',require('./router/admin')); 49 | // 访问api接口 50 | app.use('/api',require('./router/api')); 51 | // 访问页面 52 | app.use('/',require('./router/main')); 53 | 54 | mongoose.connect('mongodb://localhost:27018/blog',function(err){ 55 | if(err){ 56 | console.log('数据库连接失败'); 57 | }else{ 58 | console.log('数据库连接成功'); 59 | app.listen(2020); 60 | } 61 | }); -------------------------------------------------------------------------------- /db/WiredTiger: -------------------------------------------------------------------------------- 1 | WiredTiger 2 | WiredTiger 3.0.0: (June 27, 2017) 3 | -------------------------------------------------------------------------------- /db/WiredTiger.lock: -------------------------------------------------------------------------------- 1 | WiredTiger lock file 2 | -------------------------------------------------------------------------------- /db/WiredTiger.turtle: -------------------------------------------------------------------------------- 1 | WiredTiger version string 2 | WiredTiger 3.0.0: (June 27, 2017) 3 | WiredTiger version 4 | major=3,minor=0,patch=0 5 | file:WiredTiger.wt 6 | access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,read_timestamp=none),block_allocation=best,block_compressor=,cache_resident=false,checkpoint=(WiredTigerCheckpoint.483=(addr="018081e4f9a82e028181e42c703ca38281e41ca436b0808080e3010fc0e23fc0",order=483,time=1515321572,size=28672,write_gen=966)),checkpoint_lsn=(5,160896),checksum=uncompressed,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,value_format=S,version=(major=1,minor=1) 7 | -------------------------------------------------------------------------------- /db/WiredTiger.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/WiredTiger.wt -------------------------------------------------------------------------------- /db/WiredTigerLAS.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/WiredTigerLAS.wt -------------------------------------------------------------------------------- /db/_mdb_catalog.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/_mdb_catalog.wt -------------------------------------------------------------------------------- /db/collection-0--4065603976777118248.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/collection-0--4065603976777118248.wt -------------------------------------------------------------------------------- /db/collection-0--4163166641293810810.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/collection-0--4163166641293810810.wt -------------------------------------------------------------------------------- /db/collection-0-3081478506285748160.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/collection-0-3081478506285748160.wt -------------------------------------------------------------------------------- /db/collection-2--4065603976777118248.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/collection-2--4065603976777118248.wt -------------------------------------------------------------------------------- /db/collection-2-3081478506285748160.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/collection-2-3081478506285748160.wt -------------------------------------------------------------------------------- /db/collection-4-3081478506285748160.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/collection-4-3081478506285748160.wt -------------------------------------------------------------------------------- /db/diagnostic.data/metrics.2018-01-02T01-55-30Z-00000: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/diagnostic.data/metrics.2018-01-02T01-55-30Z-00000 -------------------------------------------------------------------------------- /db/diagnostic.data/metrics.2018-01-03T07-06-00Z-00000: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/diagnostic.data/metrics.2018-01-03T07-06-00Z-00000 -------------------------------------------------------------------------------- /db/diagnostic.data/metrics.2018-01-05T00-59-05Z-00000: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/diagnostic.data/metrics.2018-01-05T00-59-05Z-00000 -------------------------------------------------------------------------------- /db/diagnostic.data/metrics.2018-01-05T23-39-09Z-00000: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/diagnostic.data/metrics.2018-01-05T23-39-09Z-00000 -------------------------------------------------------------------------------- /db/diagnostic.data/metrics.2018-01-06T13-06-30Z-00000: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/diagnostic.data/metrics.2018-01-06T13-06-30Z-00000 -------------------------------------------------------------------------------- /db/diagnostic.data/metrics.interim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/diagnostic.data/metrics.interim -------------------------------------------------------------------------------- /db/index-1--4065603976777118248.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/index-1--4065603976777118248.wt -------------------------------------------------------------------------------- /db/index-1--4163166641293810810.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/index-1--4163166641293810810.wt -------------------------------------------------------------------------------- /db/index-1-3081478506285748160.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/index-1-3081478506285748160.wt -------------------------------------------------------------------------------- /db/index-3--4065603976777118248.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/index-3--4065603976777118248.wt -------------------------------------------------------------------------------- /db/index-3-3081478506285748160.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/index-3-3081478506285748160.wt -------------------------------------------------------------------------------- /db/index-5-3081478506285748160.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/index-5-3081478506285748160.wt -------------------------------------------------------------------------------- /db/index-6-3081478506285748160.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/index-6-3081478506285748160.wt -------------------------------------------------------------------------------- /db/journal/WiredTigerLog.0000000005: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/journal/WiredTigerLog.0000000005 -------------------------------------------------------------------------------- /db/journal/WiredTigerPreplog.0000000001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/journal/WiredTigerPreplog.0000000001 -------------------------------------------------------------------------------- /db/journal/WiredTigerPreplog.0000000002: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/journal/WiredTigerPreplog.0000000002 -------------------------------------------------------------------------------- /db/mongod.lock: -------------------------------------------------------------------------------- 1 | 2317 2 | -------------------------------------------------------------------------------- /db/sizeStorer.wt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/db/sizeStorer.wt -------------------------------------------------------------------------------- /db/storage.bson: -------------------------------------------------------------------------------- 1 | rstoragedengine wiredTigeroptions?directoryPerDBdirectoryForIndexesgroupCollections -------------------------------------------------------------------------------- /models/Category.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const categoriseSchema = require('../schemas/categorise'); 3 | 4 | module.exports = mongoose.model('Category', categoriseSchema); -------------------------------------------------------------------------------- /models/Content.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const contentsSchema = require('../schemas/contents'); 3 | 4 | module.exports = mongoose.model('Content', contentsSchema); -------------------------------------------------------------------------------- /models/User.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const usersSchema = require('../schemas/users'); 3 | 4 | module.exports = mongoose.model('User', usersSchema); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jamesblog", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "http://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz", 10 | "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=" 11 | }, 12 | "accepts": { 13 | "version": "1.3.4", 14 | "resolved": "http://registry.npm.taobao.org/accepts/download/accepts-1.3.4.tgz", 15 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", 16 | "requires": { 17 | "mime-types": "2.1.17", 18 | "negotiator": "0.6.1" 19 | } 20 | }, 21 | "amdefine": { 22 | "version": "1.0.1", 23 | "resolved": "http://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz", 24 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" 25 | }, 26 | "array-flatten": { 27 | "version": "1.1.1", 28 | "resolved": "http://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz", 29 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 30 | }, 31 | "async": { 32 | "version": "2.1.4", 33 | "resolved": "http://registry.npm.taobao.org/async/download/async-2.1.4.tgz", 34 | "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", 35 | "requires": { 36 | "lodash": "4.17.4" 37 | } 38 | }, 39 | "bluebird": { 40 | "version": "3.5.0", 41 | "resolved": "http://registry.npm.taobao.org/bluebird/download/bluebird-3.5.0.tgz", 42 | "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" 43 | }, 44 | "body-parser": { 45 | "version": "1.18.2", 46 | "resolved": "http://registry.npm.taobao.org/body-parser/download/body-parser-1.18.2.tgz", 47 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", 48 | "requires": { 49 | "bytes": "3.0.0", 50 | "content-type": "1.0.4", 51 | "debug": "2.6.9", 52 | "depd": "1.1.1", 53 | "http-errors": "1.6.2", 54 | "iconv-lite": "0.4.19", 55 | "on-finished": "2.3.0", 56 | "qs": "6.5.1", 57 | "raw-body": "2.3.2", 58 | "type-is": "1.6.15" 59 | } 60 | }, 61 | "bson": { 62 | "version": "1.0.4", 63 | "resolved": "http://registry.npm.taobao.org/bson/download/bson-1.0.4.tgz", 64 | "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" 65 | }, 66 | "bytes": { 67 | "version": "3.0.0", 68 | "resolved": "http://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz", 69 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 70 | }, 71 | "camelcase": { 72 | "version": "1.2.1", 73 | "resolved": "http://registry.npm.taobao.org/camelcase/download/camelcase-1.2.1.tgz", 74 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" 75 | }, 76 | "content-disposition": { 77 | "version": "0.5.2", 78 | "resolved": "http://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.2.tgz", 79 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 80 | }, 81 | "content-type": { 82 | "version": "1.0.4", 83 | "resolved": "http://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz", 84 | "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" 85 | }, 86 | "cookie": { 87 | "version": "0.3.1", 88 | "resolved": "http://registry.npm.taobao.org/cookie/download/cookie-0.3.1.tgz", 89 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 90 | }, 91 | "cookie-signature": { 92 | "version": "1.0.6", 93 | "resolved": "http://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz", 94 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 95 | }, 96 | "cookies": { 97 | "version": "0.7.1", 98 | "resolved": "http://registry.npm.taobao.org/cookies/download/cookies-0.7.1.tgz", 99 | "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=", 100 | "requires": { 101 | "depd": "1.1.1", 102 | "keygrip": "1.0.2" 103 | } 104 | }, 105 | "debug": { 106 | "version": "2.6.9", 107 | "resolved": "http://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz", 108 | "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", 109 | "requires": { 110 | "ms": "2.0.0" 111 | } 112 | }, 113 | "decamelize": { 114 | "version": "1.2.0", 115 | "resolved": "http://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz", 116 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 117 | }, 118 | "depd": { 119 | "version": "1.1.1", 120 | "resolved": "http://registry.npm.taobao.org/depd/download/depd-1.1.1.tgz", 121 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 122 | }, 123 | "destroy": { 124 | "version": "1.0.4", 125 | "resolved": "http://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz", 126 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 127 | }, 128 | "ee-first": { 129 | "version": "1.1.1", 130 | "resolved": "http://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz", 131 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 132 | }, 133 | "encodeurl": { 134 | "version": "1.0.1", 135 | "resolved": "http://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.1.tgz", 136 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" 137 | }, 138 | "escape-html": { 139 | "version": "1.0.3", 140 | "resolved": "http://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz", 141 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 142 | }, 143 | "etag": { 144 | "version": "1.8.1", 145 | "resolved": "http://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz", 146 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 147 | }, 148 | "express": { 149 | "version": "4.16.2", 150 | "resolved": "http://registry.npm.taobao.org/express/download/express-4.16.2.tgz", 151 | "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", 152 | "requires": { 153 | "accepts": "1.3.4", 154 | "array-flatten": "1.1.1", 155 | "body-parser": "1.18.2", 156 | "content-disposition": "0.5.2", 157 | "content-type": "1.0.4", 158 | "cookie": "0.3.1", 159 | "cookie-signature": "1.0.6", 160 | "debug": "2.6.9", 161 | "depd": "1.1.1", 162 | "encodeurl": "1.0.1", 163 | "escape-html": "1.0.3", 164 | "etag": "1.8.1", 165 | "finalhandler": "1.1.0", 166 | "fresh": "0.5.2", 167 | "merge-descriptors": "1.0.1", 168 | "methods": "1.1.2", 169 | "on-finished": "2.3.0", 170 | "parseurl": "1.3.2", 171 | "path-to-regexp": "0.1.7", 172 | "proxy-addr": "2.0.2", 173 | "qs": "6.5.1", 174 | "range-parser": "1.2.0", 175 | "safe-buffer": "5.1.1", 176 | "send": "0.16.1", 177 | "serve-static": "1.13.1", 178 | "setprototypeof": "1.1.0", 179 | "statuses": "1.3.1", 180 | "type-is": "1.6.15", 181 | "utils-merge": "1.0.1", 182 | "vary": "1.1.2" 183 | } 184 | }, 185 | "finalhandler": { 186 | "version": "1.1.0", 187 | "resolved": "http://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.0.tgz", 188 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", 189 | "requires": { 190 | "debug": "2.6.9", 191 | "encodeurl": "1.0.1", 192 | "escape-html": "1.0.3", 193 | "on-finished": "2.3.0", 194 | "parseurl": "1.3.2", 195 | "statuses": "1.3.1", 196 | "unpipe": "1.0.0" 197 | } 198 | }, 199 | "forwarded": { 200 | "version": "0.1.2", 201 | "resolved": "http://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz", 202 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 203 | }, 204 | "fresh": { 205 | "version": "0.5.2", 206 | "resolved": "http://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz", 207 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 208 | }, 209 | "http-errors": { 210 | "version": "1.6.2", 211 | "resolved": "http://registry.npm.taobao.org/http-errors/download/http-errors-1.6.2.tgz", 212 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 213 | "requires": { 214 | "depd": "1.1.1", 215 | "inherits": "2.0.3", 216 | "setprototypeof": "1.0.3", 217 | "statuses": "1.3.1" 218 | }, 219 | "dependencies": { 220 | "setprototypeof": { 221 | "version": "1.0.3", 222 | "resolved": "http://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.0.3.tgz", 223 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 224 | } 225 | } 226 | }, 227 | "iconv-lite": { 228 | "version": "0.4.19", 229 | "resolved": "http://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.19.tgz", 230 | "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" 231 | }, 232 | "inherits": { 233 | "version": "2.0.3", 234 | "resolved": "http://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz", 235 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 236 | }, 237 | "ipaddr.js": { 238 | "version": "1.5.2", 239 | "resolved": "http://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.5.2.tgz", 240 | "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" 241 | }, 242 | "kareem": { 243 | "version": "2.0.0-rc5", 244 | "resolved": "http://registry.npm.taobao.org/kareem/download/kareem-2.0.0-rc5.tgz", 245 | "integrity": "sha1-mJnHRfZfl1WcJiiM8mmp8wgjr4Y=" 246 | }, 247 | "keygrip": { 248 | "version": "1.0.2", 249 | "resolved": "http://registry.npm.taobao.org/keygrip/download/keygrip-1.0.2.tgz", 250 | "integrity": "sha1-rTKXxVcGneqLz+ek+kkbdcXd65E=" 251 | }, 252 | "lodash": { 253 | "version": "4.17.4", 254 | "resolved": "http://registry.npm.taobao.org/lodash/download/lodash-4.17.4.tgz", 255 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 256 | }, 257 | "lodash.get": { 258 | "version": "4.4.2", 259 | "resolved": "http://registry.npm.taobao.org/lodash.get/download/lodash.get-4.4.2.tgz", 260 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" 261 | }, 262 | "markdown": { 263 | "version": "0.5.0", 264 | "resolved": "http://registry.npm.taobao.org/markdown/download/markdown-0.5.0.tgz", 265 | "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=", 266 | "requires": { 267 | "nopt": "2.1.2" 268 | } 269 | }, 270 | "media-typer": { 271 | "version": "0.3.0", 272 | "resolved": "http://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz", 273 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 274 | }, 275 | "merge-descriptors": { 276 | "version": "1.0.1", 277 | "resolved": "http://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz", 278 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 279 | }, 280 | "methods": { 281 | "version": "1.1.2", 282 | "resolved": "http://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz", 283 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 284 | }, 285 | "mime": { 286 | "version": "1.4.1", 287 | "resolved": "http://registry.npm.taobao.org/mime/download/mime-1.4.1.tgz", 288 | "integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY=" 289 | }, 290 | "mime-db": { 291 | "version": "1.30.0", 292 | "resolved": "http://registry.npm.taobao.org/mime-db/download/mime-db-1.30.0.tgz", 293 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" 294 | }, 295 | "mime-types": { 296 | "version": "2.1.17", 297 | "resolved": "http://registry.npm.taobao.org/mime-types/download/mime-types-2.1.17.tgz", 298 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", 299 | "requires": { 300 | "mime-db": "1.30.0" 301 | } 302 | }, 303 | "minimist": { 304 | "version": "0.0.10", 305 | "resolved": "http://registry.npm.taobao.org/minimist/download/minimist-0.0.10.tgz", 306 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" 307 | }, 308 | "mongodb": { 309 | "version": "3.0.1", 310 | "resolved": "http://registry.npm.taobao.org/mongodb/download/mongodb-3.0.1.tgz", 311 | "integrity": "sha1-J47oAGJX7CJ5hZSmJZVGgl1t4bI=", 312 | "requires": { 313 | "mongodb-core": "3.0.1" 314 | } 315 | }, 316 | "mongodb-core": { 317 | "version": "3.0.1", 318 | "resolved": "http://registry.npm.taobao.org/mongodb-core/download/mongodb-core-3.0.1.tgz", 319 | "integrity": "sha1-/23Dbulv9ZaVPYCmhA1nMbyS7+0=", 320 | "requires": { 321 | "bson": "1.0.4", 322 | "require_optional": "1.0.1" 323 | } 324 | }, 325 | "mongoose": { 326 | "version": "5.0.0-rc0", 327 | "resolved": "http://registry.npm.taobao.org/mongoose/download/mongoose-5.0.0-rc0.tgz", 328 | "integrity": "sha1-a002CwbbCvlR2hi/0bgTpThcJeA=", 329 | "requires": { 330 | "async": "2.1.4", 331 | "bson": "1.0.4", 332 | "kareem": "2.0.0-rc5", 333 | "lodash.get": "4.4.2", 334 | "mongodb": "3.0.1", 335 | "mongoose-legacy-pluralize": "1.0.1", 336 | "mpath": "0.3.0", 337 | "mquery": "3.0.0-rc0", 338 | "ms": "2.0.0", 339 | "regexp-clone": "0.0.1", 340 | "sliced": "1.0.1" 341 | } 342 | }, 343 | "mongoose-legacy-pluralize": { 344 | "version": "1.0.1", 345 | "resolved": "http://registry.npm.taobao.org/mongoose-legacy-pluralize/download/mongoose-legacy-pluralize-1.0.1.tgz", 346 | "integrity": "sha1-Ma4l20XDDxRIwPk/UnaekDNnxwE=" 347 | }, 348 | "mpath": { 349 | "version": "0.3.0", 350 | "resolved": "http://registry.npm.taobao.org/mpath/download/mpath-0.3.0.tgz", 351 | "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q=" 352 | }, 353 | "mquery": { 354 | "version": "3.0.0-rc0", 355 | "resolved": "http://registry.npm.taobao.org/mquery/download/mquery-3.0.0-rc0.tgz", 356 | "integrity": "sha1-BexlbpLweYKL7fQgLmD7jqrLn0c=", 357 | "requires": { 358 | "bluebird": "3.5.0", 359 | "debug": "2.6.9", 360 | "regexp-clone": "0.0.1", 361 | "sliced": "0.0.5" 362 | }, 363 | "dependencies": { 364 | "sliced": { 365 | "version": "0.0.5", 366 | "resolved": "http://registry.npm.taobao.org/sliced/download/sliced-0.0.5.tgz", 367 | "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" 368 | } 369 | } 370 | }, 371 | "ms": { 372 | "version": "2.0.0", 373 | "resolved": "http://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz", 374 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 375 | }, 376 | "negotiator": { 377 | "version": "0.6.1", 378 | "resolved": "http://registry.npm.taobao.org/negotiator/download/negotiator-0.6.1.tgz", 379 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 380 | }, 381 | "nopt": { 382 | "version": "2.1.2", 383 | "resolved": "http://registry.npm.taobao.org/nopt/download/nopt-2.1.2.tgz", 384 | "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=", 385 | "requires": { 386 | "abbrev": "1.1.1" 387 | } 388 | }, 389 | "on-finished": { 390 | "version": "2.3.0", 391 | "resolved": "http://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz", 392 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 393 | "requires": { 394 | "ee-first": "1.1.1" 395 | } 396 | }, 397 | "optimist": { 398 | "version": "0.6.1", 399 | "resolved": "http://registry.npm.taobao.org/optimist/download/optimist-0.6.1.tgz", 400 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 401 | "requires": { 402 | "minimist": "0.0.10", 403 | "wordwrap": "0.0.3" 404 | } 405 | }, 406 | "parseurl": { 407 | "version": "1.3.2", 408 | "resolved": "http://registry.npm.taobao.org/parseurl/download/parseurl-1.3.2.tgz", 409 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 410 | }, 411 | "path-to-regexp": { 412 | "version": "0.1.7", 413 | "resolved": "http://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz", 414 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 415 | }, 416 | "proxy-addr": { 417 | "version": "2.0.2", 418 | "resolved": "http://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.2.tgz", 419 | "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", 420 | "requires": { 421 | "forwarded": "0.1.2", 422 | "ipaddr.js": "1.5.2" 423 | } 424 | }, 425 | "qs": { 426 | "version": "6.5.1", 427 | "resolved": "http://registry.npm.taobao.org/qs/download/qs-6.5.1.tgz", 428 | "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=" 429 | }, 430 | "range-parser": { 431 | "version": "1.2.0", 432 | "resolved": "http://registry.npm.taobao.org/range-parser/download/range-parser-1.2.0.tgz", 433 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 434 | }, 435 | "raw-body": { 436 | "version": "2.3.2", 437 | "resolved": "http://registry.npm.taobao.org/raw-body/download/raw-body-2.3.2.tgz", 438 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 439 | "requires": { 440 | "bytes": "3.0.0", 441 | "http-errors": "1.6.2", 442 | "iconv-lite": "0.4.19", 443 | "unpipe": "1.0.0" 444 | } 445 | }, 446 | "regexp-clone": { 447 | "version": "0.0.1", 448 | "resolved": "http://registry.npm.taobao.org/regexp-clone/download/regexp-clone-0.0.1.tgz", 449 | "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" 450 | }, 451 | "require_optional": { 452 | "version": "1.0.1", 453 | "resolved": "http://registry.npm.taobao.org/require_optional/download/require_optional-1.0.1.tgz", 454 | "integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=", 455 | "requires": { 456 | "resolve-from": "2.0.0", 457 | "semver": "5.4.1" 458 | } 459 | }, 460 | "resolve-from": { 461 | "version": "2.0.0", 462 | "resolved": "http://registry.npm.taobao.org/resolve-from/download/resolve-from-2.0.0.tgz", 463 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 464 | }, 465 | "safe-buffer": { 466 | "version": "5.1.1", 467 | "resolved": "http://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.1.tgz", 468 | "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" 469 | }, 470 | "semver": { 471 | "version": "5.4.1", 472 | "resolved": "http://registry.npm.taobao.org/semver/download/semver-5.4.1.tgz", 473 | "integrity": "sha1-4FnAnYVx8FQII3M0M1BdOi8AsY4=" 474 | }, 475 | "send": { 476 | "version": "0.16.1", 477 | "resolved": "http://registry.npm.taobao.org/send/download/send-0.16.1.tgz", 478 | "integrity": "sha1-pw4coh0TgsEdDZ9iMd6ygQgNerM=", 479 | "requires": { 480 | "debug": "2.6.9", 481 | "depd": "1.1.1", 482 | "destroy": "1.0.4", 483 | "encodeurl": "1.0.1", 484 | "escape-html": "1.0.3", 485 | "etag": "1.8.1", 486 | "fresh": "0.5.2", 487 | "http-errors": "1.6.2", 488 | "mime": "1.4.1", 489 | "ms": "2.0.0", 490 | "on-finished": "2.3.0", 491 | "range-parser": "1.2.0", 492 | "statuses": "1.3.1" 493 | } 494 | }, 495 | "serve-static": { 496 | "version": "1.13.1", 497 | "resolved": "http://registry.npm.taobao.org/serve-static/download/serve-static-1.13.1.tgz", 498 | "integrity": "sha1-TFfVNASnYdjy58HooYpH2/J4pxk=", 499 | "requires": { 500 | "encodeurl": "1.0.1", 501 | "escape-html": "1.0.3", 502 | "parseurl": "1.3.2", 503 | "send": "0.16.1" 504 | } 505 | }, 506 | "setprototypeof": { 507 | "version": "1.1.0", 508 | "resolved": "http://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.0.tgz", 509 | "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=" 510 | }, 511 | "sliced": { 512 | "version": "1.0.1", 513 | "resolved": "http://registry.npm.taobao.org/sliced/download/sliced-1.0.1.tgz", 514 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 515 | }, 516 | "source-map": { 517 | "version": "0.1.34", 518 | "resolved": "http://registry.npm.taobao.org/source-map/download/source-map-0.1.34.tgz", 519 | "integrity": "sha1-p8/omux7FoLDsZjQrPtH19CQVms=", 520 | "requires": { 521 | "amdefine": "1.0.1" 522 | } 523 | }, 524 | "statuses": { 525 | "version": "1.3.1", 526 | "resolved": "http://registry.npm.taobao.org/statuses/download/statuses-1.3.1.tgz", 527 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 528 | }, 529 | "swig": { 530 | "version": "1.4.2", 531 | "resolved": "http://registry.npm.taobao.org/swig/download/swig-1.4.2.tgz", 532 | "integrity": "sha1-QIXKBFM2kQS11IPihBs5t64aq6U=", 533 | "requires": { 534 | "optimist": "0.6.1", 535 | "uglify-js": "2.4.24" 536 | } 537 | }, 538 | "type-is": { 539 | "version": "1.6.15", 540 | "resolved": "http://registry.npm.taobao.org/type-is/download/type-is-1.6.15.tgz", 541 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", 542 | "requires": { 543 | "media-typer": "0.3.0", 544 | "mime-types": "2.1.17" 545 | } 546 | }, 547 | "uglify-js": { 548 | "version": "2.4.24", 549 | "resolved": "http://registry.npm.taobao.org/uglify-js/download/uglify-js-2.4.24.tgz", 550 | "integrity": "sha1-+tV1XB4Vd2WLsG/5q25UjJW+vW4=", 551 | "requires": { 552 | "async": "0.2.10", 553 | "source-map": "0.1.34", 554 | "uglify-to-browserify": "1.0.2", 555 | "yargs": "3.5.4" 556 | }, 557 | "dependencies": { 558 | "async": { 559 | "version": "0.2.10", 560 | "resolved": "http://registry.npm.taobao.org/async/download/async-0.2.10.tgz", 561 | "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" 562 | } 563 | } 564 | }, 565 | "uglify-to-browserify": { 566 | "version": "1.0.2", 567 | "resolved": "http://registry.npm.taobao.org/uglify-to-browserify/download/uglify-to-browserify-1.0.2.tgz", 568 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=" 569 | }, 570 | "unpipe": { 571 | "version": "1.0.0", 572 | "resolved": "http://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz", 573 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 574 | }, 575 | "utils-merge": { 576 | "version": "1.0.1", 577 | "resolved": "http://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz", 578 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 579 | }, 580 | "vary": { 581 | "version": "1.1.2", 582 | "resolved": "http://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz", 583 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 584 | }, 585 | "window-size": { 586 | "version": "0.1.0", 587 | "resolved": "http://registry.npm.taobao.org/window-size/download/window-size-0.1.0.tgz", 588 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" 589 | }, 590 | "wordwrap": { 591 | "version": "0.0.3", 592 | "resolved": "http://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.3.tgz", 593 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" 594 | }, 595 | "yargs": { 596 | "version": "3.5.4", 597 | "resolved": "http://registry.npm.taobao.org/yargs/download/yargs-3.5.4.tgz", 598 | "integrity": "sha1-2K/49mXpTDS9JZvevRv68N3TU2E=", 599 | "requires": { 600 | "camelcase": "1.2.1", 601 | "decamelize": "1.2.0", 602 | "window-size": "0.1.0", 603 | "wordwrap": "0.0.2" 604 | }, 605 | "dependencies": { 606 | "wordwrap": { 607 | "version": "0.0.2", 608 | "resolved": "http://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.2.tgz", 609 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" 610 | } 611 | } 612 | } 613 | } 614 | } 615 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jamesblog", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "james", 10 | "license": "ISC", 11 | "dependencies": { 12 | "body-parser": "^1.18.2", 13 | "cookies": "^0.7.1", 14 | "express": "^4.16.2", 15 | "markdown": "^0.5.0", 16 | "mongoose": "^5.0.0-rc0", 17 | "swig": "^1.4.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/.DS_Store -------------------------------------------------------------------------------- /public/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} 6 | /*# sourceMappingURL=bootstrap-theme.min.css.map */ -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | /* project util.css */ 2 | .center{ 3 | width: 960px; 4 | margin: 0 auto; 5 | position: relative; 6 | } 7 | header{ 8 | width: 100%; 9 | min-width: 960px; 10 | height: 30px; 11 | line-height: 30px; 12 | padding-top: 12px; 13 | padding-bottom: 12px; 14 | color: rgba(255,255,255,0.75); 15 | background-color: #24292e; 16 | display: inline-table; 17 | } 18 | .head_logo{ 19 | display: block; 20 | width: 32px; 21 | height: 32px; 22 | border-radius: 50%; 23 | background: rgba(255,255,255,0.95); 24 | position: relative; 25 | float: left; 26 | } 27 | .head_logo:hover{ 28 | background: rgba(255,255,255,1); 29 | } 30 | .head_logo img{ 31 | position: absolute; 32 | top: 2px; 33 | left: 2px; 34 | width: 28px; 35 | height: 28px; 36 | } 37 | .head_nav{ 38 | float: right; 39 | } 40 | .head_nav a{ 41 | display: inline-block; 42 | height: 32px; 43 | line-height: 32px; 44 | float: left; 45 | margin-left: 24px; 46 | color: rgba(255,255,255,0.75); 47 | } 48 | .head_nav a:hover{ 49 | color: rgba(255,255,255,1); 50 | } 51 | .head_nav a.head_navCur{ 52 | color: rgba(255,255,255,1); 53 | } 54 | .article_list{ 55 | width: 690px; 56 | float: left; 57 | display: inline-block; 58 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 59 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 60 | margin: 30px 0; 61 | padding: 30px 0; 62 | } 63 | .article_item{ 64 | display: inline-block; 65 | width: 650px; 66 | padding: 20px; 67 | position: relative; 68 | } 69 | .article_item:after{ 70 | content: ""; 71 | width: 650px; 72 | position: absolute; 73 | height: 1px; 74 | background: #e1e4e8; 75 | bottom: 0; 76 | } 77 | .article_item:last-child:after{ 78 | height: 0; 79 | } 80 | .article_item h3{ 81 | font-size: 18px; 82 | font-weight: 600; 83 | font-synthesis: style; 84 | line-height: 30px; 85 | color: #1e1e1e; 86 | } 87 | .article_main{ 88 | margin-top: 10px; 89 | display: inline-block; 90 | } 91 | .article_content{ 92 | color: #262626; 93 | font-size: 15px; 94 | line-height: 24px; 95 | max-height: 96px; 96 | overflow: hidden; 97 | } 98 | .article_tag{ 99 | width: 100%; 100 | clear: both; 101 | margin-top: 8px; 102 | } 103 | .article_tag span{ 104 | float: left; 105 | display: inline-block; 106 | padding: 6px 10px; 107 | white-space: nowrap; 108 | background-color: #f1f8ff; 109 | border-radius: 3px; 110 | color: #8590a6; 111 | font-size: 14px; 112 | line-height: 20px; 113 | } 114 | .article_tag i{ 115 | float: right; 116 | height: 32px; 117 | line-height: 32px; 118 | color: #8590a6; 119 | } 120 | .article_item:hover h3{ 121 | color: #0366d6; 122 | } 123 | .article_img{ 124 | width: 190px; 125 | height: 96px; 126 | float: left; 127 | margin-right: 20px; 128 | text-align: center; 129 | overflow: hidden; 130 | border-radius: 6px; 131 | } 132 | .article_img img{ 133 | width: auto; 134 | height: 100%; 135 | border-radius: 6px; 136 | } 137 | .banner{ 138 | margin-top: 10px; 139 | height: 285px; 140 | position: relative; 141 | } 142 | .banner img{ 143 | width: 100%; 144 | height: 100%; 145 | } 146 | .banner h2{ 147 | position: absolute; 148 | top: 100px; 149 | left: 100px; 150 | font-size: 60px; 151 | line-height: 85px; 152 | height: 85px; 153 | font-weight: bold; 154 | } 155 | .user_list{ 156 | width: 250px; 157 | float: right; 158 | display: inline-block; 159 | margin: 30px 0; 160 | padding: 0 0 30px 0; 161 | } 162 | .user_form{ 163 | background: #ffffff; 164 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 165 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 166 | border-radius: 4px; 167 | } 168 | .user_tab{ 169 | width: 100%; 170 | height: 50px; 171 | line-height: 50px; 172 | border-bottom: 1px solid rgba(27,31,35,0.15); 173 | } 174 | .user_tab span{ 175 | display: block; 176 | width: 50%; 177 | float: left; 178 | text-align: center; 179 | height: 100%; 180 | line-height: 50px; 181 | position: relative; 182 | cursor: pointer; 183 | } 184 | .user_tab span.user_cur:after{ 185 | content: ""; 186 | position: absolute; 187 | bottom: 0; 188 | left: 50%; 189 | width: 60px; 190 | margin-left: -30px; 191 | height: 2px; 192 | background: #0366d6; 193 | } 194 | .user_login,.user_register{ 195 | width: 100%; 196 | display: inline-block; 197 | margin-top: 20px; 198 | } 199 | .user_register{ 200 | display: none; 201 | } 202 | .user_input{ 203 | width: 220px; 204 | margin: 10px 15px; 205 | margin-bottom: 20px; 206 | background: #ffffff; 207 | box-shadow: inset 0 1px 2px rgba(27,31,35,0.075); 208 | border: 1px solid #d1d5da; 209 | height: 42px; 210 | line-height: 42px; 211 | border-radius: 3px; 212 | } 213 | .user_input i{ 214 | color: #8590a6; 215 | font-size: 18px; 216 | margin-left: 6px; 217 | margin-right: 8px; 218 | float: left; 219 | } 220 | .user_input input{ 221 | width: 160px; 222 | height: 30px; 223 | line-height: 30px; 224 | margin-top: 6px; 225 | float: left; 226 | font-size: 14px; 227 | } 228 | .user_login_btn,.user_register_btn{ 229 | height: 42px; 230 | line-height: 42px; 231 | text-align: center; 232 | background: #0f88eb; 233 | color: #ffffff; 234 | width: 220px; 235 | margin-left: 15px; 236 | border-radius: 4px; 237 | cursor: pointer; 238 | margin-bottom: 20px; 239 | } 240 | .user_login_btn:hover,.user_register_btn:hover{ 241 | background: #0366d6; 242 | } 243 | .user_err{ 244 | width: 100%; 245 | height: 30px; 246 | line-height: 30px; 247 | font-size: 12px; 248 | text-align: center; 249 | color: red; 250 | } 251 | .user_err span{ 252 | display: none; 253 | } 254 | .margin_bottom0{ 255 | margin-bottom: 0px; 256 | } 257 | .friendly_link{ 258 | background: #ffffff; 259 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 260 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 261 | border-radius: 4px; 262 | margin-top: 20px; 263 | display: inline-block; 264 | width: 100%; 265 | } 266 | .link_item{ 267 | width: 220px; 268 | margin-left: 15px; 269 | margin-top: 20px; 270 | margin-bottom: 20px; 271 | } 272 | .link_item a{ 273 | color: #262626; 274 | } 275 | .link_item a:hover{ 276 | color: #8590a6; 277 | } 278 | .copy_right{ 279 | color: #8590a6; 280 | width: 100%; 281 | font-size: 12px; 282 | } 283 | .user_no{ 284 | color: #8590a6; 285 | width: 100%; 286 | font-size: 12px; 287 | margin-top: 20px; 288 | margin-bottom: 10px; 289 | } 290 | .user_no i{ 291 | color: #262626; 292 | margin-left: 2px; 293 | margin-right: 2px; 294 | } 295 | .user_logined{ 296 | background: #ffffff; 297 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 298 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 299 | border-radius: 4px; 300 | display: inline-block; 301 | width: 100%; 302 | } 303 | .user_welcome{ 304 | width: 220px; 305 | margin-top: 20px; 306 | margin-left: 15px; 307 | font-size: 16px; 308 | } 309 | .user_welcome i{ 310 | color: #0366d6; 311 | font-weight: 600; 312 | } 313 | .user_welcome a{ 314 | margin-left: 10px; 315 | font-size: 14px; 316 | text-decoration: underline !important; 317 | } 318 | .user_loginOut{ 319 | display: inline-block; 320 | margin: 15px; 321 | text-decoration: underline; 322 | cursor: pointer; 323 | } 324 | .user_loginOut:hover{ 325 | color: #8590a6; 326 | } 327 | 328 | /* detail */ 329 | .detail_main{ 330 | width: 700px; 331 | margin: 0 auto; 332 | } 333 | .detail_title{ 334 | font-size: 24px; 335 | line-height: 40px; 336 | width: 100%; 337 | margin-top: 50px; 338 | margin-bottom: 10px; 339 | font-weight: 600; 340 | } 341 | .detail_content{ 342 | font-size: 16px; 343 | line-height: 30px; 344 | } 345 | .detail_tag{ 346 | color: gray; 347 | height: 20px; 348 | line-height: 20px; 349 | font-size: 14px; 350 | width: 100%; 351 | margin-top: 20px; 352 | margin-bottom: 20px; 353 | } 354 | .detail_discuss{ 355 | width: 100%; 356 | display: inline-block; 357 | background: #ebf3fb; 358 | min-width: 700px; 359 | margin-top: 60px; 360 | clear: both; 361 | } 362 | .discuss{ 363 | background: #ffffff; 364 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 365 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 366 | border-radius: 4px; 367 | width: 430px; 368 | float: left; 369 | display: inline-block; 370 | margin: 30px 0; 371 | padding: 0 0 30px 0; 372 | } 373 | .user_tab span.discuss_title{ 374 | display: inline-block; 375 | float: left; 376 | margin-left: 15px; 377 | width: 84px; 378 | text-align: center; 379 | position: relative; 380 | } 381 | .user_tab span.discuss_title:after{ 382 | content: ""; 383 | position: absolute; 384 | bottom: 0; 385 | left: 50%; 386 | width: 84px; 387 | margin-left: -40px; 388 | height: 2px; 389 | background: #0366d6; 390 | } 391 | .discuss_main{ 392 | display: inline-block; 393 | width: 400px; 394 | margin: 20px 15px; 395 | } 396 | .discuss_default{ 397 | color: #8590a6; 398 | text-align: center; 399 | padding: 20px 0; 400 | } 401 | .discuss_list{ 402 | width: 100%; 403 | } 404 | .discuss_user{ 405 | width: 100%; 406 | display: inline-block; 407 | height: 20px; 408 | line-height: 20px; 409 | } 410 | .discuss_user span{ 411 | font-size: 15px; 412 | line-height: 20px; 413 | font-weight: 600; 414 | } 415 | .discuss_user i{ 416 | margin-left: 10px; 417 | color: #8590a6; 418 | font-size: 12px; 419 | } 420 | .discuss_userMain{ 421 | width: 100%; 422 | display: inline-block; 423 | margin-bottom: 30px; 424 | font-size: 14px; 425 | line-height: 24px; 426 | margin-top: 6px; 427 | } 428 | .discuss_input{ 429 | width: 92%; 430 | padding: 10px 4%; 431 | height: 72px; 432 | font-size: 14px; 433 | line-height: 24px; 434 | text-align: left; 435 | border: 1px solid rgba(27,31,35,0.15); 436 | border-radius: 4px; 437 | } 438 | .discuss_input:focus{ 439 | border: 1px solid rgba(15,136,235,0.75); 440 | } 441 | .pagination{ 442 | width: 650px; 443 | margin-left: 20px; 444 | height: 30px; 445 | clear: both; 446 | display: inline-block; 447 | margin-top: 50px; 448 | text-align: center; 449 | } 450 | .pagination_left{ 451 | float: left; 452 | display: inline-block; 453 | height: 30px; 454 | line-height: 30px; 455 | text-align: left; 456 | font-size: 14px; 457 | } 458 | .pagination_right{ 459 | float: right; 460 | display: inline-block; 461 | height: 30px; 462 | line-height: 30px; 463 | font-size: 14px; 464 | text-align: right; 465 | } 466 | .pagination span{ 467 | font-size: 14px; 468 | color: #8590a6; 469 | line-height: 30px; 470 | } 471 | .noPageList{ 472 | text-align: center; 473 | margin-top: 20px; 474 | margin-bottom: 20px; 475 | color: #8590a6; 476 | font-size: 14px; 477 | } 478 | .discuss_submit{ 479 | width: 100%; 480 | height: 36px; 481 | line-height: 36px; 482 | color: #ffffff; 483 | background: #0f88eb; 484 | text-align: center; 485 | font-size: 14px; 486 | line-height: 36px; 487 | cursor: pointer; 488 | margin-top: 10px; 489 | } 490 | .discuss_submit:hover{ 491 | background: #0366d6; 492 | } -------------------------------------------------------------------------------- /public/css/util.css: -------------------------------------------------------------------------------- 1 | /* 全局样式表 */ 2 | @font-face { 3 | font-family: 'iconfont'; 4 | src: url('../font/iconfont.eot'); 5 | src: url('../font/iconfont.eot?#iefix') format('embedded-opentype'), 6 | url('../font/iconfont.woff') format('woff'), 7 | url('../font/iconfont.ttf') format('truetype'), 8 | url('../font/iconfont.svg#iconfont') format('svg'); 9 | } 10 | .iconfont{ 11 | font-family:"iconfont" !important; 12 | font-size:16px;font-style:normal; 13 | -webkit-font-smoothing: antialiased; 14 | -webkit-text-stroke-width: 0.2px; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ 18 | color: #8590a6; opacity:1; 19 | } 20 | ::-moz-placeholder { /* Mozilla Firefox 19+ */ 21 | color: #8590a6;opacity:1; 22 | } 23 | input:-ms-input-placeholder{ 24 | color: #8590a6;opacity:1; 25 | } 26 | input::-webkit-input-placeholder{ 27 | color: #8590a6;opacity:1; 28 | } 29 | input,button,select,textarea{ outline:none;} 30 | textarea{resize:none;} 31 | html { 32 | background-color:#fff; 33 | color: #313131; 34 | -webkit-text-size-adjust: 100%; 35 | -ms-text-size-adjust: 100% 36 | } 37 | body { 38 | font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif; 39 | } 40 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,figure,form,fieldset,legend,input,textarea,p,blockquote,th,td{ 41 | margin:0; 42 | padding:0; 43 | list-style: none; 44 | -webkit-tap-highlight-color:transparent 45 | } 46 | h1,h2,h3,h4,h5,h6{ 47 | font-size:100%; 48 | font-weight:normal; 49 | } 50 | input,textarea,select,code,kbd,pre,samp { 51 | font-size:100%; 52 | } 53 | input,button,select{border:none;outline: none;}/*去除iphone默认input样式*/ 54 | input::-webkit-outer-spin-button,input::-webkit-inner-spin-button { } 55 | table { 56 | border-collapse: collapse; 57 | border-spacing: 0; 58 | } 59 | em, i { 60 | font-style: normal; 61 | } 62 | html,body,button,input,select,textarea { 63 | font-size:14px/1.5; 64 | color:#313131; 65 | } 66 | img{ 67 | border: none; 68 | } 69 | a{ 70 | text-decoration:none !important; 71 | -webkit-tap-highlight-color:rgb(0,0,0,0);outline:none; 72 | color: #313131; 73 | cursor: pointer; 74 | } 75 | a:link { 76 | text-decoration: none; 77 | } 78 | a:visited { 79 | text-decoration: none; 80 | } 81 | a:hover { 82 | text-decoration: none; 83 | } 84 | a:active { 85 | text-decoration: none; 86 | } 87 | .fl{float: left;} 88 | .fr{float: right;} 89 | .clearfix:after{ 90 | display:block; 91 | clear:both; 92 | content:""; 93 | visibility:hidden; 94 | height:0; 95 | } 96 | .ellipsis_1{text-overflow: ellipsis;overflow: hidden;white-space: nowrap; word-wrap: break-word;} 97 | .ellipsis_2{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;} 98 | .ellipsis_3{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 3;-webkit-box-orient: vertical;} 99 | .ellipsis_4{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 4;-webkit-box-orient: vertical;} 100 | .ellipsis_6{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 6;-webkit-box-orient: vertical;} 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /public/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/font/iconfont.eot -------------------------------------------------------------------------------- /public/font/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /public/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/font/iconfont.ttf -------------------------------------------------------------------------------- /public/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/font/iconfont.woff -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /public/image/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/image/.DS_Store -------------------------------------------------------------------------------- /public/image/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/image/banner.jpg -------------------------------------------------------------------------------- /public/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/image/logo.png -------------------------------------------------------------------------------- /public/image/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/public/image/test.jpg -------------------------------------------------------------------------------- /public/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under the MIT license 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); -------------------------------------------------------------------------------- /public/js/main.js: -------------------------------------------------------------------------------- 1 | // project util.js 2 | $(function(){ 3 | // 登录注册切换 4 | $('.j_userTab span').on('click',function(){ 5 | var _index = $(this).index(); 6 | $(this).addClass('user_cur').siblings().removeClass('user_cur'); 7 | $('.user_login,.user_register').hide(); 8 | if( _index==0 ){ 9 | $('.user_login').css('display','inline-block'); 10 | $('.user_register').hide(); 11 | }else{ 12 | $('.user_login').hide(); 13 | $('.user_register').css('display','inline-block'); 14 | } 15 | }); 16 | 17 | // 登录校验 18 | var reg = /^[^<>"'$\|?~*&@(){}]*$/; 19 | var $login = $('#login'); 20 | var $register = $('#register'); 21 | var $userForm = $('.user_form'); 22 | var $userLogined = $('.user_logined'); 23 | $('.user_login_btn').on('click',function(){ 24 | if( $login.find('.user_input').eq(0).find('input').val().trim() == '' ){ 25 | $login.find('.user_err span').text('用户名不能为空').show(); 26 | return false; 27 | } 28 | if( !reg.test($login.find('.user_input').eq(0).find('input').val().trim()) ){ 29 | $login.find('.user_err span').text('用户名不能含有特殊字符').show(); 30 | return false; 31 | } 32 | if( $login.find('.user_input').eq(1).find('input').val().trim() == '' ){ 33 | $login.find('.user_err span').text('密码不能为空').show(); 34 | return false; 35 | } 36 | if( !reg.test($login.find('.user_input').eq(1).find('input').val().trim()) ){ 37 | $login.find('.user_err span').text('密码不能含有特殊字符').show(); 38 | return false; 39 | } 40 | $.ajax({ 41 | type: 'post', 42 | url: '/api/user/login', 43 | data: { 44 | username: $login.find('.user_input').eq(0).find('input').val().trim(), 45 | password: $login.find('.user_input').eq(1).find('input').val().trim() 46 | }, 47 | dataType: 'json', 48 | success: function(data){ 49 | console.log(data); 50 | if(data.code != 0){ 51 | $login.find('.user_err span').text( data.msg ).show(); 52 | return false; 53 | }else{ 54 | window.location.reload() 55 | } 56 | } 57 | }) 58 | }); 59 | 60 | $('.user_register_btn').on('click',function(){ 61 | if( $register.find('.user_input').eq(0).find('input').val().trim() == '' ){ 62 | $register.find('.user_err span').text('用户名不能为空').show(); 63 | return false; 64 | } 65 | if( !reg.test($register.find('.user_input').eq(0).find('input').val().trim()) ){ 66 | $register.find('.user_err span').text('用户名不能含有特殊字符').show(); 67 | return false; 68 | } 69 | if( $register.find('.user_input').eq(1).find('input').val().trim() == '' ){ 70 | $register.find('.user_err span').text('密码不能为空').show(); 71 | return false; 72 | } 73 | if( !reg.test($register.find('.user_input').eq(1).find('input').val().trim()) ){ 74 | $register.find('.user_err span').text('密码不能含有特殊字符').show(); 75 | return false; 76 | } 77 | if( $register.find('.user_input').eq(1).find('input').val().trim() != 78 | $register.find('.user_input').eq(2).find('input').val().trim() 79 | ){ 80 | $register.find('.user_err span').text('两次输入的密码不一致').show(); 81 | return false; 82 | } 83 | $.ajax({ 84 | type: 'post', 85 | url: '/api/user/register', 86 | data: { 87 | username: $register.find('.user_input').eq(0).find('input').val().trim(), 88 | password: $register.find('.user_input').eq(1).find('input').val().trim(), 89 | repassword: $register.find('.user_input').eq(2).find('input').val().trim() 90 | }, 91 | dataType: 'json', 92 | success: function(data){ 93 | console.log(data); 94 | if(data.code != 0){ 95 | $register.find('.user_err span').text( data.msg ).show(); 96 | return false; 97 | }else{ 98 | window.location.reload() 99 | } 100 | } 101 | }) 102 | }); 103 | 104 | // 退出 105 | $('#loginOut').on('click',function(){ 106 | $.ajax({ 107 | type: 'post', 108 | url: '/api/user/loginOut', 109 | success: function(data){ 110 | if(!data.code){ 111 | window.location.reload(); 112 | } 113 | } 114 | }) 115 | }); 116 | 117 | // 提交评论 118 | $('.discuss_submit').on('click',function(){ 119 | $.ajax({ 120 | type: 'post', 121 | url: '/api/comment', 122 | data: { 123 | commentId: $('.discuss_id').val(), 124 | commentContent: $('.discuss_input').val() 125 | }, 126 | dataType: 'json', 127 | success: function(data){ 128 | if(!data.code){ 129 | $('.discuss_input').val(''); 130 | renderComments( data.commentList ); 131 | } 132 | } 133 | }) 134 | }); 135 | 136 | $.ajax({ 137 | type: 'get', 138 | url: '/api/comment', 139 | data: { 140 | commentId: $('.discuss_id').val() 141 | }, 142 | dataType: 'json', 143 | success: function(data){ 144 | if(!data.code){ 145 | renderComments( data.commentList ); 146 | } 147 | } 148 | }) 149 | 150 | function renderComments(list){ 151 | var commentsStr = ""; 152 | for(var i=0;i 155 |

${list[i].userName}发表于 ${list[i].postTime}

156 |
157 | ${list[i].comment} 158 |
159 | ` 160 | }; 161 | $('.discuss_list').html( commentsStr ); 162 | }; 163 | 164 | function formatDate( date ){ 165 | var curDate = new Date( date ); 166 | return curDate.getFullYear()+'年'+(curDate.getMonth()+1)+'月'+curDate.getDay()+'日'; 167 | }; 168 | 169 | // 打字效果 170 | var str = 'hello world'; 171 | var i = 0; 172 | function typing(){ 173 | var divTyping = $('.banner h2'); 174 | if (i <= str.length) { 175 | divTyping.text( str.slice(0, i++) + '_' ); 176 | setTimeout(function(){typing()}, 200); 177 | }else{ 178 | divTyping.text( str ); 179 | } 180 | } 181 | typing(); 182 | }); -------------------------------------------------------------------------------- /router/admin.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const User = require('../models/User'); 4 | const Category = require('../models/Category'); 5 | const Content = require('../models/Content'); 6 | 7 | router.use((req, res, next)=>{ 8 | if(!req.userInfo.isAdmin){ 9 | res.send('对不起,您不具有此页面的访问权限'); 10 | return; 11 | } 12 | next(); 13 | }); 14 | 15 | router.get('/',(req,res,next)=>{ 16 | res.render('admin/index',{ 17 | userInfo: req.userInfo 18 | }); 19 | }); 20 | 21 | router.get('/user',(req,res,next)=>{ 22 | /** 23 | * 读取目前的用户数据 24 | * limit(Number) : 限制获取的数据条数 25 | * skip() : 忽略数据的条数 26 | * users : 所有的用户信息 27 | * count : 总查询页数 28 | * pages : 总页数 29 | * limit : 每页显示条数 30 | * page : 当前页 31 | */ 32 | 33 | let page = Number(req.query.page || 1); 34 | let limit = 10; 35 | let skip = 0; 36 | let pages = 0; 37 | 38 | // User 返回查询的条数 39 | User.count().then((count)=>{ 40 | pages = Math.ceil( count/limit ); 41 | page = Math.min( page, pages ); 42 | page = Math.max( page, 1 ); 43 | skip = (page-1)*limit; 44 | User.find().limit( limit ).skip( skip ).then((users)=>{ 45 | res.render('admin/user_index',{ 46 | userInfo: req.userInfo, 47 | users, 48 | count, 49 | pages, 50 | limit, 51 | page 52 | }); 53 | }) 54 | }); 55 | }); 56 | 57 | router.get('/category',(req,res,next)=>{ 58 | /** 59 | * 读取目前的用户数据 60 | * limit(Number) : 限制获取的数据条数 61 | * skip() : 忽略数据的条数 62 | * users : 所有的用户信息 63 | * count : 总查询页数 64 | * pages : 总页数 65 | * limit : 每页显示条数 66 | * page : 当前页 67 | */ 68 | 69 | let page = Number(req.query.page || 1); 70 | let limit = 10; 71 | let skip = 0; 72 | let pages = 0; 73 | 74 | // Category 返回查询的条数 75 | Category.count().then((count)=>{ 76 | pages = Math.ceil( count/limit ); 77 | page = Math.min( page, pages ); 78 | page = Math.max( page, 1 ); 79 | skip = (page-1)*limit; 80 | Category.find().sort({_id: -1}).limit( limit ).skip( skip ).then((categories)=>{ 81 | res.render('admin/category_index',{ 82 | userInfo: req.userInfo, 83 | categories, 84 | count, 85 | pages, 86 | limit, 87 | page 88 | }); 89 | }) 90 | }); 91 | }); 92 | 93 | router.get('/category/add',(req,res,next)=>{ 94 | res.render('admin/category_add',{ 95 | userInfo: req.userInfo 96 | }); 97 | }); 98 | 99 | router.post('/category/add',(req,res,next)=>{ 100 | let name = req.body.name || ''; 101 | if( name == '' ){ 102 | res.render('admin/error',{ 103 | userInfo: req.userInfo, 104 | msg: "分类名称不能为空" 105 | }); 106 | return; 107 | } 108 | 109 | Category.findOne({name}).then((categoryName)=>{ 110 | if( categoryName ){ 111 | res.render('admin/error',{ 112 | userInfo: req.userInfo, 113 | msg: "该分类已经存在" 114 | }); 115 | return Promise.reject(); 116 | } else { 117 | return new Category({name}).save(); 118 | } 119 | }).then((newCategory)=>{ 120 | if(newCategory){ 121 | res.render('admin/success',{ 122 | userInfo: req.userInfo, 123 | msg: "分类添加成功", 124 | url: '/admin/category' 125 | }) 126 | } 127 | }).catch(()=>{}); 128 | }); 129 | 130 | router.get('/category/edit',(req, res, next)=>{ 131 | let _id = req.query.id || ''; 132 | Category.findOne({_id}).then((category)=>{ 133 | if(!category){ 134 | res.render('admin/error',{ 135 | userInfo: req.userInfo, 136 | msg: '分类名称不存在' 137 | }); 138 | } else { 139 | res.render('admin/category_edit',{ 140 | userInfo: req.userInfo, 141 | category 142 | }); 143 | } 144 | }); 145 | }); 146 | 147 | router.post('/category/edit',(req, res, next)=>{ 148 | let _id = req.query.id || ''; 149 | let name = req.body.name || ''; 150 | Category.findOne({_id}).then((category)=>{ 151 | if(!category){ 152 | res.render('admin/error',{ 153 | userInfo: req.userInfo, 154 | msg: '分类名称不存在' 155 | }); 156 | return Promise.reject(); 157 | } else { 158 | if(name == category.name){ 159 | res.render('admin/success',{ 160 | userInfo: req.userInfo, 161 | msg: '分类修改成功', 162 | url: '/admin/category' 163 | }); 164 | return Promise.reject(); 165 | } else { 166 | return Category.findOne({_id: {$ne: _id}, name}) 167 | } 168 | } 169 | }).then((sameCategory)=>{ 170 | if(sameCategory){ 171 | res.render('admin/error',{ 172 | userInfo: req.userInfo, 173 | msg: '数据库中存在同名分类' 174 | }); 175 | return Promise.reject(); 176 | } else { 177 | return Category.update({_id}, {name}); 178 | } 179 | }).then(()=>{ 180 | res.render('admin/success',{ 181 | userInfo: req.userInfo, 182 | msg: '分类修改成功', 183 | url: '/admin/category' 184 | }); 185 | }).catch(()=>{}); 186 | }); 187 | 188 | router.get('/category/delete',(req, res, next)=>{ 189 | let _id = req.query.id; 190 | Category.remove({_id}).then((delCategory)=>{ 191 | res.render('admin/success',{ 192 | userInfo: req.userInfo, 193 | msg: '删除分类成功', 194 | url: '/admin/category' 195 | }); 196 | }); 197 | }); 198 | 199 | router.get('/content',(req, res, next)=>{ 200 | /** 201 | * 读取目前的用户数据 202 | * limit(Number) : 限制获取的数据条数 203 | * skip() : 忽略数据的条数 204 | * users : 所有的用户信息 205 | * count : 总查询页数 206 | * pages : 总页数 207 | * limit : 每页显示条数 208 | * page : 当前页 209 | */ 210 | 211 | let page = Number(req.query.page || 1); 212 | let limit = 10; 213 | let skip = 0; 214 | let pages = 0; 215 | 216 | // Content 返回查询的条数 217 | Content.count().then((count)=>{ 218 | pages = Math.ceil( count/limit ); 219 | page = Math.min( page, pages ); 220 | page = Math.max( page, 1 ); 221 | skip = (page-1)*limit; 222 | Content.find().sort({_id: -1}).limit( limit ).skip( skip ).populate( ['category','user'] ).then((contents)=>{ 223 | res.render('admin/content_index',{ 224 | userInfo: req.userInfo, 225 | contents, 226 | count, 227 | pages, 228 | limit, 229 | page 230 | }); 231 | }) 232 | }); 233 | }); 234 | 235 | router.get('/content/add',(req, res, next)=>{ 236 | Category.find().then((categories)=>{ 237 | res.render('admin/content_add',{ 238 | userInfo: req.userInfo, 239 | categories 240 | }) 241 | }); 242 | }); 243 | 244 | router.post('/content/add',(req, res, next)=>{ 245 | const category = req.body.category; 246 | const title = req.body.title; 247 | const description = req.body.description; 248 | const content = req.body.content; 249 | const user = req.userInfo._id.toString(); 250 | if(req.body.category == ''){ 251 | res.render('admin/error',{ 252 | userInfo: req.userInfo, 253 | msg: '文章所属栏目不能为空' 254 | }); 255 | } 256 | if(req.body.title == ''){ 257 | res.render('admin/error',{ 258 | userInfo: req.userInfo, 259 | msg: '文章标题不能为空' 260 | }); 261 | } 262 | new Content({category, title, description, content, user}).save().then(()=>{ 263 | res.render('admin/success',{ 264 | userInfo: req.userInfo, 265 | msg: '文章保存成功', 266 | url: '/admin/content' 267 | }) 268 | }) 269 | }); 270 | 271 | router.get('/content/edit',(req, res, next)=>{ 272 | let _id = req.query.id; 273 | let categoryList = []; 274 | Category.find().then((categories)=>{ 275 | categoryList = categories; 276 | return Content.findOne({_id}).populate('category'); 277 | }).then((content)=>{ 278 | if(!content){ 279 | render('admin/error',{ 280 | userInfo: req.userInfo, 281 | msg: '该文章不存在' 282 | }); 283 | } else { 284 | res.render('admin/content_edit',{ 285 | userInfo: req.userInfo, 286 | content, 287 | categoryList 288 | }) 289 | } 290 | }).catch(()=>{}); ; 291 | }); 292 | 293 | router.post('/content/edit',(req, res, next)=>{ 294 | let _id = req.query.id; 295 | const category = req.body.category; 296 | const title = req.body.title; 297 | const description = req.body.description; 298 | const content = req.body.content; 299 | if(req.body.category == ''){ 300 | res.render('admin/error',{ 301 | userInfo: req.userInfo, 302 | msg: '文章所属栏目不能为空' 303 | }); 304 | } 305 | if(req.body.title == ''){ 306 | res.render('admin/error',{ 307 | userInfo: req.userInfo, 308 | msg: '文章标题不能为空' 309 | }); 310 | } 311 | 312 | Content.update({_id},{category, title, description, content}).then(()=>{ 313 | res.render('admin/success',{ 314 | userInfo: req.userInfo, 315 | msg: '保存成功', 316 | url: `/admin/content/edit?id=${_id}` 317 | }) 318 | }); 319 | }); 320 | 321 | router.get('/content/delete',(req, res, next)=>{ 322 | let _id = req.query.id; 323 | Content.remove({_id}).then((delContent)=>{ 324 | res.render('admin/success',{ 325 | userInfo: req.userInfo, 326 | msg: '删除文章成功', 327 | url: '/admin/content' 328 | }); 329 | }); 330 | }); 331 | 332 | module.exports = router; -------------------------------------------------------------------------------- /router/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const User = require('../models/User'); 4 | const Content = require('../models/Content'); 5 | 6 | // 定义统一返回格式 7 | let reponseData; 8 | router.use((req,res,next)=>{ 9 | reponseData = { 10 | code: 0, 11 | msg: '' 12 | } 13 | next(); 14 | }); 15 | 16 | router.post('/user/register',(req,res,next)=>{ 17 | const [username,password,repassword] = [req.body.username,req.body.password,req.body.repassword]; 18 | const reg = /^[^<>"'$\|?~*&@(){}]*$/; 19 | if(username == ''){ 20 | reponseData = {code: 1,msg: '用户名不能为空'} 21 | res.json(reponseData); 22 | return; 23 | } 24 | if(!reg.test(username)){ 25 | reponseData = {code: 1,msg: '用户名不能含有特殊字符'} 26 | res.json(reponseData); 27 | return; 28 | } 29 | if(password == ''){ 30 | reponseData = {code: 2,msg: '密码不能为空'} 31 | res.json(reponseData); 32 | return; 33 | } 34 | if(!reg.test(password)){ 35 | reponseData = {code: 2,msg: '密码不能含有特殊字符'} 36 | res.json(reponseData); 37 | return; 38 | } 39 | if(repassword != password){ 40 | reponseData = {code: 3,msg: '两次输入的密码不一致'} 41 | res.json(reponseData); 42 | return; 43 | } 44 | console.log( '====前台用户注册信息====='+JSON.stringify( reponseData )+'=========' ); 45 | User.findOne({ username }).then((userInfo)=>{ 46 | console.log( '====数据库查询用户是否注册返回信息====='+JSON.stringify( reponseData )+'=========' ); 47 | if(userInfo){ 48 | reponseData = {code: 4,msg: '该用户名已经被注册'} 49 | res.json(reponseData); 50 | return; 51 | }else{ 52 | // 保存用户信息到数据库中 53 | let user = new User({username, password}); 54 | return user.save(); 55 | } 56 | }).then((saveUserInfo)=>{ 57 | if(saveUserInfo){ 58 | reponseData.msg = '注册成功'; 59 | reponseData.userInfo = { 60 | _id: saveUserInfo._id, 61 | username: saveUserInfo.username 62 | } 63 | req.cookies.set('userInfo', JSON.stringify({ 64 | _id: saveUserInfo._id, 65 | username: saveUserInfo.username 66 | })); 67 | res.json(reponseData); 68 | } 69 | console.log( '=====用户注册保存成功===='+saveUserInfo+'=========' ); 70 | }).catch(()=>{}); 71 | }); 72 | 73 | router.post('/user/login',(req,res)=>{ 74 | const [username,password] = [req.body.username,req.body.password]; 75 | const reg = /^[^<>"'$\|?~*&@(){}]*$/; 76 | if(username == ''){ 77 | reponseData = {code: 1,msg: '用户名不能为空'} 78 | res.json(reponseData); 79 | return; 80 | } 81 | if(!reg.test(username)){ 82 | reponseData = {code: 1,msg: '用户名不能含有特殊字符'} 83 | res.json(reponseData); 84 | return; 85 | } 86 | if(password == ''){ 87 | reponseData = {code: 2,msg: '密码不能为空'} 88 | res.json(reponseData); 89 | return; 90 | } 91 | if(!reg.test(password)){ 92 | reponseData = {code: 2,msg: '密码不能含有特殊字符'} 93 | res.json(reponseData); 94 | return; 95 | } 96 | 97 | console.log( '====前台用户登录信息====='+JSON.stringify( reponseData )+'=========' ); 98 | User.findOne({ username, password }).then((userInfo)=>{ 99 | console.log( '====数据库查询用户登录返回信息====='+userInfo+'=========' ); 100 | if(userInfo){ 101 | reponseData = {code: 0,msg: '登录成功'} 102 | reponseData.userInfo = { 103 | _id: userInfo._id, 104 | username: userInfo.username 105 | } 106 | req.cookies.set('userInfo', JSON.stringify({ 107 | _id: userInfo._id, 108 | username: userInfo.username 109 | })); 110 | res.json(reponseData); 111 | }else{ 112 | reponseData = {code: 4,msg: '用户名或密码不能不正确'} 113 | res.json(reponseData); 114 | } 115 | }); 116 | }); 117 | 118 | router.post('/user/loginOut',(req,res, next)=>{ 119 | req.cookies.set('userInfo',null); 120 | res.json(reponseData); 121 | }); 122 | 123 | router.post('/comment',(req, res, next)=>{ 124 | const _id = req.body.commentId; 125 | const data = { 126 | userName: req.userInfo.username, 127 | postTime: new Date(), 128 | comment: req.body.commentContent 129 | }; 130 | 131 | Content.findOne({_id}).then((content)=>{ 132 | content.comment.push( data ); 133 | return content.save(); 134 | }).then((newContent)=>{ 135 | reponseData.msg = "评论成功"; 136 | res.json({ 137 | reponseData, 138 | commentList: newContent.comment 139 | }); 140 | }).catch(()=>{}); 141 | }); 142 | 143 | router.get('/comment',(req, res, next)=>{ 144 | const _id = req.query.commentId || ''; 145 | Content.findOne({_id}).then((content)=>{ 146 | reponseData.msg = "获取成功"; 147 | res.json({reponseData, commentList: content.comment}); 148 | }) 149 | }) 150 | 151 | module.exports = router; -------------------------------------------------------------------------------- /router/main.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const Category = require('../models/Category'); 4 | const Content = require('../models/Content'); 5 | const markDown = require('markdown').markdown; 6 | 7 | router.get('/',(req,res,next)=>{ 8 | 9 | const data = { 10 | categoryType: req.query.type || '', 11 | count: 0, 12 | page: Number(req.query.page || 1), 13 | limit: 2, 14 | skip: 0, 15 | pages: 0, 16 | userInfo: req.userInfo, 17 | categories: [] 18 | }; 19 | let where = {}; 20 | if( data.categoryType != '' ) where.category = data.categoryType; 21 | 22 | Category.find().sort({_id: -1}).then((categories)=>{ 23 | data.categories = categories; 24 | return Content.where( where ).count(); 25 | }).then((count)=>{ 26 | data.count = count; 27 | data.pages = Math.ceil( data.count/data.limit ); 28 | data.page = Math.min( data.page, data.pages ); 29 | data.page = Math.max( data.page, 1 ); 30 | data.skip = (data.page-1)*data.limit; 31 | return Content.where( where ).find().sort({addTime: -1}).limit( data.limit ).skip( data.skip ).populate( ['category','user'] ); 32 | }).then((contents)=>{ 33 | data.contents = contents 34 | res.render('main/index',data); 35 | }).catch(()=>{}); 36 | }); 37 | 38 | router.get('/views',(req, res, next)=>{ 39 | const _id = req.query.page; 40 | Content.findOne({_id}).then((content)=>{ 41 | content.view++; 42 | content.save(); 43 | res.render('main/detail',{ 44 | userInfo: req.userInfo, 45 | content 46 | }); 47 | }) 48 | 49 | }) 50 | 51 | module.exports = router; -------------------------------------------------------------------------------- /schemas/categorise.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | module.exports = new mongoose.Schema({ 4 | name: String 5 | }) -------------------------------------------------------------------------------- /schemas/contents.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | module.exports = new mongoose.Schema({ 4 | // 关联字段 - 内容分类的id 5 | category: { 6 | // 引用类型 7 | type: mongoose.Schema.Types.ObjectId, 8 | // 引用 9 | ref: 'Category' 10 | }, 11 | user: { 12 | // 引用类型 13 | type: mongoose.Schema.Types.ObjectId, 14 | // 引用 15 | ref: 'User' 16 | }, 17 | addTime: { 18 | type: Date, 19 | default: new Date() 20 | }, 21 | view: { 22 | type: Number, 23 | default: 0 24 | }, 25 | title: String, 26 | description: { 27 | type: String, 28 | default: '' 29 | }, 30 | content: { 31 | type: String, 32 | default: '' 33 | }, 34 | comment: { 35 | type: Array, 36 | default: [] 37 | } 38 | }); -------------------------------------------------------------------------------- /schemas/users.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | module.exports = new mongoose.Schema({ 4 | username: String, 5 | password: String, 6 | isAdmin: { 7 | type: Boolean, 8 | default: false 9 | } 10 | }) -------------------------------------------------------------------------------- /static/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/.DS_Store -------------------------------------------------------------------------------- /static/README_img/WechatIMG5212.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/README_img/WechatIMG5212.jpeg -------------------------------------------------------------------------------- /static/README_img/WechatIMG5213.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/README_img/WechatIMG5213.jpeg -------------------------------------------------------------------------------- /static/README_img/WechatIMG5214.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/README_img/WechatIMG5214.jpeg -------------------------------------------------------------------------------- /static/README_img/WechatIMG5215.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/README_img/WechatIMG5215.jpeg -------------------------------------------------------------------------------- /static/fePage/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/.DS_Store -------------------------------------------------------------------------------- /static/fePage/.idea/.name: -------------------------------------------------------------------------------- 1 | fePage -------------------------------------------------------------------------------- /static/fePage/.idea/dictionaries/James.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /static/fePage/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /static/fePage/.idea/fePage.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /static/fePage/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Assignment issuesJavaScript 16 | 17 | 18 | CSS 19 | 20 | 21 | Code style issuesJavaScript 22 | 23 | 24 | CoffeeScript 25 | 26 | 27 | Control flow issuesJavaScript 28 | 29 | 30 | DOM issuesJavaScript 31 | 32 | 33 | Data flow issuesJavaScript 34 | 35 | 36 | Error handlingJavaScript 37 | 38 | 39 | General 40 | 41 | 42 | GeneralCoffeeScript 43 | 44 | 45 | GeneralJavaScript 46 | 47 | 48 | Internationalization issues 49 | 50 | 51 | JavaScript 52 | 53 | 54 | JavaScript function metricsJavaScript 55 | 56 | 57 | Naming conventionsJavaScript 58 | 59 | 60 | Node.jsJavaScript 61 | 62 | 63 | Potentially confusing code constructsJavaScript 64 | 65 | 66 | Probable bugsCoffeeScript 67 | 68 | 69 | Probable bugsJavaScript 70 | 71 | 72 | Spelling 73 | 74 | 75 | XML 76 | 77 | 78 | XSLT 79 | 80 | 81 | 82 | 83 | CssConvertColorToHexInspection 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /static/fePage/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /static/fePage/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | true 47 | 48 | 49 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | $USER_HOME$/.subversion 102 | 103 | 104 | 105 | 106 | 1514864139727 107 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 138 | 141 | 142 | 143 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /static/fePage/css/main.css: -------------------------------------------------------------------------------- 1 | /* project util.css */ 2 | .center{ 3 | width: 960px; 4 | margin: 0 auto; 5 | position: relative; 6 | } 7 | header{ 8 | width: 100%; 9 | min-width: 960px; 10 | height: 30px; 11 | line-height: 30px; 12 | padding-top: 12px; 13 | padding-bottom: 12px; 14 | color: rgba(255,255,255,0.75); 15 | background-color: #24292e; 16 | } 17 | .head_logo{ 18 | display: block; 19 | width: 32px; 20 | height: 32px; 21 | border-radius: 50%; 22 | background: rgba(255,255,255,0.95); 23 | position: relative; 24 | float: left; 25 | } 26 | .head_logo:hover{ 27 | background: rgba(255,255,255,1); 28 | } 29 | .head_logo img{ 30 | position: absolute; 31 | top: 2px; 32 | left: 2px; 33 | width: 28px; 34 | height: 28px; 35 | } 36 | .head_nav{ 37 | float: right; 38 | } 39 | .head_nav a{ 40 | display: inline-block; 41 | height: 32px; 42 | line-height: 32px; 43 | float: left; 44 | margin-left: 24px; 45 | color: rgba(255,255,255,0.75); 46 | } 47 | .head_nav a:hover{ 48 | color: rgba(255,255,255,1); 49 | } 50 | .article_list{ 51 | width: 690px; 52 | float: left; 53 | display: inline-block; 54 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 55 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 56 | margin: 30px 0; 57 | padding: 30px 0; 58 | } 59 | .article_item{ 60 | display: inline-block; 61 | width: 650px; 62 | padding: 20px; 63 | position: relative; 64 | } 65 | .article_item:after{ 66 | content: ""; 67 | width: 650px; 68 | position: absolute; 69 | height: 1px; 70 | background: #e1e4e8; 71 | bottom: 0; 72 | } 73 | .article_item:last-child:after{ 74 | height: 0; 75 | } 76 | .article_item h3{ 77 | font-size: 18px; 78 | font-weight: 600; 79 | font-synthesis: style; 80 | line-height: 30px; 81 | color: #1e1e1e; 82 | } 83 | .article_main{ 84 | margin-top: 10px; 85 | display: inline-block; 86 | } 87 | .article_content{ 88 | color: #262626; 89 | font-size: 15px; 90 | line-height: 24px; 91 | max-height: 96px; 92 | overflow: hidden; 93 | } 94 | .article_tag{ 95 | width: 100%; 96 | clear: both; 97 | margin-top: 8px; 98 | } 99 | .article_tag span{ 100 | float: left; 101 | display: inline-block; 102 | padding: 6px 10px; 103 | white-space: nowrap; 104 | background-color: #f1f8ff; 105 | border-radius: 3px; 106 | color: #8590a6; 107 | font-size: 14px; 108 | line-height: 20px; 109 | } 110 | .article_tag i{ 111 | float: right; 112 | height: 32px; 113 | line-height: 32px; 114 | color: #8590a6; 115 | } 116 | .article_item:hover h3{ 117 | color: #0366d6; 118 | } 119 | .article_img{ 120 | width: 190px; 121 | height: 96px; 122 | float: left; 123 | margin-right: 20px; 124 | text-align: center; 125 | overflow: hidden; 126 | border-radius: 6px; 127 | } 128 | .article_img img{ 129 | width: auto; 130 | height: 100%; 131 | border-radius: 6px; 132 | } 133 | .banner{ 134 | margin-top: 10px; 135 | height: 285px; 136 | position: relative; 137 | } 138 | .banner img{ 139 | width: 100%; 140 | height: 100%; 141 | } 142 | .banner h2{ 143 | position: absolute; 144 | top: 100px; 145 | left: 100px; 146 | font-size: 60px; 147 | line-height: 85px; 148 | height: 85px; 149 | font-weight: bold; 150 | } 151 | .user_list{ 152 | width: 250px; 153 | float: right; 154 | display: inline-block; 155 | margin: 30px 0; 156 | padding: 0 0 30px 0; 157 | } 158 | .user_form{ 159 | background: #ffffff; 160 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 161 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 162 | border-radius: 4px; 163 | } 164 | .user_tab{ 165 | width: 100%; 166 | height: 50px; 167 | line-height: 50px; 168 | border-bottom: 1px solid rgba(27,31,35,0.15); 169 | } 170 | .user_tab span{ 171 | display: block; 172 | width: 50%; 173 | float: left; 174 | text-align: center; 175 | height: 100%; 176 | line-height: 50px; 177 | position: relative; 178 | cursor: pointer; 179 | } 180 | .user_tab span.user_cur:after{ 181 | content: ""; 182 | position: absolute; 183 | bottom: 0; 184 | left: 50%; 185 | width: 60px; 186 | margin-left: -30px; 187 | height: 2px; 188 | background: #0366d6; 189 | } 190 | .user_login,.user_register{ 191 | width: 100%; 192 | display: inline-block; 193 | margin-top: 20px; 194 | } 195 | .user_register{ 196 | display: none; 197 | } 198 | .user_input{ 199 | width: 220px; 200 | margin: 10px 15px; 201 | margin-bottom: 20px; 202 | background: #ffffff; 203 | box-shadow: inset 0 1px 2px rgba(27,31,35,0.075); 204 | border: 1px solid #d1d5da; 205 | height: 42px; 206 | line-height: 42px; 207 | border-radius: 3px; 208 | } 209 | .user_input i{ 210 | color: #8590a6; 211 | font-size: 18px; 212 | margin-left: 6px; 213 | margin-right: 8px; 214 | float: left; 215 | } 216 | .user_input input{ 217 | width: 160px; 218 | height: 30px; 219 | line-height: 30px; 220 | margin-top: 6px; 221 | float: left; 222 | font-size: 14px; 223 | } 224 | .user_login_btn,.user_register_btn{ 225 | height: 42px; 226 | line-height: 42px; 227 | text-align: center; 228 | background: #0f88eb; 229 | color: #ffffff; 230 | width: 220px; 231 | margin-left: 15px; 232 | border-radius: 4px; 233 | cursor: pointer; 234 | margin-bottom: 20px; 235 | } 236 | .user_login_btn:hover,.user_register_btn:hover{ 237 | background: #0366d6; 238 | } 239 | .user_err{ 240 | width: 100%; 241 | height: 30px; 242 | line-height: 30px; 243 | font-size: 12px; 244 | text-align: center; 245 | color: red; 246 | } 247 | .user_err span{ 248 | display: none; 249 | } 250 | .margin_bottom0{ 251 | margin-bottom: 0px; 252 | } 253 | .friendly_link{ 254 | background: #ffffff; 255 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 256 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 257 | border-radius: 4px; 258 | margin-top: 20px; 259 | display: inline-block; 260 | width: 100%; 261 | } 262 | .link_item{ 263 | width: 220px; 264 | margin-left: 15px; 265 | margin-top: 20px; 266 | margin-bottom: 20px; 267 | } 268 | .link_item a{ 269 | color: #262626; 270 | } 271 | .link_item a:hover{ 272 | color: #8590a6; 273 | } 274 | .copy_right{ 275 | color: #8590a6; 276 | width: 100%; 277 | font-size: 12px; 278 | } 279 | .user_no{ 280 | color: #8590a6; 281 | width: 100%; 282 | font-size: 12px; 283 | margin-top: 20px; 284 | margin-bottom: 10px; 285 | } 286 | .user_no i{ 287 | color: #262626; 288 | margin-left: 2px; 289 | margin-right: 2px; 290 | } 291 | .user_logined{ 292 | background: #ffffff; 293 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 294 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 295 | border-radius: 4px; 296 | margin-top: 20px; 297 | display: inline-block; 298 | width: 100%; 299 | display: none; 300 | } 301 | .user_welcome{ 302 | width: 220px; 303 | margin-top: 20px; 304 | margin-left: 15px; 305 | font-size: 16px; 306 | } 307 | .user_welcome i{ 308 | color: #0366d6; 309 | font-weight: 600; 310 | } 311 | .user_loginOut{ 312 | display: inline-block; 313 | margin: 15px; 314 | text-decoration: underline; 315 | cursor: pointer; 316 | } 317 | .user_loginOut:hover{ 318 | color: #8590a6; 319 | } 320 | 321 | /* detail */ 322 | .detail_main{ 323 | width: 700px; 324 | margin: 0 auto; 325 | } 326 | .detail_title{ 327 | font-size: 24px; 328 | line-height: 40px; 329 | width: 100%; 330 | margin-top: 50px; 331 | margin-bottom: 10px; 332 | font-weight: 600; 333 | } 334 | .detail_content{ 335 | font-size: 16px; 336 | line-height: 30px; 337 | } 338 | .detail_tag{ 339 | color: gray; 340 | height: 20px; 341 | line-height: 20px; 342 | font-size: 14px; 343 | width: 100%; 344 | margin-top: 20px; 345 | margin-bottom: 20px; 346 | } 347 | .detail_discuss{ 348 | width: 100%; 349 | display: inline-block; 350 | background: #ebf3fb; 351 | min-width: 700px; 352 | margin-top: 60px; 353 | clear: both; 354 | } 355 | .discuss{ 356 | background: #ffffff; 357 | -webkit-box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 358 | box-shadow: 0 1px 3px 0 rgba(32, 62, 100, 0.1); 359 | border-radius: 4px; 360 | width: 430px; 361 | float: left; 362 | display: inline-block; 363 | margin: 30px 0; 364 | padding: 0 0 30px 0; 365 | } 366 | .user_tab span.discuss_title{ 367 | display: inline-block; 368 | float: left; 369 | margin-left: 15px; 370 | width: 84px; 371 | text-align: center; 372 | position: relative; 373 | } 374 | .user_tab span.discuss_title:after{ 375 | content: ""; 376 | position: absolute; 377 | bottom: 0; 378 | left: 50%; 379 | width: 84px; 380 | margin-left: -40px; 381 | height: 2px; 382 | background: #0366d6; 383 | } 384 | .discuss_main{ 385 | display: inline-block; 386 | width: 400px; 387 | margin: 20px 15px; 388 | } 389 | .discuss_default{ 390 | color: #8590a6; 391 | text-align: center; 392 | padding: 20px 0; 393 | } 394 | .discuss_list{ 395 | width: 100%; 396 | } 397 | .discuss_user{ 398 | width: 100%; 399 | display: inline-block; 400 | height: 20px; 401 | line-height: 20px; 402 | } 403 | .discuss_user span{ 404 | font-size: 15px; 405 | line-height: 20px; 406 | font-weight: 600; 407 | } 408 | .discuss_user i{ 409 | margin-left: 10px; 410 | color: #8590a6; 411 | font-size: 12px; 412 | } 413 | .discuss_userMain{ 414 | width: 100%; 415 | display: inline-block; 416 | margin-bottom: 30px; 417 | font-size: 14px; 418 | line-height: 24px; 419 | margin-top: 6px; 420 | } 421 | .discuss_input{ 422 | width: 92%; 423 | padding: 10px 4%; 424 | height: 72px; 425 | font-size: 14px; 426 | line-height: 24px; 427 | text-align: left; 428 | border: 1px solid rgba(27,31,35,0.15); 429 | border-radius: 4px; 430 | } 431 | .discuss_input:focus{ 432 | border: 1px solid rgba(15,136,235,0.75); 433 | } -------------------------------------------------------------------------------- /static/fePage/css/util.css: -------------------------------------------------------------------------------- 1 | /* 全局样式表 */ 2 | @font-face { 3 | font-family: 'iconfont'; 4 | src: url('../font/iconfont.eot'); 5 | src: url('../font/iconfont.eot?#iefix') format('embedded-opentype'), 6 | url('../font/iconfont.woff') format('woff'), 7 | url('../font/iconfont.ttf') format('truetype'), 8 | url('../font/iconfont.svg#iconfont') format('svg'); 9 | } 10 | .iconfont{ 11 | font-family:"iconfont" !important; 12 | font-size:16px;font-style:normal; 13 | -webkit-font-smoothing: antialiased; 14 | -webkit-text-stroke-width: 0.2px; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ 18 | color: #8590a6; opacity:1; 19 | } 20 | ::-moz-placeholder { /* Mozilla Firefox 19+ */ 21 | color: #8590a6;opacity:1; 22 | } 23 | input:-ms-input-placeholder{ 24 | color: #8590a6;opacity:1; 25 | } 26 | input::-webkit-input-placeholder{ 27 | color: #8590a6;opacity:1; 28 | } 29 | input,button,select,textarea{ outline:none;} 30 | textarea{resize:none;} 31 | html { 32 | background-color:#fff; 33 | color: #313131; 34 | -webkit-text-size-adjust: 100%; 35 | -ms-text-size-adjust: 100% 36 | } 37 | body { 38 | font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif; 39 | } 40 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,figure,form,fieldset,legend,input,textarea,p,blockquote,th,td{ 41 | margin:0; 42 | padding:0; 43 | list-style: none; 44 | -webkit-tap-highlight-color:transparent 45 | } 46 | h1,h2,h3,h4,h5,h6{ 47 | font-size:100%; 48 | font-weight:normal; 49 | } 50 | input,textarea,select,code,kbd,pre,samp { 51 | font-size:100%; 52 | } 53 | input,button,select{border:none;outline: none;}/*去除iphone默认input样式*/ 54 | input::-webkit-outer-spin-button,input::-webkit-inner-spin-button { } 55 | table { 56 | border-collapse: collapse; 57 | border-spacing: 0; 58 | } 59 | em, i { 60 | font-style: normal; 61 | } 62 | html,body,button,input,select,textarea { 63 | font-size:14px/1.5; 64 | color:#313131; 65 | } 66 | img{ 67 | border: none; 68 | } 69 | a{ 70 | text-decoration:none !important; 71 | -webkit-tap-highlight-color:rgb(0,0,0,0);outline:none; 72 | color: #313131; 73 | cursor: pointer; 74 | } 75 | a:link { 76 | text-decoration: none; 77 | } 78 | a:visited { 79 | text-decoration: none; 80 | } 81 | a:hover { 82 | text-decoration: none; 83 | } 84 | a:active { 85 | text-decoration: none; 86 | } 87 | .fl{float: left;} 88 | .fr{float: right;} 89 | .clearfix:after{ 90 | display:block; 91 | clear:both; 92 | content:""; 93 | visibility:hidden; 94 | height:0; 95 | } 96 | .ellipsis_1{text-overflow: ellipsis;overflow: hidden;white-space: nowrap; word-wrap: break-word;} 97 | .ellipsis_2{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;} 98 | .ellipsis_3{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 3;-webkit-box-orient: vertical;} 99 | .ellipsis_4{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 4;-webkit-box-orient: vertical;} 100 | .ellipsis_6{overflow : hidden;text-overflow: ellipsis; word-wrap: break-word;display: -webkit-box;-webkit-line-clamp: 6;-webkit-box-orient: vertical;} 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /static/fePage/detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 博客详情页 10 | 11 | 12 |
13 |
14 | 17 |
18 |
19 |
20 |
21 |

js设计模式-(策略模式)【16】

22 |

2018-01-03

23 |
24 |

当然js中的对象类的方式除了json,还有数组、prototype、闭包可以做为策略本身方法和策略的统一方法,具体的方式就不多述了。 25 |
26 | 在表单验证中策略模式也可以发挥相应的作用,把某一种类型的检验放进策略本身的方法里,通过在统一方法处输出最终的校验结果,这样各逻辑间也是简明单一,操作和控制起来都是比较方便的。 27 |
28 | ps:前端的工作已经不再是当面的页面仔和几个简单的插件,对于大前端的定义也在发生着变化,各位EF就各显神通吧~

29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 评论 37 |
38 |
39 | 40 |
41 |
    42 |
  • 43 |

    一只打柴沟发表于 2018-02-03

    44 |
    45 | 哈哈哈,你这个渣渣~ 46 |
    47 |
  • 48 |
  • 49 |

    一只打柴沟发表于 2018-02-03

    50 |
    51 | 关于你说的我有一点不太认同,这个123是个什么意思,可以大喊促使擦拭u 参加比赛 52 |
    53 |
  • 54 |
  • 55 |

    一只打柴沟发表于 2018-02-03

    56 |
    57 | 哈哈哈,你这个渣渣~ 58 |
    59 |
  • 60 |
61 | 62 |
63 |
64 |
65 | 115 |
116 |
117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /static/fePage/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/font/iconfont.eot -------------------------------------------------------------------------------- /static/fePage/font/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /static/fePage/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/font/iconfont.ttf -------------------------------------------------------------------------------- /static/fePage/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/font/iconfont.woff -------------------------------------------------------------------------------- /static/fePage/image/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/image/.DS_Store -------------------------------------------------------------------------------- /static/fePage/image/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/image/banner.jpg -------------------------------------------------------------------------------- /static/fePage/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/image/logo.png -------------------------------------------------------------------------------- /static/fePage/image/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/static/fePage/image/test.jpg -------------------------------------------------------------------------------- /static/fePage/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 博客首页 10 | 11 | 12 |
13 |
14 | 17 | 24 |
25 |
26 | 30 |
31 |
32 | 33 |

js设计模式-(职责链模式)【17】

34 |
35 |

不知不觉已经过了几个年轮,昨天还有伙伴说模块化的时候,自己饶有兴致的翻开之前的seajs,requirejs,并且哒哒哒了一堆,然后又莫名失落,估计好多人都早已废弃这些东西,开启了各自mvvm实践之路。哈哈,总是这么多愁善感。

36 |
37 | 41 |
42 | 43 |

js设计模式-(职责链模式)【17】

44 |
45 |
46 | 47 |
48 |

不知不觉已经过了几个年轮,昨天还有伙伴说模块化的时候,自己饶有兴致的翻开之前的seajs,requirejs,并且哒哒哒了一堆,然后又莫名失落,估计好多人都早已废弃这些东西,开启了各自mvvm实践之路。哈哈,总是这么多愁善感。

49 |
50 | 54 |
55 | 56 |

js设计模式-(职责链模式)【17】

57 |
58 |

不知不觉已经过了几个年轮,昨天还有伙伴说模块化的时候,自己饶有兴致的翻开之前的seajs,requirejs,并且哒哒哒了一堆,然后又莫名失落,估计好多人都早已废弃这些东西,开启了各自mvvm实践之路。哈哈,总是这么多愁善感。

59 |
60 | 64 |
65 |
66 | 116 |
117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /static/fePage/js/main.js: -------------------------------------------------------------------------------- 1 | // project util.js 2 | $(function(){ 3 | 4 | // 登录注册切换 5 | $('.j_userTab span').on('click',function(){ 6 | var _index = $(this).index(); 7 | $(this).addClass('user_cur').siblings().removeClass('user_cur'); 8 | $('.user_login,.user_register').hide(); 9 | if( _index==0 ){ 10 | $('.user_login').css('display','inline-block'); 11 | $('.user_register').hide(); 12 | }else{ 13 | $('.user_login').hide(); 14 | $('.user_register').css('display','inline-block'); 15 | } 16 | }); 17 | 18 | // 登录校验 19 | var reg = /^[^<>"'$\|?~*&@(){}]*$/; 20 | var $login = $('#login'); 21 | var $register = $('#register'); 22 | $('.user_login_btn').on('click',function(){ 23 | if( $login.find('.user_input').eq(0).find('input').val().trim() == '' ){ 24 | $login.find('.user_err span').text('用户名不能为空').show(); 25 | return false; 26 | } 27 | if( !reg.test($login.find('.user_input').eq(0).find('input').val().trim()) ){ 28 | $login.find('.user_err span').text('用户名不能含有特殊字符').show(); 29 | return false; 30 | } 31 | if( $login.find('.user_input').eq(1).find('input').val().trim() == '' ){ 32 | $login.find('.user_err span').text('密码不能为空').show(); 33 | return false; 34 | } 35 | if( !reg.test($login.find('.user_input').eq(1).find('input').val().trim()) ){ 36 | $login.find('.user_err span').text('密码不能含有特殊字符').show(); 37 | return false; 38 | } 39 | $login.find('.user_err span').text('').hide(); 40 | }); 41 | 42 | $('.user_register_btn').on('click',function(){ 43 | if( $register.find('.user_input').eq(0).find('input').val().trim() == '' ){ 44 | $register.find('.user_err span').text('用户名不能为空').show(); 45 | return false; 46 | } 47 | if( !reg.test($register.find('.user_input').eq(0).find('input').val().trim()) ){ 48 | $register.find('.user_err span').text('用户名不能含有特殊字符').show(); 49 | return false; 50 | } 51 | if( $register.find('.user_input').eq(1).find('input').val().trim() == '' ){ 52 | $register.find('.user_err span').text('密码不能为空').show(); 53 | return false; 54 | } 55 | if( !reg.test($register.find('.user_input').eq(1).find('input').val().trim()) ){ 56 | $register.find('.user_err span').text('密码不能含有特殊字符').show(); 57 | return false; 58 | } 59 | if( $register.find('.user_input').eq(1).find('input').val().trim() != 60 | $register.find('.user_input').eq(2).find('input').val().trim() 61 | ){ 62 | $register.find('.user_err span').text('两次输入的密码不一致').show(); 63 | return false; 64 | } 65 | $register.find('.user_err span').text('').hide(); 66 | }); 67 | 68 | // 打字效果 69 | var str = 'hello world'; 70 | var i = 0; 71 | function typing(){ 72 | var divTyping = $('.banner h2'); 73 | if (i <= str.length) { 74 | divTyping.text( str.slice(0, i++) + '_' ); 75 | setTimeout(function(){typing()}, 200); 76 | }else{ 77 | divTyping.text( str ); 78 | } 79 | } 80 | typing(); 81 | }); -------------------------------------------------------------------------------- /view/admin/category_add.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |

添加分类

8 |
9 |
10 | 11 | 12 |
13 | 14 |
15 | {% endblock %} -------------------------------------------------------------------------------- /view/admin/category_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |

修改分类-{{category.name}}

8 |
9 |
10 | 11 | 12 |
13 | 14 |
15 | {% endblock %} -------------------------------------------------------------------------------- /view/admin/category_index.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |

分类列表

8 | 9 | 10 | 11 | 12 | 13 | 14 | {% for category in categories %} 15 | 16 | 17 | 18 | 22 | 23 | {% endfor %} 24 |
ID栏目名称编辑
{{category._id.toString()}}{{category.name}} 19 | 修改 | 20 | 删除 21 |
25 | {% include 'page.html' %} 26 | {% endblock %} -------------------------------------------------------------------------------- /view/admin/content_add.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |

添加内容

8 |
9 |
10 | 11 | 16 |
17 |
18 | 19 | 20 |
21 |
22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 | 30 |
31 | {% endblock %} -------------------------------------------------------------------------------- /view/admin/content_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |

修改内容

8 |
9 |
10 | 11 | 20 |
21 |
22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 | 54 | {% endblock %} 55 | -------------------------------------------------------------------------------- /view/admin/content_index.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |

内容列表

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% for content in contents %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | {% endfor %} 32 |
ID所属栏目内容标题作者时间阅读量编辑
{{content._id.toString()}}{{content.category.name}}{{content.title}}{{content.user.username}}{{content.addTime | date('Y-m-d H:i:s', -8*60)}}{{content.view}} 27 | 修改 | 28 | 删除 29 |
33 | {% include 'page.html' %} 34 | {% endblock %} -------------------------------------------------------------------------------- /view/admin/error.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |
8 |
9 |

错误提示

10 |
11 |
12 | {{msg}} 13 |
14 |
15 | {% if url %} 16 | 点击这里跳转 17 | {% else %} 18 | 返回上一页 19 | {% endif %} 20 | 21 | {% endblock %} 22 | 23 | 24 | -------------------------------------------------------------------------------- /view/admin/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 |
4 |

Hello, {{userInfo.username}}

5 |

欢迎来到博客后台首页~

6 |
7 | {% endblock %} 8 | 9 | 10 | -------------------------------------------------------------------------------- /view/admin/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 后台管理首页 12 | 13 | 14 | 48 |
49 | {% block main %}{% endblock %} 50 |
51 | 52 | -------------------------------------------------------------------------------- /view/admin/page.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /view/admin/success.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |
8 |
9 |

成功提示

10 |
11 |
12 | {{msg}} 13 |
14 |
15 | {% if url %} 16 | 点击这里跳转 17 | {% else %} 18 | 返回上一页 19 | {% endif %} 20 | 21 | {% endblock %} 22 | 23 | 24 | -------------------------------------------------------------------------------- /view/admin/user_index.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout.html' %} 2 | {% block main %} 3 | 7 |

用户列表

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for user in users %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% endfor %} 23 |
ID用户名密码是否是管理员
{{user._id.toString()}}{{user.username}}{{user.password}}{% if user.isAdmin %}是{% else %}否{% endif %}
24 | {% include 'page.html' %} 25 | {% endblock %} -------------------------------------------------------------------------------- /view/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jamesblog/node-blog/8556a6526d6ebcc7c8e933b8f438da1fbc218912/view/index.html -------------------------------------------------------------------------------- /view/main/detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 博客详情页 11 | 12 | 13 |
14 |
15 | 18 |
19 |
20 |
21 |
22 |

{{content.title}}

23 |

日期:{{content.addTime | date('Y-m-d', -8*60)}} -阅读量:{{content.view}}

24 | 25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | 评论 33 |
34 |
35 |
36 |
    37 | 38 |
39 | {% if userInfo._id %} 40 | 41 | 42 |

提 交

43 | {% else %} 44 |

您还没有登录,请先登录~

45 | {% endif %} 46 |
47 |
48 |
49 | 106 |
107 |
108 | 109 | 110 | 111 | 123 | 124 | -------------------------------------------------------------------------------- /view/main/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 博客首页 10 | 11 | 12 |
13 |
14 | 17 | 32 |
33 |
34 | 38 |
39 |
40 | {% for content in contents %} 41 | 42 |

{{content.title}}

43 |
44 |

{{content.description}}

45 |
46 | 50 |
51 | {% endfor %} 52 | 53 | {% if pages>1 %} 54 | 67 | {% elseif count==0 %} 68 |

没有相关内容

69 | {% endif %} 70 |
71 | 128 |
129 | 130 | 131 | 132 | --------------------------------------------------------------------------------