├── .babelrc ├── public └── favicon.ico ├── views ├── favicon.ico ├── css │ ├── index.css │ └── App.css ├── index.js ├── components │ ├── MyFollow.js │ ├── Settings.js │ ├── Favorites.js │ ├── UserCenter.js │ ├── WriteBlog.js │ ├── BlogDetail.js │ ├── MyMenu.js │ ├── TopBar.js │ ├── Home.js │ ├── MyBlogs.js │ ├── SignIn.js │ └── SignUp.js ├── utils │ ├── UrlUtil.js │ └── colors.js ├── index.html ├── logo.svg └── App.js ├── screenshot ├── home_page.png ├── npm_button.png ├── register_page.png └── github_screenshot.png ├── .idea ├── misc.xml ├── vcs.xml ├── modules.xml ├── jsLibraryMappings.xml └── HiBlog.iml ├── test └── App.test.js ├── routes ├── userInfo.js ├── BaseRouter.js ├── RouterManager.js ├── HomePageRouter.js ├── BlogRouter.js └── UserRouter.js ├── .gitignore ├── config └── default.js ├── server ├── lib │ ├── ResponseUtil.js │ └── MongoUtil.js ├── DealBlog.js ├── DealSignUp.js ├── models │ ├── BlogModel.js │ └── UserModel.js └── middlewares │ └── LoginCheck.js ├── webpack.config.js ├── package.json ├── server.js └── README.md /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["transform-react-jsx"] 4 | ] 5 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenjiajun53/HiBlog/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /views/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenjiajun53/HiBlog/HEAD/views/favicon.ico -------------------------------------------------------------------------------- /screenshot/home_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenjiajun53/HiBlog/HEAD/screenshot/home_page.png -------------------------------------------------------------------------------- /views/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /screenshot/npm_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenjiajun53/HiBlog/HEAD/screenshot/npm_button.png -------------------------------------------------------------------------------- /screenshot/register_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenjiajun53/HiBlog/HEAD/screenshot/register_page.png -------------------------------------------------------------------------------- /screenshot/github_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shenjiajun53/HiBlog/HEAD/screenshot/github_screenshot.png -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /views/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import './css/index.css'; 5 | 6 | // ReactDOM.render( 7 | // , 8 | // document.getElementById('root') 9 | // ); 10 | -------------------------------------------------------------------------------- /test/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from '../views/App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | }); 9 | -------------------------------------------------------------------------------- /routes/userInfo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/1/23. 3 | */ 4 | var express = require('express'); 5 | var router = express.Router(); 6 | 7 | router.get('/:name', function (req, res) { 8 | res.send('hello, ' + req.params.name); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | 9 | # production 10 | build 11 | 12 | # misc 13 | .DS_Store 14 | .env 15 | npm-debug.log 16 | 17 | .idea 18 | uploadFiles/ 19 | -------------------------------------------------------------------------------- /config/default.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | module.exports = { 5 | port: 8006, 6 | session: { 7 | secret: 'hiblog', 8 | key: 'hiblog', 9 | maxAge: 2592000000 10 | }, 11 | mongodb: 'mongodb://localhost:27017/hiblog' 12 | }; -------------------------------------------------------------------------------- /server/lib/ResponseUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/15. 3 | */ 4 | class ResponseUtil { 5 | constructor(result, error) { 6 | return { 7 | result: result, 8 | error: error 9 | } 10 | } 11 | } 12 | module.exports = ResponseUtil; -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /views/components/MyFollow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/2/4. 3 | */ 4 | import React, {Component} from 'react'; 5 | 6 | class MyFollow extends React.Component { 7 | render() { 8 | return ( 9 |
10 |

关注

11 |
12 | ); 13 | } 14 | } 15 | export default MyFollow; -------------------------------------------------------------------------------- /views/components/Settings.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/18. 3 | */ 4 | import React, {Component} from 'react'; 5 | 6 | class Settings extends React.Component { 7 | render() { 8 | return ( 9 |
10 |

设置

11 |
12 | ); 13 | } 14 | } 15 | export default Settings; -------------------------------------------------------------------------------- /views/components/Favorites.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/18. 3 | */ 4 | import React, {Component} from 'react'; 5 | 6 | class Favorites extends React.Component { 7 | render() { 8 | return ( 9 |
10 |

收藏

11 |
12 | ); 13 | } 14 | } 15 | export default Favorites; -------------------------------------------------------------------------------- /views/components/UserCenter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | import React, {Component} from 'react'; 5 | 6 | class UserCenter extends Component { 7 | render() { 8 | return ( 9 |
10 |

UserCenter

11 |
12 | ); 13 | } 14 | } 15 | export default UserCenter; -------------------------------------------------------------------------------- /routes/BaseRouter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/11. 3 | */ 4 | let express = require('express'); 5 | // let checkNotLogin = require('../server/middlewares/check').checkNotLogin; 6 | 7 | let router = express.Router(); 8 | class BaseRouter { 9 | constructor() { 10 | this.setUpRouter(); 11 | } 12 | 13 | setUpRouter() { 14 | 15 | } 16 | 17 | getRouter() { 18 | return router; 19 | } 20 | } 21 | module.exports = BaseRouter; -------------------------------------------------------------------------------- /server/DealBlog.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/12. 3 | */ 4 | let BlogModel = require("./models/BlogModel"); 5 | 6 | class DealBlog { 7 | constructor(blog) { 8 | this.blog = blog; 9 | } 10 | 11 | 12 | 13 | restoreBlog() { 14 | // console.log("userName=" + this.userName + " pass=" + this.pass); 15 | // let mongoUtil = new MongoUtil(); 16 | // mongoUtil.connect(); 17 | let blogModel = new BlogModel(this.blog); 18 | return blogModel.createBlog(); 19 | } 20 | } 21 | 22 | module.exports = DealBlog; -------------------------------------------------------------------------------- /server/DealSignUp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/2/9. 3 | */ 4 | // let MongoUtil = require("./lib/MongoUtil"); 5 | let UserModel = require("./models/UserModel"); 6 | 7 | class DealSignUp { 8 | constructor(userName, pass, userIntro) { 9 | this.userName = userName; 10 | this.pass = pass; 11 | this.userIntro = userIntro; 12 | } 13 | 14 | restoreUser() { 15 | // console.log("userName=" + this.userName + " pass=" + this.pass); 16 | // let mongoUtil = new MongoUtil(); 17 | // mongoUtil.connect(); 18 | let userModel = new UserModel(this.userName, this.pass, this.userIntro); 19 | return userModel.createUser(); 20 | } 21 | } 22 | 23 | module.exports = DealSignUp; 24 | -------------------------------------------------------------------------------- /views/utils/UrlUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/2/13. 3 | */ 4 | export default class UrlUtil { 5 | constructor() { 6 | 7 | } 8 | 9 | json2Url(rawUrl, json) { 10 | let href = Object.keys(json).map(function (key) { 11 | return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]); 12 | }).join('&'); 13 | return rawUrl + "?" + href; 14 | } 15 | 16 | url2Json(url) { 17 | let hash; 18 | let myJson = {}; 19 | let hashes = url.slice(url.indexOf('?') + 1).split('&'); 20 | for (let i = 0; i < hashes.length; i++) { 21 | hash = hashes[i].split('='); 22 | myJson[hash[0]] = hash[1]; 23 | } 24 | return myJson; 25 | } 26 | } -------------------------------------------------------------------------------- /routes/RouterManager.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/11. 3 | */ 4 | let HomePageRouter = require("./HomePageRouter"); 5 | let UserRouter = require("./UserRouter"); 6 | let BlogRouter = require("./BlogRouter"); 7 | let LoginCheck = require('../server/middlewares/LoginCheck'); 8 | 9 | class RouterManager { 10 | constructor(app) { 11 | this.app = app; 12 | // this.startRouters(); 13 | } 14 | 15 | setApp(app) { 16 | this.app = app; 17 | } 18 | 19 | startRouters() { 20 | this.app.use("/", new HomePageRouter().getRouter()); 21 | this.app.use("/api", new UserRouter().getRouter()); 22 | this.app.use("/api", new BlogRouter().getRouter()); 23 | } 24 | } 25 | 26 | module.exports = RouterManager; -------------------------------------------------------------------------------- /.idea/HiBlog.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /views/css/App.css: -------------------------------------------------------------------------------- 1 | .dark-primary-color { 2 | background: #5D4037; 3 | } 4 | 5 | .default-primary-color { 6 | background: #795548; 7 | } 8 | 9 | .light-primary-color { 10 | background: #D7CCC8; 11 | } 12 | 13 | .text-primary-color { 14 | color: #FFFFFF; 15 | } 16 | 17 | .accent-color { 18 | background: #009688; 19 | } 20 | 21 | .primary-text-color { 22 | color: #212121; 23 | } 24 | 25 | .secondary-text-color { 26 | color: #757575; 27 | } 28 | 29 | .divider-color { 30 | border-color: #BDBDBD; 31 | } 32 | 33 | .App { 34 | text-align: center; 35 | font-family: 'Roboto', sans-serif; 36 | } 37 | 38 | .App-logo { 39 | animation: App-logo-spin infinite 20s linear; 40 | height: 80px; 41 | } 42 | 43 | .App-header { 44 | background-color: #222; 45 | height: 150px; 46 | padding: 20px; 47 | color: orange; 48 | } 49 | 50 | .App-intro { 51 | font-size: large; 52 | } 53 | 54 | @keyframes App-logo-spin { 55 | from { 56 | transform: rotate(0deg); 57 | } 58 | to { 59 | transform: rotate(360deg); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 18 | Hi Blog 19 | 20 | 21 |
22 | 23 |
24 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /server/models/BlogModel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/12. 3 | */ 4 | let MongoUtil = require("../lib/MongoUtil"); 5 | 6 | let blogSechma = { 7 | userId: String, 8 | blogTitle: String, 9 | blogContent: String, 10 | time: Number 11 | }; 12 | let modelName = "blog"; 13 | class BlogModel { 14 | constructor(blog) { 15 | this.blog = blog; 16 | } 17 | 18 | setBlog(blog) { 19 | this.blog = blog; 20 | } 21 | 22 | createBlog() { 23 | let blogValue = { 24 | userId: this.blog.userId, 25 | blogTitle: this.blog.blogTitle, 26 | blogContent: this.blog.blogContent, 27 | time: Date.now() 28 | }; 29 | let mongoUtil = new MongoUtil(); 30 | return mongoUtil.createModel(modelName, blogSechma, blogValue); 31 | } 32 | 33 | findBlogs() { 34 | let mongoUtil = new MongoUtil(); 35 | return mongoUtil.findModelSort(modelName, blogSechma, {_id: -1}); 36 | } 37 | 38 | findBlogByUser(userId) { 39 | let mongoUtil = new MongoUtil(); 40 | return mongoUtil.findModelByKeyMap(modelName, blogSechma, {"userId": userId}); 41 | } 42 | 43 | findBlogById(blogId) { 44 | let mongoUtil = new MongoUtil(); 45 | return mongoUtil.findModelByKeyMap(modelName, blogSechma, {"_id": blogId}); 46 | } 47 | } 48 | 49 | module.exports = BlogModel; -------------------------------------------------------------------------------- /server/middlewares/LoginCheck.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | let UserModel = require("../models/UserModel"); 5 | let ResponseUtil = require("../lib/ResponseUtil"); 6 | class LoginCheck { 7 | constructor() { 8 | 9 | } 10 | 11 | checkLogin(req, res) { 12 | if (req.session.user) { 13 | return true; 14 | } else { 15 | return false; 16 | } 17 | } 18 | 19 | ifLoginReturn(req, res, next) { 20 | // console.log("user save success 4444 " + req.session.user); 21 | if (req.session.user) { 22 | console.log("已登录 返回"); 23 | req.flash('error', '已登录'); 24 | return res.send(new ResponseUtil({redirect: "/"}, null));//返回之前的页面 25 | } else { 26 | console.log("未登录"); 27 | } 28 | next(); 29 | } 30 | 31 | userNameHasOccupied(req, res, next) { 32 | console.log("check has occupied" + req.body.userName); 33 | let user = req.body; 34 | let userModel = new UserModel(); 35 | userModel.findUserByName(user.userName) 36 | .then( 37 | (models) => { 38 | if (models.length > 0) { 39 | return res.json(new ResponseUtil({userOccupied: true}, null)); 40 | } else { 41 | next(); 42 | } 43 | } 44 | ) 45 | } 46 | } 47 | module.exports = LoginCheck; -------------------------------------------------------------------------------- /server/models/UserModel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/2/9. 3 | */ 4 | let MongoUtil = require("../lib/MongoUtil"); 5 | 6 | let userSechma = { 7 | userName: String, 8 | pass: String, 9 | userIntro: String, 10 | fileName: String 11 | }; 12 | let modelName = "user"; 13 | class UserModel { 14 | constructor(userName, pass, userIntro, fileName) { 15 | this.userName = userName; 16 | this.pass = pass; 17 | this.userIntro = userIntro; 18 | this.fileName = fileName; 19 | } 20 | 21 | setUser(userName, pass, userIntro, fileName) { 22 | this.userName = userName; 23 | this.pass = pass; 24 | this.userIntro = userIntro; 25 | this.fileName = fileName; 26 | } 27 | 28 | createUser() { 29 | let userValue = { 30 | userName: this.userName, 31 | pass: this.pass, 32 | userIntro: this.userIntro, 33 | fileName: this.fileName 34 | }; 35 | let mongoUtil = new MongoUtil(); 36 | return mongoUtil.createModel(modelName, userSechma, userValue); 37 | } 38 | 39 | findUserByName(userName) { 40 | let mongoUtil = new MongoUtil(); 41 | return mongoUtil.findModelByKeyMap(modelName, userSechma, {userName, userName}); 42 | } 43 | 44 | findUserById(_id) { 45 | let mongoUtil = new MongoUtil(); 46 | return mongoUtil.findModelByKeyMap(modelName, userSechma, {_id, _id}); 47 | } 48 | } 49 | 50 | module.exports = UserModel; -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/1/23. 3 | */ 4 | const webpack = require('webpack'); 5 | const path = require('path'); 6 | 7 | //命令行 webpack --minimize 压缩 8 | const minimize = process.argv.indexOf('--minimize') !== -1; 9 | 10 | module.exports = { 11 | // 页面入口文件配置 12 | entry: path.resolve(__dirname + '/views/App.js'), 13 | // 入口文件输出配置 14 | output: { 15 | path: path.resolve(__dirname + '/output/js'), 16 | filename: '[name].bundle.js' 17 | }, 18 | module: { 19 | // 加载器配置 20 | loaders: [ 21 | { 22 | test: /.jsx?$/, 23 | loader: 'babel-loader', 24 | exclude: /node_modules/, 25 | query: { 26 | presets: ['es2015', 'react'] 27 | } 28 | }, 29 | { 30 | test: /\.css$/, 31 | loader: 'style-loader!css-loader' 32 | } 33 | ] 34 | }, 35 | // 其他解决方案配置 36 | resolve: { 37 | extensions: ['', '.js', '.jsx', '.css', '.json'], 38 | }, 39 | 40 | // 插件项 41 | plugins: minimize ? [ 42 | new webpack.optimize.UglifyJsPlugin({ 43 | compress: { 44 | warnings: false, 45 | }, 46 | output: { 47 | comments: false, 48 | }, 49 | }), 50 | new webpack.DefinePlugin({ 51 | 'process.env': { 52 | NODE_ENV: JSON.stringify('production') 53 | } 54 | }), 55 | ] : [] 56 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HiBlog", 3 | "version": "0.1.0", 4 | "private": true, 5 | "engines": { 6 | "node": "^7.4.0", 7 | "npm": ">= 3.x.x" 8 | }, 9 | "devDependencies": { 10 | "concurrently": "^3.1.0", 11 | "nodemon": "^1.11.0", 12 | "supervisor": "^0.12.0" 13 | }, 14 | "dependencies": { 15 | "antd": "^2.6.4", 16 | "babel-core": "^6.22.1", 17 | "babel-loader": "^6.2.10", 18 | "babel-preset-es2015": "^6.22.0", 19 | "babel-preset-react": "^6.22.0", 20 | "body-parser": "^1.16.0", 21 | "config-lite": "^1.5.0", 22 | "connect-flash": "^0.1.1", 23 | "connect-mongo": "^1.3.2", 24 | "cookie-parser": "^1.4.3", 25 | "css-loader": "^0.26.1", 26 | "ejs": "^2.5.5", 27 | "express": "^4.14.1", 28 | "express-formidable": "^1.0.0", 29 | "express-session": "^1.15.0", 30 | "express-winston": "^2.1.3", 31 | "jsx-loader": "^0.13.2", 32 | "marked": "^0.3.6", 33 | "material-ui": "^0.16.7", 34 | "moment": "^2.17.1", 35 | "mongoose": "^4.8.1", 36 | "multer": "^1.3.0", 37 | "objectid-to-timestamp": "^1.3.0", 38 | "react": "^15.4.2", 39 | "react-dom": "^15.4.2", 40 | "react-router": "^3.0.2", 41 | "react-tap-event-plugin": "^2.0.1", 42 | "roboto": "^0.8.2", 43 | "sha1": "^1.1.1", 44 | "style-loader": "^0.13.1", 45 | "webpack": "^1.14.0", 46 | "winston": "^2.3.1" 47 | }, 48 | "scripts": { 49 | "start": "node server.js", 50 | "start-supervisor": "supervisor --harmony server", 51 | "start-nodemon": "nodemon server.js", 52 | "build": "webpack --watch", 53 | "start-dev": "concurrently \"npm run start\" \"npm run build\"", 54 | "start-dev-supervisor": "concurrently \"npm run start-supervisor\" \"npm run build\"", 55 | "start-dev-nodemon": "concurrently \"npm run start-nodemon\" \"npm run build\"" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /views/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/1/23. 3 | */ 4 | let express = require('express'); 5 | let app = express(); 6 | let path = require('path'); 7 | let ejs = require('ejs'); 8 | let bodyParser = require("body-parser"); 9 | let MongoUtil = require("./server/lib/MongoUtil"); 10 | let session = require('express-session'); 11 | let MongoStore = require('connect-mongo')(session); 12 | let cookieParser=require("cookie-parser"); 13 | let config = require('config-lite'); 14 | let flash = require('connect-flash'); 15 | 16 | let homeRouter = require('./routes/HomePageRouter'); 17 | let userRouter = require('./routes/userInfo'); 18 | // let signRouter = require("./server/signUp").signUp; 19 | // let DealSignUp = require("./server/DealSignUp"); 20 | let RouterManager = require("./routes/RouterManager"); 21 | 22 | // 设置模板目录 23 | app.set('views', './views'); 24 | 25 | // 设置模板引擎为 ejs 26 | app.set('view engine', 'html'); 27 | app.engine('html', ejs.renderFile); 28 | 29 | // app.use配置 30 | app.use('/output', express.static(path.join(__dirname, '/output'))); 31 | app.use('/views', express.static(path.join(__dirname, '/views'))); 32 | app.use('/uploadFiles', express.static(path.join(__dirname, '/uploadFiles'))); 33 | 34 | app.use(cookieParser()); 35 | 36 | app.use(session({ 37 | name: config.session.key,// 设置 cookie 中保存 session id 的字段名称 38 | secret: config.session.secret,// 通过设置 secret 来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改 39 | cookie: { 40 | maxAge: config.session.maxAge// 过期时间,过期后 cookie 中的 session id 自动删除 41 | }, 42 | store: new MongoStore({// 将 session 存储到 mongodb 43 | url: config.mongodb// mongodb 地址 44 | }) 45 | })); 46 | 47 | 48 | // flash 中间价,用来显示通知 49 | app.use(flash()); 50 | 51 | // 添加模板必需的三个变量 52 | app.use(function (req, res, next) { 53 | res.locals.user = req.session.user; 54 | res.locals.success = req.flash('success').toString(); 55 | res.locals.error = req.flash('error').toString(); 56 | console.log("server session.user=" + req.session.user); 57 | next(); 58 | }); 59 | 60 | 61 | app.use(bodyParser.json()); 62 | app.use(bodyParser.urlencoded({extended: true})); 63 | 64 | app.use(function (req, res, next) { 65 | console.log('Time:', Date.now()); 66 | next(); 67 | }); 68 | 69 | // app.use('/', homeRouter); 70 | app.use('/users', userRouter); 71 | 72 | let routerManager = new RouterManager(app); 73 | routerManager.startRouters(); 74 | 75 | 76 | app.get('*', function (request, response) { 77 | response.sendFile(path.resolve(__dirname, 'views', 'index.html')) 78 | }); 79 | 80 | let mongoUtil = new MongoUtil(); 81 | mongoUtil.connect(); 82 | 83 | app.listen(process.env.PORT || 5006); 84 | 85 | console.log("url=" + process.env.PORT); -------------------------------------------------------------------------------- /server/lib/MongoUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/2/9. 3 | */ 4 | let config = require('config-lite'); 5 | let mongoose = require('mongoose'); 6 | 7 | let mongoConnected = false; 8 | class MongoUtil { 9 | constructor() { 10 | 11 | } 12 | 13 | connect() { 14 | console.log("mongoose start connect"); 15 | mongoose.connect(config.mongodb); 16 | 17 | let db = mongoose.connection; 18 | db.on('error', () => { 19 | console.error.bind(console, 'connection error:'); 20 | this.connect(); 21 | }); 22 | db.once('open', function (callback) { 23 | // yay! 24 | console.log("open db success"); 25 | mongoConnected = true; 26 | }); 27 | } 28 | 29 | checkConnected() { 30 | return mongoConnected; 31 | } 32 | 33 | createModel(modelName, schema, modelValue) { 34 | let modelSchema = mongoose.Schema(schema); 35 | 36 | let Model; 37 | try { 38 | Model = mongoose.model(modelName); //判断Model是不是已存在 39 | } catch (error) { 40 | Model = mongoose.model(modelName, modelSchema); 41 | } 42 | 43 | let model = new Model(modelValue); 44 | // let promise = model.save(); 45 | // return promise; 46 | return model.save(); //promise 返回model 47 | // return model.save(function (err, model) { 48 | // if (err) { 49 | // return console.error(err); 50 | // } else { 51 | // console.log(modelName + "save success" + model._id); 52 | // 53 | // } 54 | // }); 55 | } 56 | 57 | findModel(modelName, schema) { 58 | let modelSchema = mongoose.Schema(schema); 59 | 60 | let Model; 61 | try { 62 | Model = mongoose.model(modelName); //判断Model是不是已存在 63 | } catch (error) { 64 | Model = mongoose.model(modelName, modelSchema); 65 | } 66 | return Model.find({}); 67 | // return model.save(); //promise 返回model 68 | } 69 | 70 | findModelSort(modelName, schema, sort) { 71 | let modelSchema = mongoose.Schema(schema); 72 | 73 | let Model; 74 | try { 75 | Model = mongoose.model(modelName); //判断Model是不是已存在 76 | } catch (error) { 77 | Model = mongoose.model(modelName, modelSchema); 78 | } 79 | return Model.find({}).sort(sort); 80 | // return model.save(); //promise 返回model 81 | } 82 | 83 | findModelByKeyMap(modelName, schema, keymap) { 84 | let modelSchema = mongoose.Schema(schema); 85 | 86 | let Model; 87 | try { 88 | Model = mongoose.model(modelName); //判断Model是不是已存在 89 | } catch (error) { 90 | Model = mongoose.model(modelName, modelSchema); 91 | } 92 | return Model.find(keymap); 93 | // return model.save(); //promise 返回model 94 | } 95 | } 96 | 97 | module.exports = MongoUtil; -------------------------------------------------------------------------------- /routes/HomePageRouter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/1/23. 3 | */ 4 | let express = require('express'); 5 | let LoginCheck = require('../server/middlewares/LoginCheck'); 6 | let BaseRouter = require("./BaseRouter"); 7 | let router = express.Router(); 8 | let BlogModel = require("../server/models/BlogModel"); 9 | let UserModel = require("../server/models/UserModel"); 10 | let ResponseUtil = require("../server/lib/ResponseUtil"); 11 | 12 | class HomePageRouter extends BaseRouter { 13 | // constructor() { 14 | // super(); 15 | // // this.setUpRouter(); 16 | // } 17 | 18 | setUpRouter() { 19 | router.get('/', function (req, res) { 20 | console.log("homepage on render"); 21 | res.render('index'); 22 | // res.render(''); 23 | // res.redirect("/SignUp"); 24 | }); 25 | 26 | router.get("/api/getAllBlogs", (req, res) => { 27 | let blogList = new Array(); 28 | let blogModel = new BlogModel(); 29 | let index = 0; 30 | blogModel.findBlogs().then((blogResults) => { 31 | console.log("blogResults size=" + blogResults.length); 32 | for (let i = 0; i < blogResults.length; i++) { 33 | let userModel = new UserModel(); 34 | userModel.findUserById(blogResults[i].userId) 35 | .then((userResults) => { 36 | if (null !== userResults && userResults.length > 0) { 37 | userResults[0].pass = ""; 38 | let user = JSON.parse(JSON.stringify(userResults[0])); //clone 39 | let blog = JSON.parse(JSON.stringify(blogResults[i])); 40 | blog.user = user; 41 | blogList.push(blog); 42 | index++; 43 | console.log("blogResult=" + JSON.stringify(blog)); 44 | console.log("blogResult.user=" + JSON.stringify(blog.user)); 45 | if (index >= blogResults.length) { 46 | blogList = blogList.sort((a, b) => { 47 | if (a._id > b._id) { 48 | return -1; 49 | } else if (a._id < b._id) { 50 | return 1; 51 | } else { 52 | return 0; 53 | } 54 | }); 55 | return res.send(new ResponseUtil({ 56 | blogList: blogList 57 | }, null)); 58 | } 59 | } 60 | }) 61 | } 62 | }).catch((e) => { 63 | console.error(e); 64 | }); 65 | }); 66 | } 67 | 68 | getRouter() { 69 | return router; 70 | } 71 | 72 | } 73 | 74 | 75 | module.exports = HomePageRouter; -------------------------------------------------------------------------------- /views/App.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import {render} from 'react-dom' 4 | import './css/App.css'; 5 | import {Router, Route, IndexRoute, Link, IndexLink, browserHistory, hashHistory} from 'react-router'; 6 | 7 | import Home from "./components/Home"; 8 | import SignIn from "./components/SignIn"; 9 | import SignUp from "./components/SignUp"; 10 | import UserCenter from "./components/UserCenter"; 11 | import MyFollow from "./components/MyFollow"; 12 | import WriteBlog from "./components/WriteBlog"; 13 | import TopBar from "./components/TopBar"; 14 | import BlogDetail from "./components/BlogDetail"; 15 | import Settings from "./components/Settings"; 16 | import Favorites from "./components/Favorites"; 17 | import MyBlogs from "./components/MyBlogs"; 18 | 19 | import injectTapEventPlugin from 'react-tap-event-plugin'; 20 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 21 | // import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'; 22 | // import getMuiTheme from 'material-ui/styles/getMuiTheme'; 23 | 24 | injectTapEventPlugin(); 25 | class App extends React.Component { 26 | constructor(props) { 27 | super(props); 28 | this.state = { 29 | hasLogin: false, 30 | user: null 31 | } 32 | } 33 | 34 | componentWillMount() { 35 | let url = "/api/getUserInfo"; 36 | fetch(url, { 37 | method: "post", 38 | credentials: 'include' //很重要,设置session,cookie可用 39 | }).then( 40 | (response) => { 41 | return response.json(); 42 | } 43 | ).then( 44 | (json) => { 45 | console.log(JSON.stringify(json)); 46 | if (json.result) { 47 | this.setState({ 48 | hasLogin: json.result.hasLogin, 49 | user: json.result.user 50 | }); 51 | } 52 | // console.log("state=" + this.state.hasLogin); 53 | } 54 | ).catch( 55 | (ex) => { 56 | console.error('parsing failed', ex); 57 | }); 58 | } 59 | 60 | render() { 61 | console.log('app render'); 62 | // console.log('chileren=' + this.props.children.name); 63 | return ( 64 | 65 |
66 | 67 | 68 | {React.cloneElement(this.props.children, {user: this.state.user})} 69 |
70 |
71 | ); 72 | } 73 | } 74 | 75 | render( 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | , 91 | document.getElementById('root') 92 | ) 93 | ; 94 | 95 | export default App; 96 | -------------------------------------------------------------------------------- /views/components/WriteBlog.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | import React, {Component} from 'react'; 5 | import TextField from "material-ui/TextField" 6 | import Card from "material-ui/Card" 7 | import RaisedButton from 'material-ui/RaisedButton'; 8 | 9 | let titleTF; 10 | let contentTF; 11 | class WriteBlog extends Component { 12 | constructor(props) { 13 | super(props); 14 | } 15 | 16 | componentDidMount() { 17 | titleTF = this.refs.titleTF; 18 | contentTF = this.refs.contentTF; 19 | } 20 | 21 | sendBlog() { 22 | let titleStr = titleTF.getValue(); 23 | let contentStr = contentTF.getValue(); 24 | 25 | console.log("titleStr=" + titleStr + " contentStr=" + contentStr); 26 | 27 | let blog = { 28 | blogTitle: titleStr, 29 | blogContent: contentStr 30 | }; 31 | 32 | let url = "/api/sendBlog"; 33 | fetch(url, { 34 | method: "post", 35 | // body: data, 36 | body: JSON.stringify(blog), 37 | headers: { 38 | 'Content-Type': 'application/json' 39 | }, 40 | credentials: 'include' //很重要,设置session,cookie可用 41 | }).then( 42 | (response) => { 43 | return response.json(); 44 | } 45 | ).then( 46 | (json) => { 47 | console.log(JSON.stringify(json)); 48 | if (json.result) { 49 | let result = json.result; 50 | if (result.blogId) { 51 | window.location = result.redirect + "/" + result.blogId; 52 | } 53 | } 54 | } 55 | ).catch( 56 | (ex) => { 57 | console.error('parsing failed', ex); 58 | }); 59 | 60 | } 61 | 62 | render() { 63 | return ( 64 |
65 | 69 |
74 |
75 | 标题 76 |
77 | 81 | 82 |
83 | 内容 84 |
85 | 91 | 92 | this.sendBlog()} 93 | primary={true} 94 | label={"发布"} 95 | style={{width: "10em", alignSelf: "center"}} 96 | /> 97 |
98 |
99 |
100 | ); 101 | } 102 | } 103 | export default WriteBlog; -------------------------------------------------------------------------------- /routes/BlogRouter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/12. 3 | */ 4 | let express = require('express'); 5 | let LoginCheck = require('../server/middlewares/LoginCheck'); 6 | let BaseRouter = require("./BaseRouter"); 7 | let router = express.Router(); 8 | let BlogModel = require("../server/models/BlogModel"); 9 | let UserModel = require("../server/models/UserModel"); 10 | let ResponseUtil = require("../server/lib/ResponseUtil"); 11 | 12 | class BlogRouter extends BaseRouter { 13 | // constructor() { 14 | // super(); 15 | // // this.setUpRouter(); 16 | // } 17 | 18 | setUpRouter() { 19 | router.post("/sendBlog", (req, res) => { 20 | console.log("on Receive " + req.body.blogTitle); 21 | // console.log("on Receive " + JSON.parse(req.body)); 22 | let rawBlog = req.body; 23 | let blog = { 24 | userId: req.session.user._id, 25 | blogTitle: rawBlog.blogTitle, 26 | blogContent: rawBlog.blogContent 27 | }; 28 | let blogModel = new BlogModel(blog); 29 | blogModel.createBlog().then( 30 | (model) => { 31 | // 写入 flash 32 | req.flash('success', '注册成功'); 33 | 34 | // 跳转到首页 35 | return res.send(new ResponseUtil({ 36 | redirect: "/BlogDetail", 37 | blogId: model._id 38 | }, null)); 39 | } 40 | ).catch((e) => { 41 | console.error(e); 42 | }); 43 | }); 44 | 45 | router.get("/getBlog", (req, res) => { 46 | console.log("on Receive blogId=" + req.query.blogId); 47 | let blogModel = new BlogModel(); 48 | blogModel.findBlogById(req.query.blogId).then((blogResults) => { 49 | console.log("blogResults size=" + blogResults.length); 50 | let userModel = new UserModel(); 51 | userModel.findUserById(blogResults[0].userId) 52 | .then((userResults) => { 53 | if (null !== userResults && userResults.length > 0) { 54 | userResults[0].pass = ""; 55 | let user = JSON.parse(JSON.stringify(userResults[0])); //clone 56 | let blog = JSON.parse(JSON.stringify(blogResults[0])); 57 | blog.user = user; 58 | return res.send(new ResponseUtil({ 59 | blog: blog 60 | }, null)); 61 | } 62 | }) 63 | 64 | }).catch((e) => { 65 | console.error(e); 66 | }); 67 | }); 68 | 69 | router.post("/getBlogsByUser", (req, res) => { 70 | let user = req.body.user; 71 | console.log("user=" + JSON.stringify(user)); 72 | let blogList = new Array(); 73 | let blogModel = new BlogModel(); 74 | let index = 0; 75 | blogModel.findBlogByUser(user._id).then((blogResults) => { 76 | console.log("blogResults size=" + blogResults.length); 77 | for (let i = 0; i < blogResults.length; i++) { 78 | let blog = JSON.parse(JSON.stringify(blogResults[i])); 79 | blog.user = user; 80 | blogList.push(blog); 81 | if (i >= blogResults.length - 1) { 82 | return res.send(new ResponseUtil({ 83 | blogList: blogList 84 | }, null)); 85 | } 86 | } 87 | }).catch((e) => { 88 | console.error(e); 89 | }); 90 | }); 91 | } 92 | 93 | getRouter() { 94 | return router; 95 | } 96 | 97 | } 98 | 99 | 100 | module.exports = BlogRouter; -------------------------------------------------------------------------------- /views/components/BlogDetail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | import React, {Component} from 'react'; 5 | import UrlUtil from "../utils/UrlUtil"; 6 | import Card from "material-ui/Card" 7 | import Avatar from "material-ui/Avatar"; 8 | import moment from "moment"; 9 | import colors from "../utils/colors" 10 | 11 | class BlogDetail extends React.Component { 12 | constructor(props) { 13 | super(props); 14 | this.state = { 15 | blog: null 16 | } 17 | } 18 | 19 | componentDidMount() { 20 | let url = "/api/getBlog"; 21 | let blog = { 22 | blogId: this.props.params.blogId, 23 | }; 24 | url = new UrlUtil().json2Url(url, blog); 25 | console.log("url=" + url); 26 | 27 | fetch(url, { 28 | method: "get", 29 | credentials: 'include' //很重要,设置session,cookie可用 30 | }).then( 31 | (response) => { 32 | return response.json(); 33 | } 34 | ).then( 35 | (json) => { 36 | console.log(JSON.stringify(json)); 37 | if (json.result) { 38 | this.setState({ 39 | blog: json.result.blog, 40 | }) 41 | } 42 | } 43 | ).catch( 44 | (ex) => { 45 | console.error('parsing failed', ex); 46 | }); 47 | } 48 | 49 | render() { 50 | let blog = this.state.blog; 51 | // console.log(JSON.stringify(blog)); 52 | let avatarPath; 53 | let showAvatarImg = "none"; 54 | let showAvatarName = "flex"; 55 | let dateStr; 56 | if (blog) { 57 | if (blog.user) { 58 | if (blog.user.fileName) { 59 | avatarPath = "/uploadFiles/avatars/" + blog.user.fileName; 60 | showAvatarImg = "flex"; 61 | showAvatarName = "none"; 62 | // console.log("avatarPath=" + avatarPath); 63 | } 64 | } 65 | let time = blog.time; 66 | let date = new Date(time); 67 | dateStr = moment(date).format("YYYY-MM-DD HH:mm:ss"); 68 | } 69 | 70 | if (blog) { 71 | return ( 72 |
77 |
84 |

{blog.blogTitle}

85 |
86 | 88 | 90 | {blog.user.userName[0]} 91 | 92 |
93 |
{blog.user.userName}
94 |
{dateStr}
95 |
96 |
97 |
{blog.blogContent}
98 |
99 |
100 | ); 101 | } else { 102 | return ( 103 |
104 |
105 | ); 106 | } 107 | } 108 | } 109 | export default BlogDetail; -------------------------------------------------------------------------------- /views/components/MyMenu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/31. 3 | */ 4 | import React, {Component} from 'react'; 5 | import IconMenu from 'material-ui/IconMenu'; 6 | import MenuItem from 'material-ui/MenuItem'; 7 | import Menu from 'material-ui/Menu'; 8 | import IconButton from 'material-ui/IconButton'; 9 | import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert'; 10 | import {Router, Route, IndexRoute, Link, IndexLink, browserHistory, hashHistory} from 'react-router'; 11 | 12 | let iconMenu; 13 | export default class MyMenu extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { 17 | openMenu: false, 18 | } 19 | } 20 | 21 | open() { 22 | console.log("on menu tap22 "); 23 | // iconMenu.open(); 24 | this.setState({ 25 | openMenu: true 26 | }); 27 | } 28 | 29 | handleOnRequestChange(value) { 30 | this.setState({ 31 | openMenu: value, 32 | }); 33 | } 34 | 35 | componentDidMount() { 36 | iconMenu = this.refs.icon_menu; 37 | } 38 | 39 | onItemClick(value) { 40 | switch (value) { 41 | case "SignUp": 42 | window.location.pathname = '/SignUp'; 43 | // location.hash="/SignUp"; 44 | break; 45 | case "SignIn": 46 | window.location.pathname = '/SignIn'; 47 | break; 48 | case "MyBlogs": 49 | window.location.pathname = '/MyBlogs'; 50 | break; 51 | case "MyFollow": 52 | window.location.pathname = '/MyFollow'; 53 | break; 54 | case "Favorites": 55 | window.location.pathname = '/Favorites'; 56 | break; 57 | case "Settings": 58 | window.location.pathname = '/Settings'; 59 | break; 60 | default: 61 | break; 62 | } 63 | } 64 | 65 | SignOut() { 66 | console.log("SIgnOut"); 67 | let url = "/api/SignOut"; 68 | fetch(url, { 69 | method: "post", 70 | credentials: 'include' //很重要,设置session,cookie可用 71 | }).then( 72 | (response) => { 73 | return response.json(); 74 | } 75 | ).then( 76 | (json) => { 77 | console.log(JSON.stringify(json)); 78 | if (json.redirect) { 79 | window.location = json.redirect; 80 | } 81 | } 82 | ).catch( 83 | (ex) => { 84 | console.error('parsing failed', ex); 85 | }); 86 | } 87 | 88 | render() { 89 | if (this.props.hasLogin) { 90 | return ( 91 | this.handleOnRequestChange(value)} 95 | iconButtonElement={} 96 | anchorOrigin={{horizontal: 'right', vertical: 'top'}} 97 | targetOrigin={{horizontal: 'right', vertical: 'top'}} 98 | > 99 | this.onItemClick("MyBlogs")}/> 100 | this.onItemClick("Favorites")}/> 101 | this.onItemClick("Settings")}/> 102 | this.SignOut()}/> 103 | 104 | ); 105 | } else { 106 | return ( 107 | this.handleOnRequestChange(value)} 111 | iconButtonElement={} 112 | anchorOrigin={{horizontal: 'right', vertical: 'top'}} 113 | targetOrigin={{horizontal: 'right', vertical: 'top'}} 114 | > 115 | this.onItemClick("SignIn")}/> 116 | this.onItemClick("SignUp")}/> 117 | 118 | ); 119 | } 120 | 121 | } 122 | } -------------------------------------------------------------------------------- /views/components/TopBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/31. 3 | */ 4 | import React, {Component} from 'react'; 5 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 6 | import RaisedButton from 'material-ui/RaisedButton'; 7 | import AppBar from 'material-ui/AppBar'; 8 | import Avatar from 'material-ui/Avatar'; 9 | import Card from "material-ui/Card"; 10 | import FlatButton from "material-ui/FlatButton"; 11 | import MyMenu from "./MyMenu"; 12 | 13 | const ON_TITLE_CLICKED = 111; 14 | const ON_CARE_CLICKED = 112; 15 | const ON_MINE_CLICKED = 113; 16 | const ON_WRITE_CLICKED = 114; 17 | let myMenu; 18 | class TopBar extends React.Component { 19 | constructor(props) { 20 | super(props); 21 | } 22 | 23 | componentDidMount() { 24 | myMenu = this.refs.my_menu; 25 | } 26 | 27 | handleOpenMenu() { 28 | console.log("on menu tap"); 29 | myMenu.open(); 30 | } 31 | 32 | onTitleClick(value) { 33 | switch (value) { 34 | case ON_TITLE_CLICKED: 35 | console.log("hostname=" + window.location.hostname + 36 | " hash=" + window.location.hash + 37 | " href=" + window.location.href + 38 | " host=" + window.location.host + 39 | " pathname=" + window.location.pathname); 40 | location.pathname = '/'; 41 | break; 42 | case ON_CARE_CLICKED: 43 | location.pathname = '/MyFollow'; 44 | break; 45 | case ON_MINE_CLICKED: 46 | location.pathname = '/UserCenter'; 47 | break; 48 | case ON_WRITE_CLICKED: 49 | if (this.props.hasLogin) { 50 | location.pathname = '/WriteBlog'; 51 | } else { 52 | location.pathname = '/SignUp'; 53 | } 54 | break; 55 | default: 56 | break; 57 | } 58 | } 59 | 60 | render() { 61 | console.log('topbar render'); 62 | 63 | let avatarPath; 64 | let showAvatar = "none"; 65 | if (this.props.user) { 66 | if (this.props.user.fileName) { 67 | avatarPath = "/uploadFiles/avatars/" + this.props.user.fileName; 68 | showAvatar = "inline"; 69 | // console.log("avatarPath=" + avatarPath); 70 | } 71 | } 72 | 73 | return ( 74 | 75 |
86 | this.onTitleClick(ON_TITLE_CLICKED)}> 89 | HiBlog 90 | 91 | this.onTitleClick(ON_CARE_CLICKED)}> 94 | 关注 95 | 96 | 97 | 98 |
104 |
105 | this.onTitleClick(ON_WRITE_CLICKED)}> 108 | 写文章 109 | 110 | 114 | 119 |
120 |
121 | ); 122 | } 123 | } 124 | export default TopBar; -------------------------------------------------------------------------------- /views/components/Home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | import React, {Component} from 'react'; 5 | import Card from "material-ui/Card" 6 | import Avatar from "material-ui/Avatar"; 7 | import TouchRipple from "material-ui/internal/TouchRipple"; 8 | 9 | import moment from "moment"; 10 | import colors from "../utils/colors" 11 | 12 | // injectTapEventPlugin(); 13 | class Home extends Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { 17 | blogList: null, 18 | } 19 | } 20 | 21 | componentDidMount() { 22 | let url = "/api/getAllBlogs"; 23 | console.log("url=" + url); 24 | 25 | fetch(url, { 26 | method: "get", 27 | credentials: 'include' //很重要,设置session,cookie可用 28 | }).then( 29 | (response) => { 30 | return response.json(); 31 | } 32 | ).then( 33 | (json) => { 34 | console.log("response=" + JSON.stringify(json)); 35 | this.setState({ 36 | blogList: json.result.blogList 37 | }) 38 | } 39 | ).catch( 40 | (ex) => { 41 | console.error('parsing failed', ex); 42 | }); 43 | } 44 | 45 | onCardClick(blog) { 46 | // console.log("blogId=" + blog._id); 47 | window.location = "/BlogDetail/" + blog._id; 48 | } 49 | 50 | render() { 51 | let blogListView; 52 | 53 | // if(null != this.state.blogList){ 54 | // for (let i = 0; i < this.state.blogList.length; i++) { 55 | // blogListView.push(
56 | //

{this.state.blogList[i].blogTitle}

57 | //
{this.state.blogList[i].blogContent}
58 | //
); 59 | // } 60 | // } 61 | 62 | if (null != this.state.blogList) { 63 | blogListView = this.state.blogList.map( 64 | (blog) => { 65 | let avatarPath; 66 | let showAvatarImg = "none"; 67 | let showAvatarName = "flex"; 68 | if (blog.user) { 69 | if (blog.user.fileName) { 70 | avatarPath = "/uploadFiles/avatars/" + blog.user.fileName; 71 | showAvatarImg = "flex"; 72 | showAvatarName = "none"; 73 | console.log("avatarPath=" + avatarPath); 74 | } 75 | } 76 | // console.log("blog=" + blog.blogTitle); 77 | let time = blog.time; 78 | let date = new Date(time); 79 | let dateStr = moment(date).format("YYYY-MM-DD HH:mm:ss"); 80 | return ( 81 | 82 | this.onCardClick(blog)}> 89 |
93 |
94 | 96 | 98 | {blog.user.userName[0]} 99 | 100 |
101 |
{blog.user.userName}
102 |
{dateStr}
103 |
104 |
105 |

{blog.blogTitle}

106 |
{blog.blogContent}
107 |
108 |
109 | ); 110 | } 111 | ); 112 | } 113 | return ( 114 |
115 | {blogListView} 116 |
117 | ); 118 | } 119 | } 120 | export default Home; -------------------------------------------------------------------------------- /routes/UserRouter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/12. 3 | */ 4 | let express = require('express'); 5 | let LoginCheck = require('../server/middlewares/LoginCheck'); 6 | let BaseRouter = require("./BaseRouter"); 7 | let router = express.Router(); 8 | let UserModel = require("../server/models/UserModel"); 9 | let ResponseUtil = require("../server/lib/ResponseUtil"); 10 | let multer = require('multer'); 11 | let storage = multer.diskStorage({ 12 | destination: './uploadFiles/avatars', 13 | filename: function (req, file, cb) { 14 | console.log("fileName=" + file.originalname); 15 | fileName = Date.now() + '-' + file.originalname; 16 | cb(null, fileName); 17 | } 18 | }); 19 | // let upload = multer({dest: 'uploads/'}); 20 | let upload = multer({storage: storage}); 21 | 22 | 23 | let fileName; 24 | class UserRouter extends BaseRouter { 25 | // constructor() { 26 | // super(); 27 | // // this.setUpRouter(); 28 | // } 29 | 30 | setUpRouter() { 31 | router.post("/getUserInfo", (req, res) => { 32 | let hasLogin = new LoginCheck().checkLogin(req, res); 33 | console.log("hasLogin=" + hasLogin); 34 | res.json( 35 | new ResponseUtil({ 36 | hasLogin: hasLogin, 37 | user: req.session.user 38 | }, null)); 39 | }); 40 | 41 | router.post("/SignUp", new LoginCheck().ifLoginReturn, 42 | upload.single('avatar'), 43 | new LoginCheck().userNameHasOccupied, 44 | (req, res) => { 45 | // console.log("user save success 3333 " + req.session.user.userName); 46 | console.log("on Receive " + req.body.userName); 47 | // console.log("on Receive " + JSON.parse(req.body)); 48 | let user = req.body; 49 | let userModel = new UserModel(user.userName, user.pass, user.userIntro, fileName); 50 | userModel.createUser().then( 51 | (model) => { 52 | delete user.pass; 53 | req.session.user = model; 54 | req.session.user.pass = null; 55 | // 写入 flash 56 | console.log("保存成功 model id=" + req.session.user._id + " name=" + req.session.user.userName); 57 | req.flash('success', '注册成功'); 58 | 59 | // 跳转到首页 60 | return res.send(new ResponseUtil({redirect: "/"}, null)); 61 | // res.redirect("/"); 62 | // return res.send(user); 63 | } 64 | ).catch((e) => { 65 | console.error(e); 66 | }); 67 | } 68 | ); 69 | 70 | router.post("/SignIn", new LoginCheck().ifLoginReturn, 71 | (req, res) => { 72 | // console.log("user save success 3333 " + req.session.user.userName); 73 | console.log("on Receive " + req.body.userName); 74 | // console.log("on Receive " + JSON.parse(req.body)); 75 | let user = req.body; 76 | let userModel = new UserModel(); 77 | userModel.findUserByName(user.userName) 78 | .then( 79 | (models) => { 80 | if (null !== models && models.length > 0) { 81 | let model = models[0]; 82 | console.log("model size=" + models.length); 83 | console.log("model pass=" + model.pass); 84 | if (models[0].pass === user.pass) { 85 | req.session.user = model; 86 | req.session.user.pass = null; 87 | return res.send(new ResponseUtil({redirect: "/"}, null)); 88 | } else { 89 | return res.send(new ResponseUtil(null, {errorMsg: "用户名或密码错误", errorType: 2})); 90 | } 91 | } else { 92 | return res.send(new ResponseUtil(null, {errorMsg: "没有此用户", errorType: 1})); 93 | } 94 | } 95 | ).catch((e) => { 96 | console.error(e); 97 | return res.send(new ResponseUtil(null, {errorMsg: "没有此用户", errorType: 1})); 98 | }); 99 | } 100 | ); 101 | 102 | router.post("/SignOut", (req, res) => { 103 | req.session.user = null; 104 | req.flash('success', '登出成功'); 105 | // 登出成功后跳转到主页 106 | return res.json({redirect: "/"}); 107 | }); 108 | 109 | 110 | } 111 | 112 | getRouter() { 113 | return router; 114 | } 115 | 116 | } 117 | 118 | 119 | module.exports = UserRouter; -------------------------------------------------------------------------------- /views/components/MyBlogs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Administrator on 2017/2/18. 3 | */ 4 | import React, {Component} from 'react'; 5 | import Card from "material-ui/Card" 6 | import Avatar from "material-ui/Avatar"; 7 | import TouchRipple from "material-ui/internal/TouchRipple"; 8 | 9 | import moment from "moment"; 10 | import colors from "../utils/colors" 11 | 12 | // injectTapEventPlugin(); 13 | class MyBlogs extends Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { 17 | blogList: null, 18 | } 19 | } 20 | 21 | getBlogs() { 22 | console.log("user=" + JSON.stringify(this.props.user)); 23 | let url = "/api/getBlogsByUser"; 24 | console.log("url=" + url); 25 | 26 | let body = { 27 | user: this.props.user 28 | }; 29 | 30 | fetch(url, { 31 | method: "post", 32 | body: JSON.stringify(body), 33 | headers: { 34 | 'Content-Type': 'application/json' 35 | // 'Content-Type': 'application/x-www-form-urlencoded' 36 | }, 37 | credentials: 'include' //很重要,设置session,cookie可用 38 | }).then( 39 | (response) => { 40 | return response.json(); 41 | } 42 | ).then( 43 | (json) => { 44 | // console.log("response=" + JSON.stringify(json)); 45 | this.setState({ 46 | blogList: json.result.blogList 47 | }) 48 | } 49 | ).catch( 50 | (ex) => { 51 | console.error('parsing failed', ex); 52 | }); 53 | } 54 | 55 | 56 | onCardClick(blog) { 57 | // console.log("blogId=" + blog._id); 58 | window.location = "/BlogDetail/" + blog._id; 59 | } 60 | 61 | render() { 62 | // console.log("onRender"); 63 | let blogListView; 64 | if (null === this.state.blogList && null !== this.props.user) { 65 | this.getBlogs(); 66 | } 67 | 68 | // if(null != this.state.blogList){ 69 | // for (let i = 0; i < this.state.blogList.length; i++) { 70 | // blogListView.push(
71 | //

{this.state.blogList[i].blogTitle}

72 | //
{this.state.blogList[i].blogContent}
73 | //
); 74 | // } 75 | // } 76 | 77 | if (null != this.state.blogList) { 78 | blogListView = this.state.blogList.map( 79 | (blog) => { 80 | let avatarPath; 81 | let showAvatarImg = "none"; 82 | let showAvatarName = "flex"; 83 | if (blog.user) { 84 | if (blog.user.fileName) { 85 | avatarPath = "/uploadFiles/avatars/" + blog.user.fileName; 86 | showAvatarImg = "flex"; 87 | showAvatarName = "none"; 88 | // console.log("avatarPath=" + avatarPath); 89 | } 90 | } 91 | // console.log("blog=" + blog.blogTitle); 92 | let time = blog.time; 93 | let date = new Date(time); 94 | let dateStr = moment(date).format("YYYY-MM-DD HH:mm:ss"); 95 | return ( 96 | 97 | this.onCardClick(blog)}> 104 |
108 |
109 | 111 | 113 | {blog.user.userName[0]} 114 | 115 |
116 |
{blog.user.userName}
117 |
{dateStr}
118 |
119 |
120 |

{blog.blogTitle}

121 |
{blog.blogContent}
122 |
123 |
124 | ); 125 | } 126 | ); 127 | } 128 | return ( 129 |
130 | {blogListView} 131 |
132 | ); 133 | } 134 | } 135 | export default MyBlogs; -------------------------------------------------------------------------------- /views/components/SignIn.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | import React, {Component} from 'react'; 5 | import TextField from "material-ui/TextField" 6 | import Card from "material-ui/Card" 7 | import SelectField from 'material-ui/SelectField'; 8 | import RaisedButton from 'material-ui/RaisedButton'; 9 | import MenuItem from 'material-ui/MenuItem'; 10 | 11 | 12 | let userNameTF; 13 | let passTF; 14 | class SignIn extends Component { 15 | constructor(props) { 16 | super(props); 17 | this.state = { 18 | selectedFileName: "", 19 | nameError: "", 20 | passError: "", 21 | } 22 | } 23 | 24 | componentDidMount() { 25 | userNameTF = this.refs.userNameTF; 26 | passTF = this.refs.passTF; 27 | } 28 | 29 | onSignIn() { 30 | let userNameStr = userNameTF.getValue(); 31 | let passStr = passTF.getValue(); 32 | 33 | let infoFinished = true; 34 | if ("" === userNameStr) { 35 | this.setState({ 36 | nameError: "不能为空" 37 | }); 38 | infoFinished = false; 39 | } 40 | if ("" === passStr) { 41 | this.setState({ 42 | passError: "不能为空" 43 | }); 44 | infoFinished = false; 45 | } 46 | if (!infoFinished) { 47 | return; 48 | } 49 | 50 | let body = { 51 | "userName": userNameStr, 52 | "pass": passStr, 53 | }; 54 | let url = "/api/SignIn"; 55 | fetch(url, { 56 | method: "post", 57 | // body: data, 58 | body: JSON.stringify(body), 59 | headers: { 60 | 'Content-Type': 'application/json' 61 | // 'Content-Type': 'application/x-www-form-urlencoded' 62 | }, 63 | credentials: 'include' //很重要,设置session,cookie可用 64 | }).then( 65 | (response) => { 66 | return response.json(); 67 | } 68 | ).then( 69 | (json) => { 70 | console.log(JSON.stringify(json)); 71 | if (json.result) { 72 | if (json.result.redirect) { 73 | window.location = json.result.redirect; 74 | } 75 | } else if (json.error) { 76 | this.setState({ 77 | nameError: json.error.errorMsg, 78 | passError: json.error.errorMsg 79 | }) 80 | } 81 | } 82 | ).catch( 83 | (ex) => { 84 | console.error('parsing failed', ex); 85 | }); 86 | } 87 | 88 | render() { 89 | return ( 90 |
91 |
92 | 96 |
101 |
102 | 用户名* 103 |
104 | { 108 | if (this.state.nameError !== "") { 109 | this.setState({ 110 | nameError: "", 111 | passError: "" 112 | }) 113 | } 114 | }} 115 | ref="userNameTF" 116 | id="userNameTF" 117 | name="userNameTF"/> 118 |
119 | 密码* 120 |
121 | { 124 | if (this.state.passError !== "") { 125 | this.setState({ 126 | nameError: "", 127 | passError: "" 128 | }) 129 | } 130 | }} 131 | type="password" 132 | ref="passTF" 133 | id="passTF" 134 | name="passTF"/> 135 | this.onSignIn()} 136 | primary={true} 137 | label={"登录"} 138 | style={{width: "10em", alignSelf: "center"}} 139 | /> 140 |
141 |
142 |
143 |
144 | ); 145 | } 146 | } 147 | export default SignIn; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 用到的技术:React Node Webpack material-ui mongo 2 | 3 | github地址:https://github.com/shenjiajun53/HiBlog 4 | 喜欢请给个star!!! 5 | 推荐两个工具:https://app.astralapp.com/dashboard 这个网站可以用来管理github上的star 6 | 7 | 另一个叫 Octotree 是Chrome应用,可以看到github上的项目结构,跟IDE一样 8 | 9 | 我是一名Android开发,虽然在互联网公司,但是感觉自己的工作根本就是软件行业的工作。 10 | 想想对服务端,前端都不了解真是挺无知的。 11 | 之前看同事有自己的博客站,百度了下,发现要做那种个人网站真是很简单,只不过那根本就是个静态网站,太辣鸡,所以我决定自己撸个博客网站。 12 | 13 | 14 | 主页 15 | 16 | ![webstorm.png](./screenshot/home_page.png) 17 | 18 | 19 | 注册页 20 | 21 | ![webstorm.png](./screenshot/register_page.png) 22 | 23 | 24 | ## 下面就是技术选型啦: 25 | ### 前端: 26 | 要用就用潮的,三个著名框架Angular,React,Vue 27 | Angular听说1和2完全不兼容,最讨厌这种对开发人员不负责的框架了,不考虑 28 | Vue的语法更像常规的前端开发,React默认支持es6,风格跟Android更像,尤其跟Android的DataBinding很像。 29 | 另一方面es6很像Java,我肯定使用es6开发的,我更喜欢面向对象。Vue当然也可以用es6,但我懒得鼓捣了,更重要的ReactNative可比Weex火多了。哈哈,所以前端我就选择React了。 30 | 真正的前端开发应该更喜欢Vue吧,文档都有中文的。 31 | 32 | ### 后端: 33 | 虽然我是做Android的,但是遥想两年前第一次接触JavaEE的时候真是被恶心到了,不考虑 34 | python没有花括号,知乎上都嘲笑写python要用游标卡尺,不考虑 35 | PHP开发比Java更快,而且现在快跟Java平分秋色了吧,可以考虑。 36 | Node技术还是挺新的,各种文章资料会比较少,坑也可能比较多。但我真是不高兴再学一门语言了,所以哈哈,就选Node了。 37 | 38 | ## 运行 39 | 1.git clone 40 | 41 | 2.安装mongo,然后在安装目录下新建文件夹,比如“D:\data\db”,然后打开“D:\MongoDB\Server\3.4\bin\mongod.exe”开启服务,会有个命令行窗口保持运行 42 | 43 | 3.建议安装一个mongo可视化工具,Robomongo,默认连接localhost:27017,能连接上就说明好了 44 | 45 | 4.进入项目目录下,执行命令 46 | ``` 47 | npm install 48 | ``` 49 | 安装相关依赖库 50 | 51 | 5.执行 52 | ``` 53 | node server.js 54 | ``` 55 | 开启服务。 56 | 或者,比如我用的Webstorm,可以点击左下角npm按钮,点击start-dev-serpervisor或者点击start-dev-nodemon,都可以 57 | 58 | ![webstorm.png](./screenshot/npm_button.png) 59 | 60 | 6.打开浏览器,输入 localhost:5006 61 | 62 | 63 | ## 下面开始: 64 | 我对前后端几乎零基础,之前有看过ReactNative,顺便看了下React。 65 | 所以写的代码在内行眼里可能很丢人,哈哈 66 | 67 | ### 第一步: 68 | 安装node,新建个文件夹,HiBlog 69 | 命令行: 70 | 71 | ``` 72 | cd HiBlog 73 | ``` 74 | 初始化: 75 | ``` 76 | npm init 77 | ``` 78 | 生成package.json文件 79 | 然后安装各种需要的包,比如express--node框架,webpack--打包工具 80 | ``` 81 | npm i express --save;npm i webpack --save 82 | ``` 83 | 然后这两个就下载好了,在node_module文件夹下,引用也自动添加到package.json文件里了 84 | 或者package.json文件直接复制的别人的,里面有内容了, 85 | ``` 86 | npm i 87 | ``` 88 | 把package里所有引用都下载到node_module下。 89 | 跟Android的依赖很像啊 90 | 91 | 我的module引用 92 | ``` 93 | { 94 | "name": "HiBlog", 95 | "version": "0.1.0", 96 | "private": true, 97 | "engines": { 98 | "node": "^7.4.0", 99 | "npm": ">= 3.x.x" 100 | }, 101 | "devDependencies": { 102 | "concurrently": "^3.1.0", 103 | "nodemon": "^1.11.0", //node监听工具,改动代码自动重启服务 104 | "supervisor": "^0.12.0", //跟上面一样的,用一个就行,反正我都加了 105 | }, 106 | "dependencies": { 107 | "antd": "^2.6.4", //蚂蚁金服的UI框架,项目里没用,哈哈 108 | "babel-core": "^6.22.1", 109 | "babel-loader": "^6.2.10", 110 | "babel-preset-es2015": "^6.22.0", 111 | "babel-preset-react": "^6.22.0", 112 | "body-parser": "^1.16.0", 113 | "config-lite": "^1.5.0", 114 | "connect-flash": "^0.1.1", 115 | "connect-mongo": "^1.3.2", 116 | "cookie-parser": "^1.4.3", 117 | "css-loader": "^0.26.1", 118 | "ejs": "^2.5.5", 119 | "express": "^4.14.1", 120 | "express-formidable": "^1.0.0", 121 | "express-session": "^1.15.0", 122 | "express-winston": "^2.1.3", 123 | "jsx-loader": "^0.13.2", 124 | "marked": "^0.3.6", 125 | "material-ui": "^0.16.7", //UI框架,项目里主要用的就是这个 126 | "moment": "^2.17.1", 127 | "mongoose": "^4.8.1", //数据库框架 128 | "multer": "^1.3.0", 129 | "objectid-to-timestamp": "^1.3.0", 130 | "react": "^15.4.2", 131 | "react-dom": "^15.4.2", 132 | "react-router": "^3.0.2", 133 | "react-tap-event-plugin": "^2.0.1", 134 | "roboto": "^0.8.2", 135 | "sha1": "^1.1.1", 136 | "style-loader": "^0.13.1", 137 | "webpack": "^1.14.0", 138 | "winston": "^2.3.1" 139 | }, 140 | "scripts": { 141 | "start": "node server.js", //启动服务 142 | "start-supervisor": "supervisor --harmony server", //启动服务 代码有变动就重启 143 | "start-nodemon": "nodemon server.js", //启动服务 代码有变动就重启 144 | "build": "webpack --watch", //打包React代码, --watch代表代码有变动就重新打包 145 | "start-dev": "concurrently \"npm run start\" \"npm run build\"", 146 | "start-dev-supervisor": "concurrently \"npm run start-supervisor\" \"npm run build\"", 147 | "start-dev-nodemon": "concurrently \"npm run start-nodemon\" \"npm run build\"" 148 | } 149 | } 150 | ``` 151 | 152 | 看下我的目录结构 153 | 154 | ![2017-02-18.png](./screenshot/github_screenshot.png) 155 | 156 | 看下我的github页面,右边就是我在最上面介绍的github插件,工欲善其事必先利其器。 157 | 158 | 新建文件webpack.config.js,webpack工具会识别到这个文件里的脚本,然后把React代码打包,很重要,不然不管是React的JSX或者ES6,浏览器都读不懂。 159 | 160 | 新建文件夹views,里面是前端代码 161 | 新建文件夹routes,里面放路由代码,因为我们用的React,所以这个网站就是所谓的单页网站,One Page Website。看views下面只有一个index.html。 162 | 这个HTML就是个空壳,真正的网页都是有js代码生成的,不管是哪个页面,都依托这个HTML。所以这里和常规网页不通,网页不是由服务器渲染的一个个HTML。网站的工作方式更像APP,通过api实现网页内容变动。前后端分离才是人性化的开发方式,不是吗? 163 | 164 | 文件夹config,里面放一些设置 165 | 166 | 最重要的server.js 167 | ``` 168 | /** 169 | * Created by shenjj on 2017/1/23. 170 | */ 171 | let express = require('express'); 172 | let app = express(); 173 | let path = require('path'); 174 | let ejs = require('ejs'); 175 | let bodyParser = require("body-parser"); 176 | let MongoUtil = require("./server/lib/MongoUtil"); 177 | let session = require('express-session'); 178 | let MongoStore = require('connect-mongo')(session); 179 | let cookieParser=require("cookie-parser"); 180 | let config = require('config-lite'); 181 | let flash = require('connect-flash'); 182 | 183 | let homeRouter = require('./routes/HomePageRouter'); 184 | let userRouter = require('./routes/userInfo'); 185 | // let signRouter = require("./server/signUp").signUp; 186 | // let DealSignUp = require("./server/DealSignUp"); 187 | let RouterManager = require("./routes/RouterManager"); 188 | 189 | // 设置模板目录 190 | app.set('views', './views'); 191 | 192 | // 设置模板引擎为 ejs 193 | app.set('view engine', 'html'); 194 | app.engine('html', ejs.renderFile); 195 | 196 | // app.use配置 197 | app.use('/output', express.static(path.join(__dirname, '/output'))); 198 | //app.use('/views', express.static(path.join(__dirname, '/views'))); 199 | app.use('/uploadFiles', express.static(path.join(__dirname, '/uploadFiles'))); 200 | 201 | ... 202 | ... 203 | 204 | app.use(bodyParser.json()); 205 | app.use(bodyParser.urlencoded({extended: true})); 206 | 207 | // app.use('/', homeRouter); 208 | app.use('/users', userRouter); 209 | 210 | let routerManager = new RouterManager(app); 211 | routerManager.startRouters(); 212 | 213 | 214 | app.get('*', function (request, response) { 215 | response.sendFile(path.resolve(__dirname, 'views', 'index.html')) 216 | }); 217 | 218 | app.listen(process.env.PORT || 5006); 219 | 220 | console.log("url=" + process.env.PORT); 221 | ``` 222 | 这里开始就是真的node代码里 223 | 设置模版目录在views下面,其实就是那个index.html 224 | 这是模版引擎ejs,用来渲染成html,(有两个主流引擎ejs和jade,ejs和html一毛一样,所以我推荐这个,jade虽然省代码,但是跟python一样,太随便了) 225 | 另外我不需要用ejs的功能,所以我直接设置成HTML了。 226 | 227 | app.use('/output', express.static(path.join(__dirname, '/output'))); 228 | app.use('/uploadFiles', express.static(path.join(__dirname, '/uploadFiles'))); 229 | 用来指定打包后的js代码,在output目录下,这个是在wenpack.config里设置的 230 | uploadFiles是js代码里引用的图片,空目录,里面的图片是用户上传的。 231 | 232 | 233 | RouterManager是我写的Router管理类,从风格也能看出我就是比较习惯Java,还是面向对象舒服,虽然代码量大一点。 234 | routerManater把app传进去 235 | 236 | 最后是端口号,默认5006 237 | 238 | 239 | RouterManager里: 240 | ``` 241 | ... 242 | this.app.use("/", new HomePageRouter().getRouter()); 243 | this.app.use("/api", new UserRouter().getRouter()); 244 | this.app.use("/api", new BlogRouter().getRouter()); 245 | ... 246 | ``` 247 | 248 | HomePageRouter里: 249 | ``` 250 | router.get('/', function (req, res) { 251 | console.log("homepage on render"); 252 | res.render('index'); 253 | // res.render(''); 254 | // res.redirect("/SignUp"); 255 | }); 256 | ``` 257 | 258 | 所以就是,直接在浏览器输入localhost:5006,会跳转到主页 259 | 如果输入localhost:5006/api/xxx,会调起userRouter或者blogRouter里的接口,看那个匹配了 260 | 261 | ## 下面是部分前端代码 262 | ``` 263 | class App extends React.Component { 264 | constructor(props) { 265 | super(props); 266 | this.state = { 267 | hasLogin: false, 268 | user: null 269 | } 270 | } 271 | 272 | componentWillMount() { 273 | let url = "/api/getUserInfo"; 274 | fetch(url, { 275 | method: "post", 276 | credentials: 'include' //很重要,设置session,cookie可用 277 | }).then( 278 | (response) => { 279 | return response.json(); 280 | } 281 | ).then( 282 | (json) => { 283 | console.log(JSON.stringify(json)); 284 | if (json.result) { 285 | this.setState({ 286 | hasLogin: json.result.hasLogin, 287 | user: json.result.user 288 | }); 289 | } 290 | // console.log("state=" + this.state.hasLogin); 291 | } 292 | ).catch( 293 | (ex) => { 294 | console.error('parsing failed', ex); 295 | }); 296 | } 297 | 298 | render() { 299 | console.log('app render'); 300 | // console.log('chileren=' + this.props.children.name); 301 | return ( 302 | 303 |
304 | 305 | 306 | {React.cloneElement(this.props.children, {user: this.state.user})} 307 |
308 |
309 | ); 310 | } 311 | } 312 | 313 | render( 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | , 329 | document.getElementById('root') 330 | ) 331 | ``` 332 | 页面跳转完全由前端控制,用Rooter类,APP是整个网页的父布局。在APP渲染完成后获取user信息,this.props.children是当前页面,可以clone一个ReactComponent,并设置props。 -------------------------------------------------------------------------------- /views/components/SignUp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjiajun on 2017/1/29. 3 | */ 4 | import React, {Component} from 'react'; 5 | import TextField from "material-ui/TextField" 6 | import Card from "material-ui/Card" 7 | import SelectField from 'material-ui/SelectField'; 8 | import RaisedButton from 'material-ui/RaisedButton'; 9 | import MenuItem from 'material-ui/MenuItem'; 10 | 11 | 12 | let uploadInput; 13 | let userNameTF; 14 | let passTF; 15 | let passConfirmTF; 16 | let userIntroTF; 17 | let file; 18 | class SignUp extends React.Component { 19 | constructor(props) { 20 | super(props); 21 | this.state = { 22 | selectedGender: 1, 23 | avatarUrl: "", 24 | selectedFileName: "", 25 | nameError: "", 26 | passError: "", 27 | passConfirmError: "", 28 | userIntroError: "" 29 | } 30 | } 31 | 32 | componentDidMount() { 33 | uploadInput = this.refs.uploadInput; 34 | userNameTF = this.refs.userNameTF; 35 | passTF = this.refs.passTF; 36 | passConfirmTF = this.refs.passConfirmTF; 37 | userIntroTF = this.refs.userIntroTF; 38 | } 39 | 40 | genderSelected(event, index, value) { 41 | // console.log("genderSelected="+value); 42 | this.setState({ 43 | selectedGender: value 44 | }) 45 | } 46 | 47 | onUpLoadClick() { 48 | // console.info("onUpLoadClick="); 49 | uploadInput.click(); 50 | } 51 | 52 | avatarSelected(event) { 53 | // console.info("event=" + uploadInput.files.length); 54 | file = uploadInput.files[0]; 55 | console.info("file=" + file.name); 56 | this.setState({ 57 | selectedFileName: file.name 58 | }); 59 | // let objectURL = window.URL.createObjectURL(file); 60 | // console.info("event=" + objectURL); 61 | // window.URL.revokeObjectURL(objectURL); 62 | } 63 | 64 | onSignUp() { 65 | let userNameStr = userNameTF.getValue(); 66 | let passStr = passTF.getValue(); 67 | let passConfirmStr = passConfirmTF.getValue(); 68 | let userIntroStr = userIntroTF.getValue(); 69 | 70 | let infoFinished = true; 71 | if ("" === userNameStr) { 72 | this.setState({ 73 | nameError: "不能为空" 74 | }); 75 | infoFinished = false; 76 | } 77 | if ("" === passStr) { 78 | this.setState({ 79 | passError: "不能为空" 80 | }); 81 | infoFinished = false; 82 | } 83 | if ("" === passConfirmStr) { 84 | this.setState({ 85 | passConfirmError: "不能为空" 86 | }); 87 | infoFinished = false; 88 | } 89 | if (passConfirmStr !== passStr) { 90 | this.setState({ 91 | passError: "密码不一致", 92 | passConfirmError: "密码不一致" 93 | }); 94 | infoFinished = false; 95 | } 96 | if (!infoFinished) { 97 | return; 98 | } 99 | 100 | console.info("upload =" + userNameStr + passStr + passConfirmStr + userIntroStr); 101 | 102 | let body = { 103 | "userName": userNameStr, 104 | "pass": passStr, 105 | "passConfirm": passConfirmStr, 106 | "userIntro": userIntroStr 107 | }; 108 | let demoBody = { 109 | "userName": "shenjiajun", 110 | "pass": "12345", 111 | "passConfirm": "12345", 112 | "userIntro": "啦啦啦" 113 | }; 114 | let data = "userName=shenjiajun&pass=12345&userIntro=啦啦啦"; 115 | 116 | document.cookie = "cookie1=5006"; 117 | 118 | let formData = new FormData(); 119 | formData.append('avatar', file); 120 | formData.append('userName', userNameStr); 121 | formData.append('pass', passStr); 122 | formData.append('passConfirm', passConfirmStr); 123 | formData.append('userIntro', userIntroStr); 124 | 125 | let url = "/api/SignUp"; 126 | fetch(url, { 127 | method: "post", 128 | // body: data, 129 | body: formData, 130 | headers: { 131 | // 'Content-Type': 'application/json' 132 | // 'Content-Type': 'application/x-www-form-urlencoded' 133 | }, 134 | credentials: 'include' //很重要,设置session,cookie可用 135 | }).then( 136 | (response) => { 137 | return response.json(); 138 | } 139 | ).then( 140 | (json) => { 141 | console.log(JSON.stringify(json)); 142 | if (json.result) { 143 | let result=json.result; 144 | if (result.redirect) { 145 | window.location = result.redirect; 146 | } else if (result.userOccupied) { 147 | // window.alert("用户名已被占用"); 148 | this.setState({ 149 | nameError: "用户名已被占用" 150 | }) 151 | } 152 | } 153 | } 154 | ).catch( 155 | (ex) => { 156 | console.error('parsing failed', ex); 157 | }); 158 | } 159 | 160 | render() { 161 | return ( 162 |
163 |

注册

164 |
165 | 169 |
174 |
175 | 用户名* 176 |
177 | { 181 | if (this.state.nameError !== "") { 182 | this.setState({ 183 | nameError: "" 184 | }) 185 | } 186 | }} 187 | ref="userNameTF" 188 | id="userNameTF" 189 | name="userNameTF"/> 190 |
191 | 密码* 192 |
193 | { 196 | if (this.state.passError !== "") { 197 | this.setState({ 198 | passError: "" 199 | }) 200 | } 201 | }} 202 | type="password" 203 | ref="passTF" 204 | id="passTF" 205 | name="passTF"/> 206 |
207 | 重复密码* 208 |
209 | { 212 | if (this.state.passConfirmError !== "") { 213 | this.setState({ 214 | passConfirmError: "" 215 | }) 216 | } 217 | }} 218 | type="password" 219 | ref="passConfirmTF" 220 | id="passConfirmTF" 221 | name="passConfirmTF"/> 222 | 223 | this.genderSelected(event, index, value)} 228 | > 229 | 230 | 231 | 232 | 233 |
234 | 头像* 235 | this.onUpLoadClick()} 236 | label={"选择文件"} 237 | secondary={true} 238 | style={{marginLeft: "0.5em"}} 239 | /> 240 |
241 |
242 | {this.state.selectedFileName} 243 |
244 | this.avatarSelected(event)} 251 | /> 252 |
253 | 个人简介* 254 |
255 | 262 | 263 | this.onSignUp()} 264 | primary={true} 265 | label={"注册"} 266 | style={{width: "10em", alignSelf: "center"}} 267 | /> 268 |
269 |
270 |
271 |
272 | ); 273 | } 274 | } 275 | export default SignUp; -------------------------------------------------------------------------------- /views/utils/colors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shenjj on 2017/2/17. 3 | */ 4 | var primary_dark = exports.primary_dark = '#5D4037'; 5 | var primary_default = exports.primary_default = '#795548'; 6 | var primary_light = exports.primary_light = '#D7CCC8'; 7 | var primary_text = exports.primary_text = '#FFFFFF'; 8 | var accent = exports.accent = '#009688'; 9 | var text_primary = exports.text_primary = '#212121'; 10 | var text_secondary = exports.text_secondary = '#757575'; 11 | var divider = exports.divider = '#BDBDBD'; 12 | 13 | 14 | var red50 = exports.red50 = '#ffebee'; 15 | var red100 = exports.red100 = '#ffcdd2'; 16 | var red200 = exports.red200 = '#ef9a9a'; 17 | var red300 = exports.red300 = '#e57373'; 18 | var red400 = exports.red400 = '#ef5350'; 19 | var red500 = exports.red500 = '#f44336'; 20 | var red600 = exports.red600 = '#e53935'; 21 | var red700 = exports.red700 = '#d32f2f'; 22 | var red800 = exports.red800 = '#c62828'; 23 | var red900 = exports.red900 = '#b71c1c'; 24 | var redA100 = exports.redA100 = '#ff8a80'; 25 | var redA200 = exports.redA200 = '#ff5252'; 26 | var redA400 = exports.redA400 = '#ff1744'; 27 | var redA700 = exports.redA700 = '#d50000'; 28 | 29 | var pink50 = exports.pink50 = '#fce4ec'; 30 | var pink100 = exports.pink100 = '#f8bbd0'; 31 | var pink200 = exports.pink200 = '#f48fb1'; 32 | var pink300 = exports.pink300 = '#f06292'; 33 | var pink400 = exports.pink400 = '#ec407a'; 34 | var pink500 = exports.pink500 = '#e91e63'; 35 | var pink600 = exports.pink600 = '#d81b60'; 36 | var pink700 = exports.pink700 = '#c2185b'; 37 | var pink800 = exports.pink800 = '#ad1457'; 38 | var pink900 = exports.pink900 = '#880e4f'; 39 | var pinkA100 = exports.pinkA100 = '#ff80ab'; 40 | var pinkA200 = exports.pinkA200 = '#ff4081'; 41 | var pinkA400 = exports.pinkA400 = '#f50057'; 42 | var pinkA700 = exports.pinkA700 = '#c51162'; 43 | 44 | var purple50 = exports.purple50 = '#f3e5f5'; 45 | var purple100 = exports.purple100 = '#e1bee7'; 46 | var purple200 = exports.purple200 = '#ce93d8'; 47 | var purple300 = exports.purple300 = '#ba68c8'; 48 | var purple400 = exports.purple400 = '#ab47bc'; 49 | var purple500 = exports.purple500 = '#9c27b0'; 50 | var purple600 = exports.purple600 = '#8e24aa'; 51 | var purple700 = exports.purple700 = '#7b1fa2'; 52 | var purple800 = exports.purple800 = '#6a1b9a'; 53 | var purple900 = exports.purple900 = '#4a148c'; 54 | var purpleA100 = exports.purpleA100 = '#ea80fc'; 55 | var purpleA200 = exports.purpleA200 = '#e040fb'; 56 | var purpleA400 = exports.purpleA400 = '#d500f9'; 57 | var purpleA700 = exports.purpleA700 = '#aa00ff'; 58 | 59 | var deepPurple50 = exports.deepPurple50 = '#ede7f6'; 60 | var deepPurple100 = exports.deepPurple100 = '#d1c4e9'; 61 | var deepPurple200 = exports.deepPurple200 = '#b39ddb'; 62 | var deepPurple300 = exports.deepPurple300 = '#9575cd'; 63 | var deepPurple400 = exports.deepPurple400 = '#7e57c2'; 64 | var deepPurple500 = exports.deepPurple500 = '#673ab7'; 65 | var deepPurple600 = exports.deepPurple600 = '#5e35b1'; 66 | var deepPurple700 = exports.deepPurple700 = '#512da8'; 67 | var deepPurple800 = exports.deepPurple800 = '#4527a0'; 68 | var deepPurple900 = exports.deepPurple900 = '#311b92'; 69 | var deepPurpleA100 = exports.deepPurpleA100 = '#b388ff'; 70 | var deepPurpleA200 = exports.deepPurpleA200 = '#7c4dff'; 71 | var deepPurpleA400 = exports.deepPurpleA400 = '#651fff'; 72 | var deepPurpleA700 = exports.deepPurpleA700 = '#6200ea'; 73 | 74 | var indigo50 = exports.indigo50 = '#e8eaf6'; 75 | var indigo100 = exports.indigo100 = '#c5cae9'; 76 | var indigo200 = exports.indigo200 = '#9fa8da'; 77 | var indigo300 = exports.indigo300 = '#7986cb'; 78 | var indigo400 = exports.indigo400 = '#5c6bc0'; 79 | var indigo500 = exports.indigo500 = '#3f51b5'; 80 | var indigo600 = exports.indigo600 = '#3949ab'; 81 | var indigo700 = exports.indigo700 = '#303f9f'; 82 | var indigo800 = exports.indigo800 = '#283593'; 83 | var indigo900 = exports.indigo900 = '#1a237e'; 84 | var indigoA100 = exports.indigoA100 = '#8c9eff'; 85 | var indigoA200 = exports.indigoA200 = '#536dfe'; 86 | var indigoA400 = exports.indigoA400 = '#3d5afe'; 87 | var indigoA700 = exports.indigoA700 = '#304ffe'; 88 | 89 | var blue50 = exports.blue50 = '#e3f2fd'; 90 | var blue100 = exports.blue100 = '#bbdefb'; 91 | var blue200 = exports.blue200 = '#90caf9'; 92 | var blue300 = exports.blue300 = '#64b5f6'; 93 | var blue400 = exports.blue400 = '#42a5f5'; 94 | var blue500 = exports.blue500 = '#2196f3'; 95 | var blue600 = exports.blue600 = '#1e88e5'; 96 | var blue700 = exports.blue700 = '#1976d2'; 97 | var blue800 = exports.blue800 = '#1565c0'; 98 | var blue900 = exports.blue900 = '#0d47a1'; 99 | var blueA100 = exports.blueA100 = '#82b1ff'; 100 | var blueA200 = exports.blueA200 = '#448aff'; 101 | var blueA400 = exports.blueA400 = '#2979ff'; 102 | var blueA700 = exports.blueA700 = '#2962ff'; 103 | 104 | var lightBlue50 = exports.lightBlue50 = '#e1f5fe'; 105 | var lightBlue100 = exports.lightBlue100 = '#b3e5fc'; 106 | var lightBlue200 = exports.lightBlue200 = '#81d4fa'; 107 | var lightBlue300 = exports.lightBlue300 = '#4fc3f7'; 108 | var lightBlue400 = exports.lightBlue400 = '#29b6f6'; 109 | var lightBlue500 = exports.lightBlue500 = '#03a9f4'; 110 | var lightBlue600 = exports.lightBlue600 = '#039be5'; 111 | var lightBlue700 = exports.lightBlue700 = '#0288d1'; 112 | var lightBlue800 = exports.lightBlue800 = '#0277bd'; 113 | var lightBlue900 = exports.lightBlue900 = '#01579b'; 114 | var lightBlueA100 = exports.lightBlueA100 = '#80d8ff'; 115 | var lightBlueA200 = exports.lightBlueA200 = '#40c4ff'; 116 | var lightBlueA400 = exports.lightBlueA400 = '#00b0ff'; 117 | var lightBlueA700 = exports.lightBlueA700 = '#0091ea'; 118 | 119 | var cyan50 = exports.cyan50 = '#e0f7fa'; 120 | var cyan100 = exports.cyan100 = '#b2ebf2'; 121 | var cyan200 = exports.cyan200 = '#80deea'; 122 | var cyan300 = exports.cyan300 = '#4dd0e1'; 123 | var cyan400 = exports.cyan400 = '#26c6da'; 124 | var cyan500 = exports.cyan500 = '#00bcd4'; 125 | var cyan600 = exports.cyan600 = '#00acc1'; 126 | var cyan700 = exports.cyan700 = '#0097a7'; 127 | var cyan800 = exports.cyan800 = '#00838f'; 128 | var cyan900 = exports.cyan900 = '#006064'; 129 | var cyanA100 = exports.cyanA100 = '#84ffff'; 130 | var cyanA200 = exports.cyanA200 = '#18ffff'; 131 | var cyanA400 = exports.cyanA400 = '#00e5ff'; 132 | var cyanA700 = exports.cyanA700 = '#00b8d4'; 133 | 134 | var teal50 = exports.teal50 = '#e0f2f1'; 135 | var teal100 = exports.teal100 = '#b2dfdb'; 136 | var teal200 = exports.teal200 = '#80cbc4'; 137 | var teal300 = exports.teal300 = '#4db6ac'; 138 | var teal400 = exports.teal400 = '#26a69a'; 139 | var teal500 = exports.teal500 = '#009688'; 140 | var teal600 = exports.teal600 = '#00897b'; 141 | var teal700 = exports.teal700 = '#00796b'; 142 | var teal800 = exports.teal800 = '#00695c'; 143 | var teal900 = exports.teal900 = '#004d40'; 144 | var tealA100 = exports.tealA100 = '#a7ffeb'; 145 | var tealA200 = exports.tealA200 = '#64ffda'; 146 | var tealA400 = exports.tealA400 = '#1de9b6'; 147 | var tealA700 = exports.tealA700 = '#00bfa5'; 148 | 149 | var green50 = exports.green50 = '#e8f5e9'; 150 | var green100 = exports.green100 = '#c8e6c9'; 151 | var green200 = exports.green200 = '#a5d6a7'; 152 | var green300 = exports.green300 = '#81c784'; 153 | var green400 = exports.green400 = '#66bb6a'; 154 | var green500 = exports.green500 = '#4caf50'; 155 | var green600 = exports.green600 = '#43a047'; 156 | var green700 = exports.green700 = '#388e3c'; 157 | var green800 = exports.green800 = '#2e7d32'; 158 | var green900 = exports.green900 = '#1b5e20'; 159 | var greenA100 = exports.greenA100 = '#b9f6ca'; 160 | var greenA200 = exports.greenA200 = '#69f0ae'; 161 | var greenA400 = exports.greenA400 = '#00e676'; 162 | var greenA700 = exports.greenA700 = '#00c853'; 163 | 164 | var lightGreen50 = exports.lightGreen50 = '#f1f8e9'; 165 | var lightGreen100 = exports.lightGreen100 = '#dcedc8'; 166 | var lightGreen200 = exports.lightGreen200 = '#c5e1a5'; 167 | var lightGreen300 = exports.lightGreen300 = '#aed581'; 168 | var lightGreen400 = exports.lightGreen400 = '#9ccc65'; 169 | var lightGreen500 = exports.lightGreen500 = '#8bc34a'; 170 | var lightGreen600 = exports.lightGreen600 = '#7cb342'; 171 | var lightGreen700 = exports.lightGreen700 = '#689f38'; 172 | var lightGreen800 = exports.lightGreen800 = '#558b2f'; 173 | var lightGreen900 = exports.lightGreen900 = '#33691e'; 174 | var lightGreenA100 = exports.lightGreenA100 = '#ccff90'; 175 | var lightGreenA200 = exports.lightGreenA200 = '#b2ff59'; 176 | var lightGreenA400 = exports.lightGreenA400 = '#76ff03'; 177 | var lightGreenA700 = exports.lightGreenA700 = '#64dd17'; 178 | 179 | var lime50 = exports.lime50 = '#f9fbe7'; 180 | var lime100 = exports.lime100 = '#f0f4c3'; 181 | var lime200 = exports.lime200 = '#e6ee9c'; 182 | var lime300 = exports.lime300 = '#dce775'; 183 | var lime400 = exports.lime400 = '#d4e157'; 184 | var lime500 = exports.lime500 = '#cddc39'; 185 | var lime600 = exports.lime600 = '#c0ca33'; 186 | var lime700 = exports.lime700 = '#afb42b'; 187 | var lime800 = exports.lime800 = '#9e9d24'; 188 | var lime900 = exports.lime900 = '#827717'; 189 | var limeA100 = exports.limeA100 = '#f4ff81'; 190 | var limeA200 = exports.limeA200 = '#eeff41'; 191 | var limeA400 = exports.limeA400 = '#c6ff00'; 192 | var limeA700 = exports.limeA700 = '#aeea00'; 193 | 194 | var yellow50 = exports.yellow50 = '#fffde7'; 195 | var yellow100 = exports.yellow100 = '#fff9c4'; 196 | var yellow200 = exports.yellow200 = '#fff59d'; 197 | var yellow300 = exports.yellow300 = '#fff176'; 198 | var yellow400 = exports.yellow400 = '#ffee58'; 199 | var yellow500 = exports.yellow500 = '#ffeb3b'; 200 | var yellow600 = exports.yellow600 = '#fdd835'; 201 | var yellow700 = exports.yellow700 = '#fbc02d'; 202 | var yellow800 = exports.yellow800 = '#f9a825'; 203 | var yellow900 = exports.yellow900 = '#f57f17'; 204 | var yellowA100 = exports.yellowA100 = '#ffff8d'; 205 | var yellowA200 = exports.yellowA200 = '#ffff00'; 206 | var yellowA400 = exports.yellowA400 = '#ffea00'; 207 | var yellowA700 = exports.yellowA700 = '#ffd600'; 208 | 209 | var amber50 = exports.amber50 = '#fff8e1'; 210 | var amber100 = exports.amber100 = '#ffecb3'; 211 | var amber200 = exports.amber200 = '#ffe082'; 212 | var amber300 = exports.amber300 = '#ffd54f'; 213 | var amber400 = exports.amber400 = '#ffca28'; 214 | var amber500 = exports.amber500 = '#ffc107'; 215 | var amber600 = exports.amber600 = '#ffb300'; 216 | var amber700 = exports.amber700 = '#ffa000'; 217 | var amber800 = exports.amber800 = '#ff8f00'; 218 | var amber900 = exports.amber900 = '#ff6f00'; 219 | var amberA100 = exports.amberA100 = '#ffe57f'; 220 | var amberA200 = exports.amberA200 = '#ffd740'; 221 | var amberA400 = exports.amberA400 = '#ffc400'; 222 | var amberA700 = exports.amberA700 = '#ffab00'; 223 | 224 | var orange50 = exports.orange50 = '#fff3e0'; 225 | var orange100 = exports.orange100 = '#ffe0b2'; 226 | var orange200 = exports.orange200 = '#ffcc80'; 227 | var orange300 = exports.orange300 = '#ffb74d'; 228 | var orange400 = exports.orange400 = '#ffa726'; 229 | var orange500 = exports.orange500 = '#ff9800'; 230 | var orange600 = exports.orange600 = '#fb8c00'; 231 | var orange700 = exports.orange700 = '#f57c00'; 232 | var orange800 = exports.orange800 = '#ef6c00'; 233 | var orange900 = exports.orange900 = '#e65100'; 234 | var orangeA100 = exports.orangeA100 = '#ffd180'; 235 | var orangeA200 = exports.orangeA200 = '#ffab40'; 236 | var orangeA400 = exports.orangeA400 = '#ff9100'; 237 | var orangeA700 = exports.orangeA700 = '#ff6d00'; 238 | 239 | var deepOrange50 = exports.deepOrange50 = '#fbe9e7'; 240 | var deepOrange100 = exports.deepOrange100 = '#ffccbc'; 241 | var deepOrange200 = exports.deepOrange200 = '#ffab91'; 242 | var deepOrange300 = exports.deepOrange300 = '#ff8a65'; 243 | var deepOrange400 = exports.deepOrange400 = '#ff7043'; 244 | var deepOrange500 = exports.deepOrange500 = '#ff5722'; 245 | var deepOrange600 = exports.deepOrange600 = '#f4511e'; 246 | var deepOrange700 = exports.deepOrange700 = '#e64a19'; 247 | var deepOrange800 = exports.deepOrange800 = '#d84315'; 248 | var deepOrange900 = exports.deepOrange900 = '#bf360c'; 249 | var deepOrangeA100 = exports.deepOrangeA100 = '#ff9e80'; 250 | var deepOrangeA200 = exports.deepOrangeA200 = '#ff6e40'; 251 | var deepOrangeA400 = exports.deepOrangeA400 = '#ff3d00'; 252 | var deepOrangeA700 = exports.deepOrangeA700 = '#dd2c00'; 253 | 254 | var brown50 = exports.brown50 = '#efebe9'; 255 | var brown100 = exports.brown100 = '#d7ccc8'; 256 | var brown200 = exports.brown200 = '#bcaaa4'; 257 | var brown300 = exports.brown300 = '#a1887f'; 258 | var brown400 = exports.brown400 = '#8d6e63'; 259 | var brown500 = exports.brown500 = '#795548'; 260 | var brown600 = exports.brown600 = '#6d4c41'; 261 | var brown700 = exports.brown700 = '#5d4037'; 262 | var brown800 = exports.brown800 = '#4e342e'; 263 | var brown900 = exports.brown900 = '#3e2723'; 264 | 265 | var blueGrey50 = exports.blueGrey50 = '#eceff1'; 266 | var blueGrey100 = exports.blueGrey100 = '#cfd8dc'; 267 | var blueGrey200 = exports.blueGrey200 = '#b0bec5'; 268 | var blueGrey300 = exports.blueGrey300 = '#90a4ae'; 269 | var blueGrey400 = exports.blueGrey400 = '#78909c'; 270 | var blueGrey500 = exports.blueGrey500 = '#607d8b'; 271 | var blueGrey600 = exports.blueGrey600 = '#546e7a'; 272 | var blueGrey700 = exports.blueGrey700 = '#455a64'; 273 | var blueGrey800 = exports.blueGrey800 = '#37474f'; 274 | var blueGrey900 = exports.blueGrey900 = '#263238'; 275 | 276 | var grey50 = exports.grey50 = '#fafafa'; 277 | var grey100 = exports.grey100 = '#f5f5f5'; 278 | var grey200 = exports.grey200 = '#eeeeee'; 279 | var grey300 = exports.grey300 = '#e0e0e0'; 280 | var grey400 = exports.grey400 = '#bdbdbd'; 281 | var grey500 = exports.grey500 = '#9e9e9e'; 282 | var grey600 = exports.grey600 = '#757575'; 283 | var grey700 = exports.grey700 = '#616161'; 284 | var grey800 = exports.grey800 = '#424242'; 285 | var grey900 = exports.grey900 = '#212121'; 286 | 287 | var black = exports.black = '#000000'; 288 | var white = exports.white = '#ffffff'; 289 | 290 | var transparent = exports.transparent = 'rgba(0, 0, 0, 0)'; 291 | var fullBlack = exports.fullBlack = 'rgba(0, 0, 0, 1)'; 292 | var darkBlack = exports.darkBlack = 'rgba(0, 0, 0, 0.87)'; 293 | var lightBlack = exports.lightBlack = 'rgba(0, 0, 0, 0.54)'; 294 | var minBlack = exports.minBlack = 'rgba(0, 0, 0, 0.26)'; 295 | var faintBlack = exports.faintBlack = 'rgba(0, 0, 0, 0.12)'; 296 | var fullWhite = exports.fullWhite = 'rgba(255, 255, 255, 1)'; 297 | var darkWhite = exports.darkWhite = 'rgba(255, 255, 255, 0.87)'; 298 | var lightWhite = exports.lightWhite = 'rgba(255, 255, 255, 0.54)'; --------------------------------------------------------------------------------