├── .gitignore
├── README.md
├── Untitled.txt
├── api
├── management
│ ├── article.js
│ ├── terms.js
│ ├── upload.js
│ └── user.js
└── user
│ └── article.js
├── app.js
├── bin
└── www
├── db
└── mongoose.js
├── models
├── key_maps.js
├── management
│ ├── article
│ │ ├── list.js
│ │ ├── posts.js
│ │ └── terms.js
│ ├── attachment
│ │ └── imgs.js
│ └── user
│ │ └── users.js
└── user
│ └── posts.js
├── package.json
├── proxy.js
├── router
└── router.js
├── test
└── testFormatPara2Camel.html
├── tools
└── tools.js
├── views
├── error.jade
├── index.jade
├── layout.jade
└── user.jade
└── web
├── README.md
├── assets
└── js
│ └── app.js
├── build
├── ZeroClipboard.swf
├── app.js
├── app.js.map
├── css
│ ├── font-icons
│ │ ├── fonts
│ │ │ ├── material-ui-icons.eot
│ │ │ ├── material-ui-icons.svg
│ │ │ ├── material-ui-icons.ttf
│ │ │ └── material-ui-icons.woff
│ │ └── style.css
│ ├── github.css
│ └── main.css
├── fonts
│ ├── demo.css
│ ├── demo_fontclass.html
│ ├── demo_symbol.html
│ ├── demo_unicode.html
│ ├── iconfont.css
│ ├── iconfont.eot
│ ├── iconfont.js
│ ├── iconfont.svg
│ ├── iconfont.ttf
│ └── iconfont.woff
├── images
│ ├── 3fuyu.png
│ ├── 3fuyu_bg.jpg
│ ├── 3fuyu_small.jpg
│ ├── angular.jpg
│ ├── banner_small.jpg
│ ├── banner_small_two.jpg
│ ├── electron.png
│ ├── favicon.ico
│ ├── gomoku.jpg
│ ├── mongodb.jpg
│ ├── nodejs.jpg
│ ├── react.png
│ ├── vue.jpg
│ └── weex.png
├── index.html
├── laboratory
│ └── gomoku
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ └── wood.jpg
└── versions.json
├── gulpfile.js
├── package.json
├── src
├── .DS_Store
├── .babelrc
├── app
│ ├── .DS_Store
│ ├── AppRoutes.js
│ ├── app.js
│ ├── css
│ │ ├── about.less
│ │ ├── articleCategory.less
│ │ ├── articleDetail.less
│ │ ├── articleList.less
│ │ ├── base.less
│ │ ├── github-gist.css
│ │ ├── home.less
│ │ ├── iconfont
│ │ │ ├── iconfont.css
│ │ │ ├── iconfont.eot
│ │ │ ├── iconfont.svg
│ │ │ ├── iconfont.ttf
│ │ │ └── iconfont.woff
│ │ ├── laboratory.less
│ │ ├── login.less
│ │ ├── main.less
│ │ ├── markdown.less
│ │ └── newArticle.less
│ ├── fonts
│ │ ├── demo.css
│ │ ├── demo_fontclass.html
│ │ ├── demo_symbol.html
│ │ ├── demo_unicode.html
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.js
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ ├── images
│ │ ├── 3fuyu_bg.jpg
│ │ ├── add_pic.png
│ │ ├── angular.jpg
│ │ ├── banner_small_two.jpg
│ │ ├── default_xz.png
│ │ ├── delete_btn.png
│ │ ├── electron.png
│ │ ├── gomoku.jpg
│ │ ├── gomoku.png
│ │ ├── line.png
│ │ ├── line_green.png
│ │ ├── logo_small.jpg
│ │ ├── mongodb.jpg
│ │ ├── nodejs.jpg
│ │ ├── react.png
│ │ ├── select_photo.jpg
│ │ ├── select_photo.png
│ │ ├── vue.jpg
│ │ └── weex.png
│ ├── js
│ │ ├── .DS_Store
│ │ ├── actions
│ │ │ └── actions.js
│ │ ├── components
│ │ │ ├── .DS_Store
│ │ │ ├── index
│ │ │ │ ├── About.js
│ │ │ │ ├── About_power.js
│ │ │ │ ├── ArticleDetail.js
│ │ │ │ ├── Home.js
│ │ │ │ └── Laboratory.js
│ │ │ ├── lib
│ │ │ │ ├── Loading.js
│ │ │ │ └── upload.js
│ │ │ └── management
│ │ │ │ ├── AppNavDrawer.js
│ │ │ │ ├── ArticleCategory.js
│ │ │ │ ├── ArticleList.js
│ │ │ │ ├── FullWidthSection.js
│ │ │ │ ├── Login.js
│ │ │ │ ├── MarkdownElement.js
│ │ │ │ ├── Master.js
│ │ │ │ ├── Media.js
│ │ │ │ └── NewArticle.js
│ │ ├── lib
│ │ │ ├── ZeroClipboard.min.js
│ │ │ ├── ZeroClipboard.swf
│ │ │ └── changyan.js
│ │ ├── reducers
│ │ │ ├── reducers.js
│ │ │ └── todos.js
│ │ ├── service
│ │ │ ├── CacheService.js
│ │ │ ├── DataService.js
│ │ │ ├── EnumService.js
│ │ │ ├── FYToolService.js
│ │ │ ├── RouterService.js
│ │ │ └── StorageService.js
│ │ ├── upload.html
│ │ └── upload.js
│ └── laboratory
│ │ └── gomoku
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ └── wood.jpg
└── www
│ ├── css
│ ├── font-icons
│ │ ├── fonts
│ │ │ ├── material-ui-icons.eot
│ │ │ ├── material-ui-icons.svg
│ │ │ ├── material-ui-icons.ttf
│ │ │ └── material-ui-icons.woff
│ │ └── style.css
│ ├── github.css
│ └── main.css
│ ├── fonts
│ ├── demo.css
│ ├── demo_fontclass.html
│ ├── demo_symbol.html
│ ├── demo_unicode.html
│ ├── iconfont.css
│ ├── iconfont.eot
│ ├── iconfont.js
│ ├── iconfont.svg
│ ├── iconfont.ttf
│ └── iconfont.woff
│ ├── images
│ ├── 3fuyu.png
│ ├── 3fuyu_bg.jpg
│ ├── 3fuyu_small.jpg
│ ├── angular.jpg
│ ├── banner_small.jpg
│ ├── banner_small_two.jpg
│ ├── electron.png
│ ├── favicon.ico
│ ├── gomoku.jpg
│ ├── mongodb.jpg
│ ├── nodejs.jpg
│ ├── react.png
│ ├── vue.jpg
│ └── weex.png
│ ├── index.html
│ ├── laboratory
│ └── gomoku
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ └── wood.jpg
│ ├── management.html
│ └── versions.json
├── test
└── testHightlight.html
├── testHS.html
├── webpack-production.config.js
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # IntelliJ project files
2 | .idea
3 | *.iml
4 | out
5 | gen
6 | node_modules
7 | express_test/myapp/node_modules
8 | .npm-debug.log
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # blog building...
2 |
3 | hi I'm 3fuyu
4 |
5 | want: nodejs + express + mongodb + react + redux + handlebarsjs + materail + lodash
6 |
7 | now: server is building , already have nodejs + express + mongo + react + lodash...
8 |
9 |
--------------------------------------------------------------------------------
/Untitled.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/Untitled.txt
--------------------------------------------------------------------------------
/api/management/article.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | let express = require('express');
4 | let postsModel = require('../../models/management/article/posts');
5 | let keyMapsModel = require('../../models/key_maps');
6 | let Tools = require('../../tools/tools');
7 | let MD = require('marked');
8 | let hljs = require('highlight.js');
9 |
10 | let baseRoute = '/admin/article';
11 |
12 | let postApis = [{
13 |
14 | // 发布文章
15 | type: 'post',
16 | url: baseRoute + '/postNew',
17 | success: function (req, res, next) {
18 | let max_id = 1;
19 | MD.setOptions({
20 | gfm: true,
21 | tables: true,
22 | breaks: false,
23 | pedantic: false,
24 | sanitize: true, // if false -> allow plain old HTML ;)
25 | smartLists: true,
26 | smartypants: false,
27 | highlight: function (code, lang) {
28 | if (lang && hljs.getLanguage(lang)) {
29 | return hljs.highlight(lang, code, true).value;
30 | } else {
31 | console.log(hljs.highlightAuto(code).value);
32 | return hljs.highlightAuto(code).value;
33 | }
34 | }
35 | });
36 |
37 | keyMapsModel.find({post_map_key: true}, function (err, docs) {
38 | if (err) {
39 | console.error(err);
40 | } else {
41 | if (docs.length === 0) {
42 | let postMapObj = JSON.stringify({max_id: 1});
43 |
44 | let keyMapsEntity = new keyMapsModel({
45 | post_map_key: true,
46 | post_map_value: postMapObj
47 | });
48 |
49 | keyMapsEntity.save(function (err, docs) {
50 | if (err) console.error(err);
51 | });
52 | } else {
53 | max_id = parseInt(JSON.parse(docs[0].post_map_value).max_id) + 1;
54 | }
55 |
56 | // 存数据库
57 | let postEntity = new postsModel({
58 | post_author: '3fuyu',
59 | post_content: req.body.content,
60 | post_md_content: MD(req.body.content),
61 | post_title: req.body.title,
62 | post_category_id: req.body.categoryId,
63 | post_category_name: req.body.categoryName,
64 | post_date: req.body.date || +new Date(),
65 | _id: max_id,
66 | view_count: 0
67 | });
68 |
69 | postEntity.save(function (err, tree) {
70 | if (err) {
71 | console.error('Somthing wrong: ' + err);
72 | } else {
73 |
74 | var conditions = {post_map_key: true};
75 | var update = {$set: {post_map_value: JSON.stringify({max_id: max_id})}};
76 | var options = {upsert: true};
77 | keyMapsModel.update(conditions, update, options, function (err, suc) {
78 | if (err) console.error(err);
79 |
80 | if (suc) console.log(suc);
81 | });
82 | }
83 | });
84 |
85 | res.send({
86 | code: 200,
87 | description: 'success'
88 | });
89 | }
90 | });
91 | }
92 | }, {
93 |
94 | // 查询文章列表
95 | type: 'get',
96 | url: baseRoute + '/queryList',
97 | success: function (req, res, next) {
98 | postsModel
99 | .find({})
100 | .sort({'post_date': 'desc'})
101 | .exec(function (err, data) {
102 | res.send({
103 | code: 200,
104 | description: 'success',
105 | data: Tools.para2camel(data)
106 | });
107 | });
108 | }
109 | }, {
110 |
111 | // 查询文章详情
112 | type: 'get',
113 | url: baseRoute + '/get',
114 | success: function (req, res, next) {
115 | postsModel
116 | .find({_id: req.query.id}, function (err, data) {
117 | res.send({
118 | code: 200,
119 | description: 'success',
120 | data: Tools.para2camel(data)
121 | });
122 | });
123 | }
124 | }, {
125 |
126 | // 更新文章详情
127 | type: 'post',
128 | url: baseRoute + '/update',
129 | success: function (req, res, next) {
130 | let query = {_id: req.body.id},
131 | update = {
132 | post_author: '3fuyu',
133 | post_content: req.body.content,
134 | post_md_content: MD(req.body.content),
135 | post_title: req.body.title,
136 | post_category_id: req.body.categoryId,
137 | post_category_name: req.body.categoryName,
138 | post_date: req.body.date || +new Date()
139 | },
140 | options = {multi: true};
141 |
142 | postsModel.update(query, update, options, function (err, data) {
143 | res.send({
144 | code: 200,
145 | description: 'success',
146 | data: Tools.para2camel(data)
147 | });
148 | });
149 | }
150 | }, {
151 |
152 | // 删除文章
153 | type: 'post',
154 | url: baseRoute + '/del',
155 | success: function (req, res, next) {
156 | postsModel
157 | .remove({
158 | _id: req.body.id
159 | })
160 | .exec(function (err, data) {
161 | res.send({
162 | code: 200,
163 | description: 'success'
164 | });
165 | });
166 | }
167 | }];
168 |
169 |
170 | module.exports = postApis;
171 |
--------------------------------------------------------------------------------
/api/management/terms.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2016/11/20.
3 | */
4 |
5 | "use strict";
6 |
7 | let express = require('express');
8 | let termsModel = require('../../models/management/article/terms');
9 | let keyMapsModel = require('../../models/key_maps');
10 | let Tools = require('../../tools/tools');
11 |
12 | let baseRoute = '/admin/terms';
13 |
14 | let termsApis = [{
15 | // 新增分类
16 | type: 'post',
17 | url: baseRoute + '/termsNew',
18 | success: function (req, res, next) {
19 | let max_id = 1;
20 |
21 | keyMapsModel.find({terms_map_key: true}, function (err, docs) {
22 | if (err) {
23 | console.error(err);
24 | } else {
25 | if (docs.length === 0) {
26 | let termsMapKey = JSON.stringify({max_id: 1});
27 |
28 | let keyMapsEntity = new keyMapsModel({
29 | terms_map_key: true,
30 | terms_map_value: termsMapKey
31 | });
32 |
33 | keyMapsEntity.save(function (err, docs) {
34 | if (err) console.error(err);
35 | });
36 | } else {
37 | max_id = parseInt(JSON.parse(docs[0].terms_map_value).max_id) + 1;
38 | }
39 |
40 | // 存数据库
41 | let termsEntity = new termsModel({
42 | _id: max_id,
43 | name: req.body.name,
44 | slug: req.body.slug || req.body.name,
45 | term_group: '未分组'
46 | });
47 |
48 | termsEntity.save(function (err, docs) {
49 | if (err) {
50 | console.error('Somthing wrong: ' + err);
51 | } else {
52 | let conditions = {terms_map_key: true};
53 | let update = {$set: {terms_map_value: JSON.stringify({max_id: max_id})}};
54 | let options = {upsert: true};
55 |
56 | keyMapsModel.update(conditions, update, options, function (err, suc) {
57 | if (err) console.error(err);
58 |
59 | if (suc) console.log(suc);
60 |
61 | res.send({
62 | code: 200,
63 | description: 'success'
64 | });
65 | });
66 | }
67 | });
68 | }
69 | });
70 | }
71 | }, {
72 | // 查询分类列表
73 | type: 'get',
74 | url: baseRoute + '/queryList',
75 | success: function (req, res, next) {
76 | termsModel
77 | .find({})
78 | .sort({'_id': 'desc'})
79 | .exec(function (err, data) {
80 | res.send({
81 | code: 200,
82 | description: 'success',
83 | data: Tools.para2camel(data)
84 | });
85 | });
86 | }
87 | }, {
88 | // 删除分类
89 | type: 'post',
90 | url: baseRoute + '/del',
91 | success: function (req, res, next) {
92 | var conditions = {'_id': req.body.id};
93 | termsModel.remove(conditions, function (error) {
94 | if (error) {
95 | console.error(error);
96 | } else {
97 | console.log('delete ok!');
98 | res.send({
99 | code: 200,
100 | description: 'success'
101 | });
102 | }
103 | });
104 | }
105 | }];
106 |
107 | module.exports = termsApis;
--------------------------------------------------------------------------------
/api/management/upload.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/2/14.
3 | */
4 |
5 | "use strict";
6 |
7 | let express = require('express');
8 | let formidable = require('formidable');
9 | let util = require('util');
10 | let keyMapsModel = require('../../models/key_maps');
11 | let imgsModel = require('../../models/management/attachment/imgs');
12 | let fs = require('fs');
13 | let Tools = require('../../tools/tools');
14 | let _ = require('lodash');
15 |
16 | let baseRoute = '/admin/upload'
17 |
18 | let uploadApis = [{
19 | // 新增附件
20 | type: 'post',
21 | url: baseRoute + '/image',
22 | success: function (req, res) {
23 | let form = new formidable.IncomingForm();
24 |
25 | form.keepExtensions = true;
26 | form.multiples = true;
27 | form.parse(req, function (err, fields, files) {
28 |
29 | keyMapsModel.find({imgs_map_key: true}, function (err, docs) {
30 | if (err) {
31 | console.error(err);
32 | } else {
33 | if (docs.length === 0) {
34 | let keyMapsEntity = new keyMapsModel({
35 | imgs_map_key: true,
36 | imgs_max_id: 1
37 | });
38 |
39 | keyMapsEntity.save(function (err, docs) {
40 | if (err) console.error(err);
41 |
42 | if (_.isArray(files.img)) {
43 | files.img.forEach(function (value, key) {
44 | setImg(res, value);
45 | });
46 | } else {
47 | setImg(res, files.img);
48 | }
49 |
50 | res.send({
51 | code: 200,
52 | description: 'success'
53 | });
54 | });
55 | } else {
56 | if (_.isArray(files.img)) {
57 | files.img.forEach(function (value, key) {
58 | setImg(res, value);
59 | });
60 | } else {
61 | setImg(res, files.img);
62 | }
63 |
64 | res.send({
65 | code: 200,
66 | description: 'success'
67 | });
68 | }
69 | }
70 | });
71 | });
72 | }
73 | }, {
74 | // 查询附件列表
75 | type: 'get',
76 | url: baseRoute + '/queryList',
77 | success: function (req, res, next) {
78 | imgsModel
79 | .find({})
80 | .sort({'_id': 'desc'})
81 | .exec(function (err, data) {
82 | res.send({
83 | code: 200,
84 | description: 'success',
85 | data: Tools.para2camel(data)
86 | });
87 | });
88 | }
89 | }, {
90 | // 删除分类
91 | type: 'post',
92 | url: baseRoute + '/del',
93 | success: function (req, res, next) {
94 | var conditions = {'_id': req.body.id};
95 | imgsModel.remove(conditions, function (error) {
96 | if (error) {
97 | console.error(error);
98 | } else {
99 | console.log('delete ok!');
100 | res.send({
101 | code: 200,
102 | description: 'success'
103 | });
104 | }
105 | });
106 | }
107 | }];
108 |
109 | function setImg(res, img) {
110 | keyMapsModel.findOneAndUpdate({imgs_map_key: true}, {$inc: {'imgs_max_id': 1}}, function (err, suc) {
111 | let name = +new Date() + '.' + img.type.split('/')[1],
112 | url = '/static/imgs/' + name;
113 |
114 | if (err) return console.log(err);
115 |
116 | // 存数据库
117 | let imgsEntity = new imgsModel({
118 | _id: suc.imgs_max_id,
119 | name: img.name,
120 | url: url
121 | });
122 |
123 | imgsEntity.save(function (err, docs) {
124 | fs.renameSync(img.path, './static/imgs/' + name);
125 | });
126 | });
127 | }
128 |
129 |
130 | module.exports = uploadApis;
--------------------------------------------------------------------------------
/api/management/user.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var baseRoute = '/admin/user';
4 | var usersModel = require('../../models/management/user/users');
5 | var Tools = require('../../tools/tools');
6 |
7 | var userApis = [{
8 |
9 | type: 'get',
10 | url: baseRoute + '/getUserInfo',
11 | success: function (req, res, next) {
12 | usersModel
13 | .find({ID: req.session.user_id})
14 | .exec(function (err, data) {
15 | var _data = Tools.para2camel(data);
16 |
17 | res.send({
18 | code: 200,
19 | description: 'success',
20 | data: _data
21 | });
22 | });
23 |
24 | }
25 | }, {
26 | type: 'post',
27 | url: baseRoute + '/login',
28 | success: function (req, res, next) {
29 | usersModel
30 | .find({ID: '1'})
31 | .exec(function (err, data) {
32 | var _data = Tools.para2camel(data);
33 |
34 | if (req.body.name === _data[0].userLogin && req.body.password === _data[0].userPass) {
35 |
36 | req.session.user_id = '1';
37 | req.session.user = '3fuyu';
38 |
39 | res.send({
40 | code: 200,
41 | description: 'success'
42 | });
43 | } else {
44 | res.send({
45 | code: 500,
46 | description: 'name or password wrong'
47 | });
48 | }
49 | });
50 | }
51 | }, {
52 | type: 'post',
53 | url: baseRoute + '/logout',
54 | success: function (req, res, next) {
55 | req.session.destroy();
56 |
57 | res.send({
58 | code: 200,
59 | description: 'success'
60 | });
61 |
62 | }
63 | }];
64 |
65 |
66 | module.exports = userApis;
67 |
--------------------------------------------------------------------------------
/api/user/article.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var express = require('express');
4 | var postsModel = require('../../models/management/article/posts');
5 | var Tools = require('../../tools/tools');
6 | let request = require('superagent');
7 |
8 | var baseRoute = '/article';
9 |
10 | var postApis = [{
11 |
12 | // 获取文章详情
13 | type: 'get',
14 | url: baseRoute + '/getDetail',
15 | success: function (req, res, next) {
16 | postsModel
17 | .find({'_id': req.query.id})
18 | .sort({'post_date': 'desc'})
19 | .exec(function (err, data) {
20 |
21 | if (err) {
22 | res.send(err);
23 | } else {
24 | let query = {_id: req.query.id},
25 | update = '',
26 | options = {multi: true};
27 |
28 | if (data[0].view_count) {
29 | // 原子操作,+1
30 | update = {$inc: {view_count: 1}};
31 | } else {
32 | // 没有则插入该字段
33 | update = {$set: {view_count: 1}}
34 | }
35 |
36 | // 获取畅言评论数
37 | request
38 | .get('http://changyan.sohu.com/api/2/topic/count?client_id=cyt1S1w3M&topic_id=&topic_source_id=' + req.query.id + '&topic_url=')
39 | .type('form')
40 | .end(function (err, suc) {
41 | if (err) {
42 | console.log(err);
43 | } else {
44 | if (update.$set) {
45 | update.$set.comment_count = suc.body.result[req.query.id].comments;
46 | } else {
47 | update.$set = {
48 | comment_count: suc.body.result[req.query.id].comments
49 | }
50 | }
51 |
52 | postsModel.update(query, update, options, function (err, data) {
53 | });
54 | }
55 | });
56 |
57 | res.send({
58 | code: 200,
59 | description: 'success',
60 | data: Tools.para2camel(data)[0]
61 | });
62 | }
63 |
64 | });
65 | }
66 | }, {
67 |
68 | // 获取文章详情
69 | type: 'get',
70 | url: baseRoute + '/queryList',
71 | success: function (req, res, next) {
72 | let pageIndex = parseInt(req.query.pageIndex),
73 | pageSize = parseInt(req.query.pageSize),
74 | position = parseInt(pageIndex - 1),
75 | search = {},
76 | type = req.query.type || '',
77 | category = [],
78 | _postModel,
79 | __postModel;
80 |
81 | if (type) {
82 | switch (type) {
83 | case '1':
84 | category.push('js', 'javascript', 'angularJs', 'web前端', 'react');
85 | break;
86 | case '2':
87 | category.push('ubuntu', 'linux');
88 | break;
89 | default:
90 | break;
91 | }
92 | search.post_category_name = type;
93 | }
94 |
95 | if (category.length > 0) {
96 | _postModel = postsModel.where('post_category_name').in(category);
97 | // copy 一份统计数据用
98 | __postModel = postsModel.where('post_category_name').in(category);
99 | } else {
100 | _postModel = postsModel.find({});
101 | // copy 一份统计数据用
102 | __postModel = postsModel.find({});
103 | }
104 |
105 | _postModel
106 | .skip(position)
107 | .limit(pageSize)
108 | .sort({'post_date': 'desc'})
109 | .exec(function (err, data) {
110 | if (err) {
111 | res.send(err);
112 | } else {
113 | __postModel.count(function (errcount, count) {
114 | if (errcount) {
115 | res.send(errcount);
116 | } else {
117 | let total = count,
118 | nextPage = pageIndex + pageSize,
119 | isFinish = total <= nextPage ? true : false;
120 |
121 | res.send({
122 | code: 200,
123 | description: 'success',
124 | data: {
125 | data: Tools.para2camel(data),
126 | pageObj: {
127 | nextPage: nextPage,
128 | total: total,
129 | isFinish: isFinish
130 | }
131 | }
132 | });
133 | }
134 | });
135 | }
136 | });
137 | }
138 | }];
139 |
140 |
141 | module.exports = postApis;
142 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var express = require('express');
4 | var path = require('path');
5 | var favicon = require('serve-favicon');
6 | var logger = require('morgan');
7 | var cookieParser = require('cookie-parser');
8 | var bodyParser = require('body-parser');
9 | var proxy = require('./proxy');
10 | var session = require ('express-session');
11 | var router = require('./router/router');
12 | var compression = require('compression');
13 | var baseUrl = '/api';
14 | var app = express();
15 |
16 | // 设置session
17 | app.use(session({
18 | secret: '123456',
19 | name: '3fuyu',
20 | cookie: {
21 | maxAge: 3 * 60 * 60 * 1000 + 8 * 3600 * 1000, // 0.5h
22 | path: '/'
23 | },
24 | resave: false,
25 | saveUninitialized: true
26 | }));
27 |
28 | //设置跨域访问
29 | app.all('*', function(req, res, next) {
30 | res.header("Access-Control-Allow-Origin", "*");
31 | res.header("Access-Control-Allow-Headers", "X-Requested-With");
32 | res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
33 | res.header("X-Powered-By",' 3.2.1');
34 | next();
35 | });
36 |
37 | // view engine setup
38 | app.set('views', path.join(__dirname, 'views'));
39 | app.set('view engine', 'jade');
40 |
41 | // uncomment after placing your favicon in /web
42 | //app.use(favicon(path.join(__dirname, 'web', 'favicon.ico')));
43 | // 压缩
44 | app.use(compression());
45 | app.use(logger('dev'));
46 | app.use(bodyParser.json());
47 | app.use(bodyParser.urlencoded({extended: false}));
48 | app.use(cookieParser());
49 |
50 | app.use(baseUrl, router);
51 | app.use(express.static(path.join(__dirname, 'web/build')));
52 | app.use('/static', express.static(path.join(__dirname, 'static')));
53 |
54 | // catch 404 and forward to error handler
55 | app.use(function (req, res, next) {
56 | var err = new Error('Not Found');
57 | err.status = 404;
58 | next(err);
59 | });
60 |
61 | // error handlers
62 |
63 | // development error handler
64 | // will print stacktrace
65 | if (app.get('env') === 'development') {
66 | app.use(function (err, req, res, next) {
67 | res.status(err.status || 500);
68 | res.render('error', {
69 | message: err.message,
70 | error: err
71 | });
72 | });
73 | }
74 |
75 | // production error handler
76 | // no stacktraces leaked to user
77 | app.use(function (err, req, res, next) {
78 | res.status(err.status || 500);
79 | res.render('error', {
80 | message: err.message,
81 | error: {}
82 | });
83 | });
84 |
85 |
86 | module.exports = app;
87 |
--------------------------------------------------------------------------------
/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('blog:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '8080');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/db/mongoose.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/8/11.
3 | */
4 |
5 | var mongoose = require('mongoose');
6 | mongoose.connect('mongodb://localhost/blog');
7 |
8 | var db = mongoose.connection;
9 | db.on('error', console.error.bind(console, 'connection error:'));
10 | db.once('open', function (callback) {
11 | // yay!
12 | console.log.bind(console, 'connection success!');
13 | });
14 |
15 | module.exports = mongoose;
--------------------------------------------------------------------------------
/models/key_maps.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/8/11.
3 | */
4 |
5 | var mongoose = require('../db/mongoose');
6 |
7 | var mapsSchema = mongoose.Schema({
8 | 'post_map_key' : {
9 | type: 'Boolean'
10 | },
11 | "post_map_value" : {
12 | type: 'String'
13 | },
14 | "post_max_id": {
15 | type: 'Number'
16 | },
17 | 'terms_map_key': {
18 | type: 'Boolean'
19 | },
20 | 'terms_map_value': {
21 | type: 'String'
22 | },
23 | "terms_max_id": {
24 | type: 'Number'
25 | },
26 | 'imgs_map_key': {
27 | type: 'Boolean'
28 | },
29 | 'imgs_map_value': {
30 | type: 'String'
31 | },
32 | "imgs_max_id": {
33 | type: 'Number'
34 | }
35 | });
36 |
37 | var mapsModel = mongoose.model('key_maps', mapsSchema);
38 |
39 | module.exports = mapsModel;
--------------------------------------------------------------------------------
/models/management/article/list.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2016/10/13.
3 | */
4 |
5 | "use strict";
6 |
7 | let mongoose = require('../../../db/mongoose');
8 | let Schema = mongoose.Schema;
9 |
10 | let listSchema = new Schema({
11 | "_id": {
12 | type: 'Number',
13 | required: [true, '请输入id']
14 | },
15 | "post_author": {
16 | type: 'String',
17 | required: [true, '请输入作者名称']
18 | },
19 | "post_date": {
20 | type: 'String'
21 | },
22 | "post_content": {
23 | type: 'String',
24 | required: [true, '请输入内容']
25 | },
26 | "post_title": {
27 | type: 'String',
28 | required: [true, '请输入标题']
29 | },
30 | "post_excerpt": {
31 | type: 'String',
32 | },
33 | "post_status": {
34 | type: 'String',
35 | },
36 | "comment_status": {
37 | type: 'String',
38 | },
39 | "post_password": {
40 | type: 'String',
41 | },
42 | "post_name": {
43 | type: 'String',
44 | },
45 | "post_modified": {
46 | type: 'String',
47 | },
48 | "post_parent": {
49 | type: 'String',
50 | },
51 | "menu_order": {
52 | type: 'String',
53 | },
54 | "post_type": {
55 | type: 'String',
56 | },
57 | "comment_count": {
58 | type: 'String',
59 | }
60 | });
61 |
--------------------------------------------------------------------------------
/models/management/article/posts.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/8/11.
3 | */
4 |
5 | var mongoose = require('../../../db/mongoose');
6 | var Schema = mongoose.Schema;
7 | var postsSchema = new Schema({
8 | "_id": {
9 | type: 'Number',
10 | required: [true, '请输入id']
11 | },
12 | "post_author": {
13 | type: 'String',
14 | required: [true, '请输入作者名称']
15 | },
16 | "post_date": {
17 | type: 'Number'
18 | },
19 | "post_category_id": {
20 | type: 'String',
21 | required: [true, '请输入分类id']
22 | },
23 | "post_category_name": {
24 | type: 'String',
25 | required: [true, '请输入分类名称']
26 | },
27 | "post_content": {
28 | type: 'String',
29 | required: [true, '请输入内容']
30 | },
31 | "post_md_content": {
32 | type: 'String',
33 | required: [true, '请输入内容']
34 | },
35 | "post_title": {
36 | type: 'String',
37 | required: [true, '请输入标题']
38 | },
39 | "post_excerpt": {
40 | type: 'String',
41 | },
42 | "post_status": {
43 | type: 'String',
44 | },
45 | "comment_status": {
46 | type: 'String',
47 | },
48 | "post_password": {
49 | type: 'String',
50 | },
51 | "post_name": {
52 | type: 'String',
53 | },
54 | "post_modified": {
55 | type: 'String',
56 | },
57 | "post_parent": {
58 | type: 'String',
59 | },
60 | "menu_order": {
61 | type: 'String',
62 | },
63 | "post_type": {
64 | type: 'String',
65 | },
66 | "view_count": {
67 | type: 'Number',
68 | },
69 | "comment_count": {
70 | type: 'Number',
71 | }
72 | }, { _id: false });
73 |
74 | var postsModel = mongoose.model('posts', postsSchema);
75 |
76 | module.exports = postsModel;
--------------------------------------------------------------------------------
/models/management/article/terms.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2016/11/20.
3 | */
4 |
5 | let mongoose = require('../../../db/mongoose');
6 | let Schema = mongoose.Schema;
7 | let termsSchema = new Schema({
8 | "_id": {
9 | type: 'Number',
10 | required: [true, '请输入id']
11 | },
12 | "name": { // 分类名
13 | type: 'String',
14 | required: [true, '请输入分类名称']
15 | },
16 | "slug": { // 缩略名
17 | type: 'String'
18 | },
19 | "term_group": { // 相似的 terms 集合在一起
20 | type: 'String'
21 | }
22 | }, { _id: false });
23 |
24 | let termsModel = mongoose.model('terms', termsSchema);
25 |
26 | module.exports = termsModel;
27 |
28 |
--------------------------------------------------------------------------------
/models/management/attachment/imgs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/4/24.
3 | */
4 |
5 | "use strict";
6 |
7 | let mongoose = require('../../../db/mongoose');
8 | let Schema = mongoose.Schema;
9 |
10 | let imgsSchema = new Schema({
11 | "_id": {
12 | type: 'Number',
13 | required: [true, '请输入id']
14 | },
15 | "url": {
16 | type: 'String',
17 | },
18 | "name": {
19 | type: 'String'
20 | }
21 | }, { _id: false });
22 |
23 | let imgsModel = mongoose.model('imgs', imgsSchema);
24 | module.exports = imgsModel;
--------------------------------------------------------------------------------
/models/management/user/users.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/8/11.
3 | */
4 |
5 | var mongoose = require('../../../db/mongoose');
6 |
7 | var usersSchema = mongoose.Schema({
8 | "ID" : {
9 | type: "String"
10 | },
11 | "user_login" : {
12 | type: "String"
13 | },
14 | "user_pass" : {
15 | type: "String"
16 | },
17 | "user_nicename" : {
18 | type: "String"
19 | },
20 | "user_email" : {
21 | type: "String"
22 | },
23 | "user_url" : {
24 | type: "String"
25 | },
26 | "user_registered" : {
27 | type: "String"
28 | },
29 | "user_status" : {
30 | type: "String"
31 | },
32 | "display_name" : {
33 | type: "String"
34 | }
35 | });
36 |
37 | var usersModel = mongoose.model('users', usersSchema);
38 |
39 | module.exports = usersModel;
--------------------------------------------------------------------------------
/models/user/posts.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/8/11.
3 | */
4 |
5 | var mongoose = require('../../db/mongoose');
6 | var Schema = mongoose.Schema;
7 | var postsSchema = new Schema({
8 | "_id": {
9 | type: 'Number',
10 | required: [true, '请输入id']
11 | },
12 | "post_author": {
13 | type: 'String',
14 | required: [true, '请输入作者名称']
15 | },
16 | "post_date": {
17 | type: 'Number'
18 | },
19 | "post_content": {
20 | type: 'String',
21 | required: [true, '请输入内容']
22 | },
23 | "post_title": {
24 | type: 'String',
25 | required: [true, '请输入标题']
26 | },
27 | "post_excerpt": {
28 | type: 'String',
29 | },
30 | "post_status": {
31 | type: 'String',
32 | },
33 | "comment_status": {
34 | type: 'String',
35 | },
36 | "post_password": {
37 | type: 'String',
38 | },
39 | "post_name": {
40 | type: 'String',
41 | },
42 | "post_modified": {
43 | type: 'String',
44 | },
45 | "post_parent": {
46 | type: 'String',
47 | },
48 | "menu_order": {
49 | type: 'String',
50 | },
51 | "post_type": {
52 | type: 'String',
53 | },
54 | "view_count": {
55 | type: 'Number',
56 | },
57 | "comment_count": {
58 | type: 'Number',
59 | }
60 | }, { _id: false });
61 |
62 | var postsModel = mongoose.model('posts', postsSchema);
63 |
64 | module.exports = postsModel;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "blog",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "peerDependencies": {
9 | "react": "15.0.0",
10 | "react-dom": "15.0.0",
11 | "react-tap-event-plugin": "1.0.0"
12 | },
13 | "dependencies": {
14 | "body-parser": "1.15.1",
15 | "cookie-parser": "1.4.3",
16 | "debug": "2.2.0",
17 | "express": "4.13.4",
18 | "express-session": "1.14.2",
19 | "formidable": "1.1.1",
20 | "jade": "1.11.0",
21 | "lodash": "4.14.2",
22 | "marked": "0.3.6",
23 | "mongoose": "4.5.8",
24 | "morgan": "1.7.0",
25 | "serve-favicon": "2.3.0"
26 | },
27 | "devDependencies": {
28 | "babel": "6.5.2",
29 | "babel-core": "6.6.4",
30 | "babel-loader": "6.2.4",
31 | "babel-polyfill": "6.7.2",
32 | "babel-preset-es2015": "6.6.0",
33 | "babel-preset-react": "6.5.0",
34 | "css-loader": "0.23.1",
35 | "fastclick": "1.0.6",
36 | "highlight.js": "9.7.0",
37 | "history": "2.0.1",
38 | "html-webpack-plugin": "2.29.0",
39 | "http-proxy": "1.15.1",
40 | "less": "2.7.1",
41 | "less-loader": "2.2.3",
42 | "material-ui": "0.15.4",
43 | "moment": "2.15.1",
44 | "path": "0.12.7",
45 | "react": "15.3.2",
46 | "react-dom": "15.3.2",
47 | "react-event-listener": "0.3.0",
48 | "react-hot-loader": "3.0.0-beta.3",
49 | "react-redux": "4.4.5",
50 | "react-router": "2.8.0",
51 | "react-tap-event-plugin": "1.0.0",
52 | "reactify": "1.1.0",
53 | "redux": "3.6.0",
54 | "simple-assign": "0.1.0",
55 | "store": "1.3.20",
56 | "style-loader": "0.13.0",
57 | "superagent": "1.8.0",
58 | "webpack": "1.12.14",
59 | "webpack-dev-server": "1.16.1"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/proxy.js:
--------------------------------------------------------------------------------
1 | var proxy = require('http-proxy').createProxyServer({});
2 |
3 | proxy.on(function (err, req, res) {
4 | res.writeHead(500, {
5 | 'Content-Type': 'text/plain'
6 | });
7 | });
8 |
9 | var server = require('http').createServer(function (req, res) {
10 | var host = req.headers.host;
11 | switch (host) {
12 | case 'www.3fuyu.com':
13 | proxy.web(req, res, {target: 'http://3fuyu.com:8080'});
14 | break;
15 | case '3fuyu.com':
16 | proxy.web(req, res, {target: 'http://3fuyu.com:8080'});
17 | break;
18 | case '120.25.92.21':
19 | proxy.web(req, res, {target: '120.25.92.21:8080'});
20 | break;
21 | default:
22 | res.writeHead(200, {
23 | 'Content-Type': 'text/plain'
24 | });
25 |
26 | res.end('Welcome to my server!');
27 | }
28 | });
29 | console.log("listening on port 80")
30 |
31 | // 监听服务器上 80 端口
32 | server.listen(80);
--------------------------------------------------------------------------------
/router/router.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/8/12.
3 | */
4 | "use strict";
5 |
6 | var express = require('express');
7 | var router = express.Router();
8 | var _ = require('lodash');
9 |
10 | var adminArticle = require('../api/management/article'),
11 | user = require('../api/management/user'),
12 | article = require('../api/user/article'),
13 | terms = require('../api/management/terms'),
14 | upload = require('../api/management/upload');
15 |
16 | // 合并api
17 | var apis = _.concat(adminArticle, article, user, terms, upload);
18 |
19 | apis.forEach(function (value, key) {
20 | if (value.type === 'get') {
21 | router.get(value.url, authorize, function (req, res, next) {
22 | req.session.lastPage = value.url;
23 |
24 | value.success(req, res);
25 | });
26 | } else if (value.type === 'post') {
27 | router.post(value.url, authorize, function (req, res, next) {
28 | req.session.lastPage = value.url;
29 |
30 | value.success(req, res);
31 | });
32 | }
33 | });
34 |
35 | function authorize(req, res, next) {
36 |
37 | // debug 去掉登录态,方便开发
38 | next();
39 | return;
40 |
41 | if (req.route.path !== '/admin/user/login' && req.route.path.indexOf('/admin/') > -1) {
42 | if (!req.session.user_id) {
43 | res.send({
44 | code: 401,
45 | description: '用户未登录'
46 | });
47 | } else {
48 | next();
49 | }
50 | } else {
51 | next();
52 | }
53 | }
54 |
55 | module.exports = router;
--------------------------------------------------------------------------------
/test/testFormatPara2Camel.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 |
11 |
104 |
--------------------------------------------------------------------------------
/tools/tools.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/8/12.
3 | */
4 | "use strict";
5 |
6 | var _ = require('lodash');
7 | var Tools = {};
8 | var formatPara2CamelArray = [];
9 |
10 | function isArray(data) {
11 | if (data && (data instanceof Array) && (data.constructor === Array)) {
12 | return true;
13 | }
14 | }
15 |
16 | function isObject(data) {
17 | if (data && (data instanceof Object) && (data.constructor === Object)) {
18 | return true;
19 | } else {
20 | return false;
21 | }
22 | }
23 |
24 | function checkUnderline(key) {
25 | for (var i = 0; i < key.split('_').length; i++) {
26 | if (key.split('_')[i] !== '') {
27 | return key.split('_')[i];
28 | }
29 | }
30 | }
31 |
32 | function formatPara2Camel(data) {
33 | // 过滤mogodb返回对象多余类型
34 | data = JSON.stringify(data);
35 | data = JSON.parse(data);
36 | if (isArray(data) || isObject(data)) {
37 | _.each(data, function (value, key) {
38 | if (isArray(value) || isObject(value)) {
39 | formatPara2Camel(value);
40 | } else {
41 | if (key.indexOf('_') > -1) {
42 | if (key.split('_')[0] === '') {
43 | var _key = checkUnderline(key);
44 | data[_key] = data[key];
45 | delete data[key];
46 | } else {
47 | var _key = key.replace(/_./g, function (a) {return a.split('_')[1].toUpperCase();});
48 | data[_key] = data[key];
49 | delete data[key];
50 | }
51 | }
52 | }
53 | });
54 | // 收集数据
55 | formatPara2CamelArray.push(data);
56 | } else {
57 | return data;
58 | }
59 | }
60 |
61 | Tools.para2camel = function (para) {
62 | var data = [];
63 |
64 | formatPara2Camel(para);
65 | formatPara2CamelArray.pop();
66 |
67 | data = _.cloneDeep(formatPara2CamelArray);
68 | formatPara2CamelArray = [];
69 |
70 | return data;
71 | };
72 |
73 | module.exports = Tools;
--------------------------------------------------------------------------------
/views/error.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= message
5 | h2= error.status
6 | pre #{error.stack}
7 |
--------------------------------------------------------------------------------
/views/index.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= title
5 | p Welcome to #{title}
6 |
--------------------------------------------------------------------------------
/views/layout.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title= title
5 | link(rel='stylesheet', href='/stylesheets/style.css')
6 | body
7 | block content
8 |
--------------------------------------------------------------------------------
/views/user.jade:
--------------------------------------------------------------------------------
1 | //
2 | Created by 3fuyu on 16/8/5.
3 |
4 |
5 | extends layout
6 |
7 | block content
8 | h1= title
9 | p Welcome to #{title}
--------------------------------------------------------------------------------
/web/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 目录结构
4 | ```
5 | +---assets //发布文件夹
6 | | +---css
7 | | +---images
8 | | \---js
9 | +---dist //发布压缩包
10 | | \---dist.zip
11 | \---src //源码
12 | +---css
13 | | \---iconfont
14 | +---images
15 | \---js
16 | +---components
17 | \---service
18 | ```
19 |
20 | ## service介绍
21 | ```
22 | service
23 | CacheService.js //缓存服务
24 | DataService.js //接口服务
25 | EnumService.js //枚举服务
26 | RouterService.js //路由服务
27 | StorageService.js //storage服务
28 | FuyuToolService.js //工具类服务
29 | ```
30 |
--------------------------------------------------------------------------------
/web/build/ZeroClipboard.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/ZeroClipboard.swf
--------------------------------------------------------------------------------
/web/build/css/font-icons/fonts/material-ui-icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/css/font-icons/fonts/material-ui-icons.eot
--------------------------------------------------------------------------------
/web/build/css/font-icons/fonts/material-ui-icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/web/build/css/font-icons/fonts/material-ui-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/css/font-icons/fonts/material-ui-icons.ttf
--------------------------------------------------------------------------------
/web/build/css/font-icons/fonts/material-ui-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/css/font-icons/fonts/material-ui-icons.woff
--------------------------------------------------------------------------------
/web/build/css/font-icons/style.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'material-ui-icons';
3 | src: url('fonts/material-ui-icons.eot');
4 | }
5 | @font-face {
6 | font-family: 'material-ui-icons';
7 | src: url(data:application/x-font-ttf;charset=utf-8;base64,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) format('truetype'),
8 | url(data:application/font-woff;charset=utf-8;base64,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) format('woff');
9 | font-weight: normal;
10 | font-style: normal;
11 | }
12 |
13 | [class^="muidocs-icon-"], [class*=" muidocs-icon-"] {
14 | font-family: 'material-ui-icons';
15 | speak: none;
16 | font-style: normal;
17 | font-weight: normal;
18 | font-variant: normal;
19 | text-transform: none;
20 | line-height: 1;
21 |
22 | /* Better Font Rendering =========== */
23 | -webkit-font-smoothing: antialiased;
24 | -moz-osx-font-smoothing: grayscale;
25 | }
26 |
27 | .muidocs-icon-communication-phone:before {
28 | content: "\e601";
29 | }
30 |
31 | .muidocs-icon-communication-voicemail:before {
32 | content: "\e602";
33 | }
34 |
35 | .muidocs-icon-navigation-expand-more:before {
36 | content: "\e603";
37 | }
38 |
39 | .muidocs-icon-action-grade:before {
40 | content: "\e604";
41 | }
42 |
43 | .muidocs-icon-action-home:before {
44 | content: "\e605";
45 | }
46 |
47 | .muidocs-icon-action-stars:before {
48 | content: "\e606";
49 | }
50 |
51 | .muidocs-icon-action-thumb-up:before {
52 | content: "\e607";
53 | }
54 |
55 | .muidocs-icon-custom-sort:before {
56 | content: "\e600";
57 | }
58 |
59 | .muidocs-icon-custom-github:before {
60 | content: "\e625";
61 | }
62 |
63 | .muidocs-icon-custom-arrow-drop-right:before {
64 | content: "\e60b";
65 | }
66 |
67 | .muidocs-icon-custom-pie:before {
68 | content: "\e610";
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/web/build/css/github.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | github.com style (c) Vasily Polovnyov
4 |
5 | */
6 |
7 | .hljs {
8 | display: block;
9 | overflow-x: auto;
10 | padding: 0.5em;
11 | color: #333;
12 | background: #f8f8f8;
13 | -webkit-text-size-adjust: none;
14 | }
15 |
16 | .hljs-comment,
17 | .hljs-template_comment,
18 | .diff .hljs-header,
19 | .hljs-javadoc {
20 | color: #998;
21 | font-style: italic;
22 | }
23 |
24 | .hljs-keyword,
25 | .css .rule .hljs-keyword,
26 | .hljs-winutils,
27 | .nginx .hljs-title,
28 | .hljs-subst,
29 | .hljs-request,
30 | .hljs-status {
31 | color: #333;
32 | font-weight: bold;
33 | }
34 |
35 | .hljs-number,
36 | .hljs-hexcolor,
37 | .ruby .hljs-constant {
38 | color: #008080;
39 | }
40 |
41 | .hljs-string,
42 | .hljs-tag .hljs-value,
43 | .hljs-phpdoc,
44 | .hljs-dartdoc,
45 | .tex .hljs-formula {
46 | color: #d14;
47 | }
48 |
49 | .hljs-title,
50 | .hljs-id,
51 | .scss .hljs-preprocessor {
52 | color: #900;
53 | font-weight: bold;
54 | }
55 |
56 | .hljs-list .hljs-keyword,
57 | .hljs-subst {
58 | font-weight: normal;
59 | }
60 |
61 | .hljs-class .hljs-title,
62 | .hljs-type,
63 | .vhdl .hljs-literal,
64 | .tex .hljs-command {
65 | color: #458;
66 | font-weight: bold;
67 | }
68 |
69 | .hljs-tag,
70 | .hljs-tag .hljs-title,
71 | .hljs-rules .hljs-property,
72 | .django .hljs-tag .hljs-keyword {
73 | color: #000080;
74 | font-weight: normal;
75 | }
76 |
77 | .hljs-attribute,
78 | .hljs-variable,
79 | .lisp .hljs-body {
80 | color: #008080;
81 | }
82 |
83 | .hljs-regexp {
84 | color: #009926;
85 | }
86 |
87 | .hljs-symbol,
88 | .ruby .hljs-symbol .hljs-string,
89 | .lisp .hljs-keyword,
90 | .clojure .hljs-keyword,
91 | .scheme .hljs-keyword,
92 | .tex .hljs-special,
93 | .hljs-prompt {
94 | color: #990073;
95 | }
96 |
97 | .hljs-built_in {
98 | color: #0086b3;
99 | }
100 |
101 | .hljs-preprocessor,
102 | .hljs-pragma,
103 | .hljs-pi,
104 | .hljs-doctype,
105 | .hljs-shebang,
106 | .hljs-cdata {
107 | color: #999;
108 | font-weight: bold;
109 | }
110 |
111 | .hljs-deletion {
112 | background: #fdd;
113 | }
114 |
115 | .hljs-addition {
116 | background: #dfd;
117 | }
118 |
119 | .diff .hljs-change {
120 | background: #0086b3;
121 | }
122 |
123 | .hljs-chunk {
124 | color: #aaa;
125 | }
126 |
--------------------------------------------------------------------------------
/web/build/css/main.css:
--------------------------------------------------------------------------------
1 | /* custom font icons */
2 | @import "font-icons/style.css";
3 |
4 | /* hightlight.js for syntax highlighting */
5 | @import "github.css";
6 |
7 | a {
8 | color: #ff4081;
9 | text-decoration: none;
10 | }
11 |
12 | a:hover {
13 | text-decoration: underline;
14 | }
15 |
16 | html {
17 | font-family: 'Roboto', sans-serif;
18 | -webkit-font-smoothing: antialiased;
19 | }
20 |
21 | body, h1, h2, h3, h4, h5, h6 {
22 | margin: 0;
23 | }
24 |
25 | body {
26 | font-size: 15px;
27 | line-height: 24px;
28 | }
29 |
30 | /* Used in our inline-styles.jsx as an example */
31 | .muidocs-checkbox-example {
32 | border: 2px solid #FF9800;
33 | background-color: #4CAF50;
34 | }
35 |
--------------------------------------------------------------------------------
/web/build/fonts/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/fonts/iconfont.eot
--------------------------------------------------------------------------------
/web/build/fonts/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/fonts/iconfont.ttf
--------------------------------------------------------------------------------
/web/build/fonts/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/fonts/iconfont.woff
--------------------------------------------------------------------------------
/web/build/images/3fuyu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/3fuyu.png
--------------------------------------------------------------------------------
/web/build/images/3fuyu_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/3fuyu_bg.jpg
--------------------------------------------------------------------------------
/web/build/images/3fuyu_small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/3fuyu_small.jpg
--------------------------------------------------------------------------------
/web/build/images/angular.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/angular.jpg
--------------------------------------------------------------------------------
/web/build/images/banner_small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/banner_small.jpg
--------------------------------------------------------------------------------
/web/build/images/banner_small_two.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/banner_small_two.jpg
--------------------------------------------------------------------------------
/web/build/images/electron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/electron.png
--------------------------------------------------------------------------------
/web/build/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/favicon.ico
--------------------------------------------------------------------------------
/web/build/images/gomoku.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/gomoku.jpg
--------------------------------------------------------------------------------
/web/build/images/mongodb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/mongodb.jpg
--------------------------------------------------------------------------------
/web/build/images/nodejs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/nodejs.jpg
--------------------------------------------------------------------------------
/web/build/images/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/react.png
--------------------------------------------------------------------------------
/web/build/images/vue.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/vue.jpg
--------------------------------------------------------------------------------
/web/build/images/weex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/images/weex.png
--------------------------------------------------------------------------------
/web/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 3fuyu
8 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/web/build/laboratory/gomoku/index.css:
--------------------------------------------------------------------------------
1 | .main-content{position:relative;background-image:url(./wood.jpg);background-repeat:no-repeat;background-size:700px;margin:0 auto;height:100%;box-shadow:0 0 10px #000}.options{position:absolute;top:80px;right:50px}.options div{width:150px;height:40px;font-size:16px;border-radius:10px;cursor:pointer;box-shadow:0 1px 1px #333;line-height:40px;text-align:center}.board-content{font-size:0;width:600px;margin-left:50px;padding:55px}.board-item{display:inline-block;width:40px;height:40px;position:relative}.row{position:absolute;height:1px;width:100%;content:' ';background-color:#444;top:20px}.column{position:absolute;width:1px;height:100%;content:' ';background-color:#444;left:19px}.row-left-top{position:absolute;width:2px;height:50%;content:' ';background-color:#444;left:20px;top:20px}.column-left-top{position:absolute;height:2px;width:50%;content:' ';background-color:#444;left:20px;top:20px}.row-right-top{position:absolute;width:2px;height:50%;content:' ';background-color:#444;right:20px;top:20px}.column-right-top{position:absolute;height:2px;width:50%;content:' ';background-color:#444;right:20px;top:20px}.row-left-bottom{position:absolute;width:2px;height:50%;content:' ';background-color:#444;left:20px;bottom:20px}.column-left-bottom{position:absolute;height:2px;width:50%;content:' ';background-color:#444;left:20px;bottom:20px}.row-right-bottom{position:absolute;width:2px;height:50%;content:' ';background-color:#444;right:20px;bottom:20px}.column-right-bottom{position:absolute;height:2px;width:50%;content:' ';background-color:#444;right:20px;bottom:20px}.row-top{position:absolute;height:2px;width:100%;content:' ';background-color:#444;top:20px}.column-top{position:absolute;width:1px;height:50%;content:' ';background-color:#444;top:20px;left:19px}.row-bottom{position:absolute;height:2px;width:100%;content:' ';background-color:#444;bottom:20px}.column-bottom{position:absolute;width:1px;height:50%;content:' ';background-color:#444;bottom:20px;left:19px}.row-left{position:absolute;height:1px;width:50%;content:' ';background-color:#444;left:20px;top:20px}.column-left{position:absolute;width:2px;height:100%;content:' ';background-color:#444;left:20px}.row-right{position:absolute;height:1px;width:50%;content:' ';background-color:#444;right:20px;top:20px}.column-right{position:absolute;width:2px;height:100%;content:' ';background-color:#444;right:20px}.black:before{position:absolute;width:100%;height:100%;border-radius:1000px;content:' ';z-index:1;background:-webkit-radial-gradient(30% 25%,circle closest-corner,#777,#222);background:-moz-radial-gradient(30% 25%,circle closest-corner,#777,#222);background:-o-radial-gradient(30% 25%,circle closest-corner,#777,#222);background:-ms-radial-gradient(30% 25%,circle closest-corner,#777,#222);background:radial-gradient(30% 25%,circle closest-corner,#777,#222);-webkit-box-shadow:inset 0 -2px 15px rgba(255,255,255,.3),inset -2px -1px 40px rgba(10,10,10,.4),0 0 2px rgba(0,0,0,.5);box-shadow:inset 0 -2px 15px rgba(255,255,255,.3),inset -2px -1px 40px rgba(10,10,10,.4),0 0 2px rgba(0,0,0,.5);-webkit-transform:scale(.9);-moz-transform:scale(.9);-o-transform:scale(.9);-ms-transform:scale(.9);transform:scale(.9)}.white:before{position:absolute;width:100%;height:100%;border-radius:1000px;content:' ';z-index:1;background:-webkit-radial-gradient(30% 25%,circle closest-corner,#fff,#eee);background:-moz-radial-gradient(30% 25%,circle closest-corner,#fff,#eee);background:-o-radial-gradient(30% 25%,circle closest-corner,#fff,#eee);background:-ms-radial-gradient(30% 25%,circle closest-corner,#fff,#eee);background:radial-gradient(30% 25%,circle closest-corner,#fff,#eee);-webkit-box-shadow:inset 0 -2px 15px rgba(255,255,255,.3),inset -2px -1px 40px rgba(10,10,100,.4),0 0 2px rgba(0,0,0,.5);box-shadow:inset 0 -2px 15px rgba(255,255,255,.3),inset -2px -1px 40px rgba(10,10,100,.4),0 0 2px rgba(0,0,0,.5);-webkit-transform:scale(.9);-moz-transform:scale(.9);-o-transform:scale(.9);-ms-transform:scale(.9);transform:scale(.9)}.options>div{border:1px solid #c27426;background:#c27426;font-weight:700;color:#fff;text-shadow:0 1px 1px #444;background-image:-webkit-gradient(linear,left top,left bottom,from(#d57f29),to(#ae6822));background-image:-webkit-linear-gradient(#d57f29,#ae6822);background-image:-moz-linear-gradient(#d57f29,#ae6822);background-image:-ms-linear-gradient(#d57f29,#ae6822);background-image:-o-linear-gradient(#d57f29,#ae6822);background-image:linear-gradient(#d57f29,#ae6822);margin-bottom:30px}
--------------------------------------------------------------------------------
/web/build/laboratory/gomoku/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gomoku
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
人机
13 |
重新开始
14 |
悔棋
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/web/build/laboratory/gomoku/wood.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/build/laboratory/gomoku/wood.jpg
--------------------------------------------------------------------------------
/web/build/versions.json:
--------------------------------------------------------------------------------
1 | [
2 | "HEAD",
3 | "v0.15.4",
4 | "v0.15.3",
5 | "v0.15.2",
6 | "v0.15.1",
7 | "v0.15.0",
8 | "v0.14.4",
9 | "v0.14.3",
10 | "v0.14.2",
11 | "v0.14.1",
12 | "v0.14.0",
13 | "v0.13.4",
14 | "v0.13.3",
15 | "v0.13.2",
16 | "v0.13.1",
17 | "v0.13.0",
18 | "v0.12.5",
19 | "v0.12.4",
20 | "v0.12.3",
21 | "v0.12.2",
22 | "v0.12.1",
23 | "v0.12.0",
24 | "v0.11.1",
25 | "v0.11.0",
26 | "v0.10.4",
27 | "v0.10.3",
28 | "v0.10.2",
29 | "v0.10.1",
30 | "v0.10.0",
31 | "v0.9.2",
32 | "v0.9.1",
33 | "v0.9.0",
34 | "v0.8.0",
35 | "v0.7.5",
36 | "v0.7.2",
37 | "v0.7.1",
38 | "v0.5.0",
39 | "v0.7.4",
40 | "v0.7.3",
41 | "v0.7.0",
42 | "v0.6.1",
43 | "v0.6.0",
44 | "v0.4.1",
45 | "v0.4.0",
46 | "v0.3.3",
47 | "v0.3.2",
48 | "v0.3.1",
49 | "v0.3.0"
50 | ]
51 |
--------------------------------------------------------------------------------
/web/gulpfile.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/03/10.
3 | */
4 |
5 | (function () {
6 | "use strict";
7 |
8 | var gulp = require('gulp'),
9 | uglify = require('gulp-uglify'),
10 | zip = require('gulp-zip'),
11 | clean = require('gulp-clean');
12 | // htmlmin = require('gulp-htmlmin'),
13 | // minify = require('gulp-minify-css');
14 |
15 | var releaseVersion = '1-0-0';
16 |
17 | var date = new Date();
18 | var result = date.getFullYear() + (date.getMonth() < 9 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes());
19 |
20 | var debugVersion = releaseVersion.split('-')[0] + '-' + releaseVersion.split('-')[1] + '-' + result;
21 |
22 | var realm = 'quality';
23 |
24 | gulp.task('default-release', ['build-release-dist', 'clean-src'], function () {
25 | //default
26 | });
27 |
28 | gulp.task('build-release-dist', ['build-release-directory'], function () {
29 | return gulp.src([
30 | 'dist/**'
31 | ])
32 | .pipe(zip(realm + '-' + releaseVersion + '.zip'))
33 | .pipe(gulp.dest('dist'));
34 |
35 | });
36 |
37 | gulp.task('build-release-directory', ['build-release-directory-index'], function () {
38 | return gulp.src([
39 | 'assets/*/*'
40 | ])
41 | .pipe(gulp.dest('dist/quality/assets'));
42 | });
43 |
44 | gulp.task('build-release-directory-index',['clean-dist'], function () {
45 | return gulp.src([
46 | 'index.html'
47 | ])
48 | .pipe(gulp.dest('dist/quality'));
49 | });
50 |
51 | gulp.task('build-debug-dist', function () {
52 | return gulp.src([
53 | 'assets/*/*'
54 | ])
55 | .pipe(zip(realm + '-' + debugVersion + '.zip'))
56 | .pipe(gulp.dest('dist'));
57 |
58 | });
59 |
60 | gulp.task('clean-src', function () {
61 | return gulp.src([
62 | 'dist/quality'
63 | ])
64 | .pipe(clean());
65 | });
66 |
67 | gulp.task('clean-dist', function () {
68 | return gulp.src([
69 | 'dist'
70 | ])
71 | .pipe(clean());
72 | });
73 |
74 | gulp.task('html-min', function () {
75 | return gulp.src([
76 | 'conf.index.html'
77 | ])
78 | .pipe(
79 | htmlmin({collapseWhitespace: true})
80 | )
81 | .pipe(gulp.dest('dist'));
82 | });
83 |
84 | gulp.task('css-min', function () {
85 | return gulp.src([
86 | 'dist/conf.index.html'
87 | ])
88 | .pipe(minify())
89 | .pipe(gulp.dest('dist'));
90 | });
91 | })();
--------------------------------------------------------------------------------
/web/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-project",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack --colors",
8 | "start": "webpack-dev-server --config webpack.config.js --progress --colors --inline",
9 | "browser:build": "NODE_ENV=docs-production webpack --config webpack-production.config.js --progress --colors --profile"
10 | },
11 | "author": "3fuyu",
12 | "license": "ISC",
13 | "peerDependencies": {
14 | "react": "15.3.1",
15 | "react-component": "0.0.0",
16 | "react-dom": "15.3.1",
17 | "react-redux": "4.4.5",
18 | "react-router": "2.0.0",
19 | "react-tap-event-plugin": "1.0.0",
20 | "material-ui": "0.15.4"
21 | },
22 | "dependencies": {
23 | "babel-plugin-transform-react-constant-elements": "6.9.1",
24 | "babel-plugin-transform-react-inline-elements": "6.8.0",
25 | "babel-plugin-transform-react-remove-prop-types": "0.2.9",
26 | "babel-plugin-transform-replace-object-assign": "0.2.1",
27 | "babel-preset-stage-1": "6.13.0",
28 | "material-ui": "0.15.4",
29 | "md5": "2.2.1",
30 | "mongoose": "4.5.8",
31 | "react": "15.3.1",
32 | "react-component": "0.0.0",
33 | "react-dom": "15.3.1",
34 | "react-redux": "4.4.5",
35 | "react-router": "2.0.0"
36 | },
37 | "devDependencies": {
38 | "autosize": "^3.0.15",
39 | "babel": "^6.5.2",
40 | "babel-core": "^6.6.4",
41 | "babel-loader": "^6.2.4",
42 | "babel-polyfill": "^6.7.2",
43 | "babel-preset-es2015": "^6.6.0",
44 | "babel-preset-react": "^6.5.0",
45 | "copy-webpack-plugin": "^3.0.1",
46 | "css-loader": "^0.23.1",
47 | "fastclick": "^1.0.6",
48 | "gulp": "^3.8.11",
49 | "gulp-browserify": "^0.5.1",
50 | "gulp-clean": "^0.3.2",
51 | "gulp-concat": "^2.5.2",
52 | "gulp-connect": "^2.2.0",
53 | "gulp-react": "^3.0.1",
54 | "gulp-uglify": "^1.5.3",
55 | "gulp-zip": "^3.2.0",
56 | "history": "^2.0.1",
57 | "jquery": "^3.1.1",
58 | "less": "^2.7.1",
59 | "less-loader": "^2.2.3",
60 | "lodash": "^3.6.0",
61 | "marked": "^0.3.6",
62 | "material-ui": "^0.15.4",
63 | "moment": "^2.15.1",
64 | "path": "^0.12.7",
65 | "react": "15.3.1",
66 | "react-addons-perf": "15.3.2",
67 | "react-dom": "15.3.2",
68 | "react-hot-loader": "3.0.0-beta.3",
69 | "react-redux": "4.4.5",
70 | "react-router": "2.8.0",
71 | "react-tap-event-plugin": "1.0.0",
72 | "react-title-component": "1.0.1",
73 | "reactify": "1.1.0",
74 | "redux": "3.6.0",
75 | "store": "1.3.20",
76 | "style-loader": "^0.13.0",
77 | "superagent": "^1.8.0",
78 | "webpack": "^1.12.14",
79 | "webpack-dev-server": "^1.14.1"
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/web/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/.DS_Store
--------------------------------------------------------------------------------
/web/src/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react", "es2015", "stage-1"],
3 | "plugins": [
4 | ["transform-replace-object-assign", "simple-assign", "react-hot-loader/babel"]
5 | ],
6 | "env": {
7 | "docs-production": {
8 | "plugins": [
9 | "transform-react-remove-prop-types",
10 | "transform-react-constant-elements",
11 | "transform-react-inline-elements",
12 | ["transform-replace-object-assign", "simple-assign"]
13 | ]
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/web/src/app/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/.DS_Store
--------------------------------------------------------------------------------
/web/src/app/AppRoutes.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Route, Redirect, IndexRoute} from 'react-router';
3 | import Master from '../app/js/components/management/Master';
4 | import Login from '../app/js/components/management/Login';
5 | import Home from '../app/js/components/index/Home';
6 | import ArticleDetail from '../app/js/components/index/ArticleDetail';
7 | import NewArticle from '../app/js/components/management/NewArticle';
8 | import ArticleList from '../app/js/components/management/ArticleList';
9 | import ArticleCategory from '../app/js/components/management/ArticleCategory';
10 | import Media from '../app/js/components/management/Media';
11 | import About from '../app/js/components/index/About';
12 | import Laboratory from '../app/js/components/index/Laboratory';
13 |
14 |
15 | // Here we define all our material-ui ReactComponents.
16 |
17 | /**
18 | * Routes: https://github.com/rackt/react-router/blob/master/docs/api/components/Route.md
19 | *
20 | * Routes are used to declare your view hierarchy.
21 | *
22 | * Say you go to http://material-ui.com/#/components/paper
23 | * The react router will search for a route named 'paper' and will recursively render its
24 | * handler and its parent handler like so: Paper > Components > Master
25 | */
26 | const AppRoutes = (
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | );
45 |
46 | export default AppRoutes;
47 |
--------------------------------------------------------------------------------
/web/src/app/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {render} from 'react-dom';
3 | import $ from 'jquery';
4 | import {Router, useRouterHistory} from 'react-router';
5 | import AppRoutes from './AppRoutes';
6 | import injectTapEventPlugin from 'react-tap-event-plugin';
7 | import {createHashHistory} from 'history';
8 | import MuiThemeProvider from '../../node_modules/material-ui/styles/MuiThemeProvider';
9 | // Helpers for debugging
10 | window.React = React;
11 | window.Perf = require('react-addons-perf');
12 | window.$ = $;
13 | // Needed for onTouchTap
14 | // http://stackoverflow.com/a/34015469/988941
15 | injectTapEventPlugin();
16 |
17 | /**
18 | * Render the main app component. You can read more about the react-router here:
19 | * https://github.com/rackt/react-router/blob/master/docs/guides/overview.md
20 | */
21 |
22 | const App = () => (
23 |
24 |
25 | {AppRoutes}
26 |
27 |
28 | );
29 |
30 | render(
31 |
32 | , document.getElementById('app'));
33 |
--------------------------------------------------------------------------------
/web/src/app/css/about.less:
--------------------------------------------------------------------------------
1 | #about {
2 | display: flex;
3 | color: #ef6b3a;
4 | font-weight: bold;
5 | flex-direction: column;
6 | font-size: 16px;
7 | font-family: "Microsoft YaHei", Helvetica, Arial, 'Hiragino Sans GB', '微软雅黑', sans-serif;
8 |
9 | .head {
10 | display: flex;
11 | flex-direction: column;
12 | justify-content: center;
13 | align-items: center;
14 | width: 800px;
15 | margin: 0 auto 50px;
16 | .logo {
17 | width: 300px;
18 | margin-top: 20px;
19 | }
20 | .discription {
21 | font-size: 28px;
22 | font-weight: bold;
23 | font-family: "Helvetica Neue", Helvetica, Arial, 'Hiragino Sans GB', 'Microsoft Yahei', '微软雅黑', sans-serif;
24 | }
25 | }
26 | .line {
27 | height: 1px;
28 | content: ' ';
29 | margin: 10px 0 80px;
30 | background-color: #ef6b3a;
31 | }
32 | .body {
33 | display: flex;
34 | flex-direction: column;
35 | width: 800px;
36 | margin: 0 auto 200px;
37 |
38 | .about_me {
39 | .title {
40 | font-size: 30px;
41 | font-family: "Helvetica Neue", Helvetica, Arial, 'Hiragino Sans GB', 'Microsoft Yahei', '微软雅黑', sans-serif;
42 | }
43 | }
44 | .about_power {
45 | .title {
46 | font-size: 30px;
47 | font-family: "Helvetica Neue", Helvetica, Arial, 'Hiragino Sans GB', 'Microsoft Yahei', '微软雅黑', sans-serif;
48 | span {
49 | font-size: 16px;
50 | }
51 | }
52 | .about_power_content {
53 | display: flex;
54 | flex-direction: column;
55 | align-items: center;
56 | }
57 | }
58 | .contact_me {
59 | font-family: "Helvetica Neue", Helvetica, Arial, 'Hiragino Sans GB', 'Microsoft Yahei', '微软雅黑', sans-serif;
60 | .title {
61 | font-size: 30px;
62 | }
63 | a {
64 | color: #ef6b3a;
65 | }
66 | }
67 | .attention {
68 | .title {
69 | font-size: 30px;
70 | font-family: "Helvetica Neue", Helvetica, Arial, 'Hiragino Sans GB', 'Microsoft Yahei', '微软雅黑', sans-serif;
71 | }
72 | .attention_list {
73 | display: flex;
74 | img {
75 | height: 70px;
76 | margin-right: 40px;
77 | }
78 | }
79 | }
80 | }
81 | .footer {
82 | height: 300px;
83 | width: 100%;
84 | background-color: #212121;
85 | color: #fff;
86 | font-size: 15px;
87 | .footer-content {
88 | text-align: center;
89 | padding-top: 80px;
90 | color: rgba(255, 255, 255, 0.541176);
91 | .footer-content-github {
92 | margin: 10px 0 30px 0;
93 | span {
94 | color: rgba(255, 255, 255, 0.870588) !important;
95 | }
96 | }
97 | .ICP {
98 | font-size: 12px;
99 | img {
100 | position: relative;
101 | top: 3px;
102 | margin: 0 8px;
103 | width: 14px;
104 | height: 14px;
105 | border-radius: 14px;
106 | }
107 | }
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/web/src/app/css/articleCategory.less:
--------------------------------------------------------------------------------
1 | #article-category {
2 | padding: 20px 40px;
3 |
4 | .article-category-title {
5 | margin-bottom: 40px;
6 | }
7 |
8 | .article-category-list {
9 | .article-category-list-title {
10 | }
11 | .article-categoyr-list-content {
12 | display: flex;
13 | flex-wrap: wrap;
14 | .category-label-repeat {
15 | -webkit-font-smoothing: initial;
16 | margin-right: 10px!important;
17 | margin-bottom: 15px!important;
18 | svg {
19 | opacity: 0;
20 | }
21 | span {
22 | color: #fefefe!important;
23 | font-weight: bold;
24 | }
25 | }
26 | .category-label-repeat:hover {
27 | svg {
28 | opacity: 1;
29 | }
30 | }
31 | }
32 |
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/web/src/app/css/articleDetail.less:
--------------------------------------------------------------------------------
1 | #article-detail {
2 | img {
3 | width: 100%;
4 | }
5 | .article-detail-content {
6 | display: flex;
7 | color: #2D3F50;
8 | h1 {
9 | font-size: 40px;
10 | margin: 30px 0 22px 0;
11 | }
12 | h2 {
13 | font-size: 32px;
14 | margin: 30px 0 22px 0;
15 | }
16 | h3 {
17 | font-size: 24px;
18 | margin: 30px 0 22px 0;
19 | }
20 | h4 {
21 | font-size: 16px;
22 | margin: 30px 0 22px 0;
23 | }
24 |
25 | .article-main {
26 | flex: 1;
27 | margin: 100px 50px 50px 150px;
28 | .article-title {
29 | font-size: 50px;
30 | line-height: 1.5;
31 | margin-bottom: 10px;
32 | font-weight: bold;
33 | }
34 | .article-date {
35 | font-size: 14px;
36 | margin-bottom: 20px;
37 | padding-left: 5px;
38 | color: #9EABB3;
39 | }
40 | .article-content {
41 | overflow: auto;
42 |
43 | line-height: 2;
44 |
45 | blockquote {
46 | margin: 20px 0;
47 | padding: 1px 30px;
48 | background: #F2F4F6;
49 | border-left: 10px solid #E8EDEE;
50 | }
51 |
52 | ul {
53 | padding-left: 36px;
54 | margin: 0 0 32px 20px;
55 | li {
56 | margin: 8px 0;
57 | }
58 | li::before {
59 | content: "";
60 | display: block;
61 | position: relative;
62 | top: 19px;
63 | left: -20px;
64 | width: 6px;
65 | height: 6px;
66 | background: #3A4145;
67 | -moz-border-radius: 50px;
68 | -webkit-border-radius: 50px;
69 | border-radius: 50px;
70 | }
71 |
72 | }
73 | }
74 | #SOHUCS {
75 | margin-top: 55px;
76 | padding-top: 50px;
77 | border-top: 1px dashed #ddd;
78 | }
79 | }
80 | .article-sidebar {
81 | width: 300px;
82 | margin: 280px 20px 20px 20px;
83 | .article-sidebar-category {
84 | font-size: 20px;
85 | line-height: 20px;
86 | }
87 | .article-sidebar-tag-list {
88 | color: #fff;
89 | display: flex;
90 | justify-content: flex-start;
91 | flex-wrap: wrap;
92 | font-size: 12px;
93 | margin-top: 20px;
94 |
95 | .tag-item {
96 | padding: 1px 12px;
97 | background: rgba(0, 0, 0, 0.1);
98 | border-radius: 5px;
99 | margin: 5px 10px 5px 0;
100 | height: 24px;
101 | line-height: 22px;
102 | transition: all 1000ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
103 | }
104 |
105 | .tag-item:hover {
106 | background-color: #1FBCD2;
107 | color: #fff;
108 | cursor: pointer;
109 | }
110 | }
111 | }
112 | pre {
113 | padding: 16px 22px;
114 | overflow: auto;
115 | font-size: 85%;
116 | line-height: 1.45;
117 | background-color: #f6f6f6;
118 | border-radius: 3px;
119 | line-height: 2;
120 | border-radius: 5px;
121 | }
122 |
123 | code, kbd, pre, samp {
124 | font-family: Monaco, Source Code Pro, Consolas, Menlo, Monaco, Courier New, monospace;
125 | }
126 |
127 | table {
128 | width: 100%;
129 | border: 1px solid #f2f2f2;
130 | padding: 0px 10px;
131 | margin: 10px 0;
132 | border-collapse: collapse;
133 | td, th {
134 | border: 1px solid #f2f2f2;
135 | padding: 0 10px 2px 10px;
136 | }
137 | }
138 |
139 | }
140 |
141 | }
--------------------------------------------------------------------------------
/web/src/app/css/articleList.less:
--------------------------------------------------------------------------------
1 | #article-list {
2 | padding: 20px 40px;
3 | .list-head {
4 | th {
5 | font-size: 16px!important;
6 | color: #0e0e0e!important;
7 | }
8 | }
9 | table {
10 | border: none;
11 | th, td {
12 | border: none;
13 | }
14 | .option {
15 | width: 200px;
16 | text-align: center!important;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/web/src/app/css/base.less:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: 'Open Sans', Tahoma, Helvetica, Arial, '黑体', sans-serif!important;
4 | }
5 |
6 | .y-hide {
7 | display: none !important;
8 | }
9 |
10 | ul {
11 | outline: none;
12 | list-style: none;
13 | margin: 0;
14 | padding: 0;
15 | }
16 |
17 | h1, h2, h3, h4, h5, h6 {
18 | -webkit-font-feature-settings: 'dlig' 1, 'liga' 1, 'lnum' 1, 'kern' 1;
19 | -moz-font-feature-settings: 'dlig' 1, 'liga' 1, 'lnum' 1, 'kern' 1;
20 | -o-font-feature-settings: 'dlig' 1, 'liga' 1, 'lnum' 1, 'kern' 1;
21 | color: #2E2E2E;
22 | line-height: 1.15em;
23 | margin: 0 0 0.4em 0;
24 | font-family: "Open Sans", sans-serif;
25 | text-rendering: geometricPrecision;
26 | }
27 |
28 | h2 {
29 | font-size: 36px;
30 | letter-spacing: -1px;
31 | }
32 |
33 | html {
34 | font-family: sans-serif;
35 | -ms-text-size-adjust: 100%;
36 | -webkit-text-size-adjust: 100%;
37 | }
--------------------------------------------------------------------------------
/web/src/app/css/github-gist.css:
--------------------------------------------------------------------------------
1 | /**
2 | * GitHub Gist Theme
3 | * Author : Anthony Attard - https://github.com/AnthonyAttard
4 | * Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
5 | */
6 |
7 | .hljs {
8 | display: block;
9 | background: white;
10 | padding: 0.5em;
11 | color: #333333;
12 | overflow-x: auto;
13 | }
14 |
15 | .hljs-comment,
16 | .hljs-meta {
17 | color: #969896;
18 | }
19 |
20 | .hljs-variable,
21 | .hljs-template-variable,
22 | .hljs-strong,
23 | .hljs-emphasis,
24 | .hljs-quote {
25 | color: #df5000;
26 | }
27 |
28 | .hljs-keyword,
29 | .hljs-selector-tag,
30 | .hljs-type {
31 | color: #d73a49;
32 | }
33 |
34 | .hljs-literal,
35 | .hljs-symbol,
36 | .hljs-bullet,
37 | .hljs-attribute {
38 | color: #0086b3;
39 | }
40 |
41 | .hljs-section,
42 | .hljs-name {
43 | color: #63a35c;
44 | }
45 |
46 | .hljs-tag {
47 | color: #333333;
48 | }
49 |
50 | .hljs-title,
51 | .hljs-attr,
52 | .hljs-selector-id,
53 | .hljs-selector-class,
54 | .hljs-selector-attr,
55 | .hljs-selector-pseudo {
56 | color: #6f42c1;
57 | }
58 |
59 | .hljs-addition {
60 | color: #55a532;
61 | background-color: #eaffea;
62 | }
63 |
64 | .hljs-deletion {
65 | color: #bd2c00;
66 | background-color: #ffecec;
67 | }
68 |
69 | .hljs-link {
70 | text-decoration: underline;
71 | }
72 |
73 | .hljs-number {
74 | color: #005cc5;
75 | }
76 |
77 | .hljs-string {
78 | color: #032f62;
79 | }
80 |
--------------------------------------------------------------------------------
/web/src/app/css/iconfont/iconfont.css:
--------------------------------------------------------------------------------
1 |
2 | @font-face {font-family: "iconfont";
3 | src: url('iconfont.eot?t=1459136393'); /* IE9*/
4 | src: url('iconfont.eot?t=1459136393#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('iconfont.woff?t=1459136393') format('woff'), /* chrome, firefox */
6 | url('iconfont.ttf?t=1459136393') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
7 | url('iconfont.svg?t=1459136393#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family:"iconfont" !important;
12 | font-size:16px;
13 | font-style:normal;
14 | -webkit-font-smoothing: antialiased;
15 | -webkit-text-stroke-width: 0.2px;
16 | -moz-osx-font-smoothing: grayscale;
17 | }
18 | .icon-commoditymanagement01:before { content: "\e600"; }
19 | .icon-ordermanagement01:before { content: "\e601"; }
20 | .icon-groupons01:before { content: "\e602"; }
21 | .icon-richscan01:before { content: "\e603"; }
22 | .icon-refund01:before { content: "\e604"; }
23 | .icon-specialoffer01:before { content: "\e605"; }
24 | .icon-income01:before { content: "\e606"; }
25 | .icon-sitemanager01:before { content: "\e607"; }
26 | .icon-statistical01:before { content: "\e608"; }
27 | .icon-operationcofiguration01:before { content: "\e609"; }
28 | .icon-unpaiding01:before { content: "\e60a"; }
29 | .icon-unpaid01:before { content: "\e60b"; }
30 | .icon-delivered01:before { content: "\e60c"; }
31 | .icon-delivereding01:before { content: "\e60d"; }
32 | .icon-closeding01:before { content: "\e60e"; }
33 | .icon-closed01:before { content: "\e60f"; }
34 | .icon-tobeshippde01:before { content: "\e610"; }
35 | .icon-tobeshippdeing:before { content: "\e611"; }
36 | .icon-association01:before { content: "\e612"; }
37 | .icon-deblocking01:before { content: "\e613"; }
38 | .icon-privateletter01:before { content: "\e624"; }
39 | .icon-revamp01:before { content: "\e614"; }
40 | .icon-shoppingcart01:before { content: "\e615"; }
41 | .icon-sort01:before { content: "\e616"; }
42 | .icon-lockin01:before { content: "\e617"; }
43 | .icon-commoditysalesstatistics01:before { content: "\e618"; }
44 | .icon-transactionamountstatistics01:before { content: "\e619"; }
45 | .icon-transactionorderstatistics01:before { content: "\e61a"; }
46 | .icon-rob01:before { content: "\e61b"; }
47 | .icon-reverseback:before { content: "\e625"; }
48 | .icon-skip:before { content: "\e626"; }
49 | .icon-search01:before { content: "\e627"; }
50 | .icon-delete01:before { content: "\e628"; }
51 | .icon-unfold01:before { content: "\e629"; }
52 | .icon-packup01:before { content: "\e62a"; }
53 | .icon-add01:before { content: "\e61e"; }
54 | .icon-subtract01:before { content: "\e61f"; }
55 | .icon-collect01:before { content: "\e620"; }
56 | .icon-collect:before { content: "\e621"; }
57 | .icon-telephone01:before { content: "\e62b"; }
58 | .icon-time:before { content: "\e623"; }
59 | .icon-shopnotices01:before { content: "\e622"; }
60 | .icon-delete1:before { content: "\e61c"; }
61 | .icon-delete2:before { content: "\e61d"; }
62 | .icon-check:before { content: "\e62d"; }
63 | .icon-location:before { content: "\e62c"; }
64 |
--------------------------------------------------------------------------------
/web/src/app/css/iconfont/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/css/iconfont/iconfont.eot
--------------------------------------------------------------------------------
/web/src/app/css/iconfont/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/css/iconfont/iconfont.ttf
--------------------------------------------------------------------------------
/web/src/app/css/iconfont/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/css/iconfont/iconfont.woff
--------------------------------------------------------------------------------
/web/src/app/css/laboratory.less:
--------------------------------------------------------------------------------
1 | #laboratory {
2 | display: flex;
3 | flex-direction: column;
4 | font-size: 16px;
5 | width: 1200px;
6 | justify-content: center;
7 | align-items: center;
8 | margin: 0 auto;
9 | .top {
10 | width: 200px;
11 | text-align: center;
12 | .title {
13 | margin-top: 80px;
14 | }
15 | .discription {
16 | color: #666;
17 | margin: 0 0 50px 0;
18 | }
19 | }
20 | .list {
21 | display: flex;
22 | flex-direction: row;
23 | width: 100%;
24 | flex-wrap: wrap;
25 | margin-top: 50px;
26 | .list-item {
27 | display: flex;
28 | flex-direction: column;
29 | width: 265px;
30 | position: relative;
31 | border: 1px solid #eee;
32 | border-radius: 5px;
33 | margin-left: 15px;
34 | margin-right: 15px;
35 | margin-bottom: 30px;
36 | cursor: pointer;
37 | -webkit-transition: box-shadow 0.3s ease-in, -webkit-transform 0.2s ease-in;
38 | transition: box-shadow 0.3s ease-in, transform 0.2s ease-in;
39 | overflow: hidden;
40 | .photo {
41 | img {
42 | width: 265px;
43 | height: auto;
44 | }
45 | }
46 | .title {
47 | color: #333;
48 | font-size: 14px;
49 | margin: 0 10px;
50 | font-weight: bold;
51 | }
52 | .discription {
53 | font-size: 14px;
54 | color: #333;
55 | margin: 5px 10px 10px 10px;
56 | overflow: hidden;
57 | text-overflow: ellipsis;
58 | display: -webkit-box;
59 | -webkit-line-clamp: 2;
60 | -webkit-box-orient: vertical;
61 | }
62 | i.light {
63 | cursor: pointer;
64 | position: absolute;
65 | left: -100%;
66 | top: 0;
67 | width: 100%;
68 | height: 100%;
69 | background-image: -webkit-linear-gradient(0deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.5),hsla(0,0%,100%,0));
70 | transform: skewx(-25deg);
71 | -o-transform: skewx(-25deg);
72 | -moz-transform: skewx(-25deg);
73 | -webkit-transform: skewx(-25deg);
74 | }
75 |
76 | }
77 | .list-item:hover {
78 | -webkit-transform: translate(0, -6px);
79 | transform: translate(0, -6px);
80 | box-shadow: 0 26px 40px -24px rgba(26, 28, 31, 0.5);
81 | -webkit-box-shadow: 0 26px 40px -24px rgba(26, 28, 31, 0.5);
82 | -moz-box-shadow: 0 26px 40px -24px rgba(26, 28, 31, 0.5);
83 | background-color: white;
84 | i.light {
85 | -webkit-transition: all .3s ease;
86 | transition: all .3s ease;
87 | left: 100%;
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/web/src/app/css/login.less:
--------------------------------------------------------------------------------
1 | #login {
2 | width: 20%;
3 | margin: 100px auto;
4 | position: absolute;
5 | left: 0;
6 | right: 0;
7 | .title {
8 | font-size: 30px;
9 | text-align: center;
10 | padding: 50px 0;
11 | }
12 | .content {
13 | input {
14 | width: 100%;
15 | }
16 | .login-btn {
17 | margin-top: 30px;
18 | }
19 | .on-login {
20 | position: relative;
21 | float: right;
22 | top: 58px;
23 | z-index: 1;
24 | i {
25 | font-size: 24px;
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/web/src/app/css/main.less:
--------------------------------------------------------------------------------
1 | //#main {
2 | // .app-bar-title {
3 | // box-shadow: none!important;
4 | // }
5 | .menu {
6 | .menu-title {
7 | background-color: #00BCD4;
8 | height: 64px;
9 | line-height: 64px;
10 | font-size: 20px;
11 | color: #fff;
12 | padding: 0 16px;
13 | }
14 | }
15 | //}
16 |
17 | .show {
18 | display: block;
19 | }
20 |
21 | .hide {
22 | display: none!important;
23 | }
--------------------------------------------------------------------------------
/web/src/app/css/markdown.less:
--------------------------------------------------------------------------------
1 | h1 {
2 | font-size: 40px;
3 | margin: 30px 0 22px 0;
4 | }
5 |
6 | h2 {
7 | font-size: 32px;
8 | margin: 30px 0 22px 0;
9 | }
10 |
11 | h3 {
12 | font-size: 24px;
13 | margin: 30px 0 22px 0;
14 | }
15 |
16 | h4 {
17 | font-size: 16px;
18 | margin: 30px 0 22px 0;
19 | }
20 |
21 | pre {
22 | padding: 16px 22px;
23 | word-break: break-all;
24 | white-space: normal;
25 | overflow: auto;
26 | font-size: 85%;
27 | line-height: 1.45;
28 | background-color: #f6f6f6;
29 | border-radius: 3px;
30 | line-height: 2;
31 | border-radius: 5px;
32 | }
33 |
34 | code, kbd, pre, samp {
35 | font-family: Monaco, Source Code Pro, Consolas, Menlo, Monaco, Courier New, monospace;
36 | white-space: pre;
37 | }
38 |
39 | table {
40 | width: 100%;
41 | border: 1px solid #f2f2f2;
42 | padding: 0px 10px;
43 | margin: 10px 0;
44 | border-collapse: collapse;
45 | td, th {
46 | border: 1px solid #f2f2f2;
47 | padding: 0 10px 2px 10px;
48 | }
49 | }
50 |
51 | blockquote {
52 | margin: 20px 0;
53 | padding: 1px 30px;
54 | background: #F2F4F6;
55 | border-left: 10px solid #E8EDEE;
56 | }
--------------------------------------------------------------------------------
/web/src/app/css/newArticle.less:
--------------------------------------------------------------------------------
1 | #new-article {
2 | padding: 20px 40px;
3 | .article-title {
4 | z-index: 99;
5 | font-size: 24px!important;
6 | hr {
7 | bottom: 0!important;
8 | }
9 | }
10 | .article-date {
11 | color: #555;
12 | font-size: 16px;
13 | padding: 20px 0 6px 0;
14 | position: relative;
15 | z-index: 99;
16 | }
17 | .article-category {
18 | color: #555;
19 | font-size: 16px;
20 | z-index: 99;
21 | }
22 | #article-editor {
23 | background: #FBFBFB;
24 | position: absolute;
25 | right: 0;
26 | top: 0;
27 | left: 256px;
28 | padding: 250px 40px;
29 | z-index: 9;
30 | height: 100%;
31 | width: 1024px;
32 | font-size: 13pt;
33 | line-height: 1.8em;
34 | resize: none;
35 | outline: none;
36 | display: block;
37 | border: none;
38 | white-space: pre-wrap;
39 | word-wrap: break-word;
40 | box-sizing: border-box;
41 | }
42 | #article-editor:focus {
43 | outline: none;
44 | }
45 | .article-submit {
46 | position: absolute;
47 | bottom: 40px;
48 | right: 40px;
49 | z-index: 99;
50 | span {
51 | color: #FFF;
52 | line-height: 56px;
53 | height: 56px;
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/web/src/app/fonts/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/fonts/iconfont.eot
--------------------------------------------------------------------------------
/web/src/app/fonts/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/fonts/iconfont.ttf
--------------------------------------------------------------------------------
/web/src/app/fonts/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/fonts/iconfont.woff
--------------------------------------------------------------------------------
/web/src/app/images/3fuyu_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/3fuyu_bg.jpg
--------------------------------------------------------------------------------
/web/src/app/images/add_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/add_pic.png
--------------------------------------------------------------------------------
/web/src/app/images/angular.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/angular.jpg
--------------------------------------------------------------------------------
/web/src/app/images/banner_small_two.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/banner_small_two.jpg
--------------------------------------------------------------------------------
/web/src/app/images/default_xz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/default_xz.png
--------------------------------------------------------------------------------
/web/src/app/images/delete_btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/delete_btn.png
--------------------------------------------------------------------------------
/web/src/app/images/electron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/electron.png
--------------------------------------------------------------------------------
/web/src/app/images/gomoku.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/gomoku.jpg
--------------------------------------------------------------------------------
/web/src/app/images/gomoku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/gomoku.png
--------------------------------------------------------------------------------
/web/src/app/images/line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/line.png
--------------------------------------------------------------------------------
/web/src/app/images/line_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/line_green.png
--------------------------------------------------------------------------------
/web/src/app/images/logo_small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/logo_small.jpg
--------------------------------------------------------------------------------
/web/src/app/images/mongodb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/mongodb.jpg
--------------------------------------------------------------------------------
/web/src/app/images/nodejs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/nodejs.jpg
--------------------------------------------------------------------------------
/web/src/app/images/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/react.png
--------------------------------------------------------------------------------
/web/src/app/images/select_photo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/select_photo.jpg
--------------------------------------------------------------------------------
/web/src/app/images/select_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/select_photo.png
--------------------------------------------------------------------------------
/web/src/app/images/vue.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/vue.jpg
--------------------------------------------------------------------------------
/web/src/app/images/weex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/images/weex.png
--------------------------------------------------------------------------------
/web/src/app/js/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/js/.DS_Store
--------------------------------------------------------------------------------
/web/src/app/js/actions/actions.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/9/14.
3 | */
4 | "use strict";
5 |
6 | /*
7 | * action 类型
8 | */
9 |
10 | export const ADD_TODO = 'ADD_TODO';
11 | export const COMPLETE_TODO = 'COMPLETE_TODO';
12 |
13 |
14 | /*
15 | * action 创建函数
16 | */
17 |
18 | export function addTodo(text) {
19 | return { type: ADD_TODO, text };
20 | }
21 |
22 | export function completeTodo(index) {
23 | return { type: COMPLETE_TODO, index };
24 | }
--------------------------------------------------------------------------------
/web/src/app/js/components/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/js/components/.DS_Store
--------------------------------------------------------------------------------
/web/src/app/js/components/index/About.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/7/7.
3 | */
4 |
5 | import {Component} from 'react';
6 | import Power from './About_power';
7 | import '../../../css/about.less';
8 | import IconButton from "../../../../../node_modules/material-ui/IconButton";
9 |
10 | class About extends Component {
11 | componentWillMount () {
12 | document.body.scrollTop = 0;
13 | }
14 | render() {
15 | return (
16 |
17 |
18 |

19 |
3Fuyu
20 |
21 |
22 |
23 |
About Me
24 |
25 | 3fuyu(张宇),93年生,平常喜欢跑步,大学跑了三年,工作之后有时间就会跑,现在基本每晚四公里。另外还是Steve
26 | Jobs的狂热粉丝,自传读过不下3遍,因此也被“扭曲厂力”感染上了轻微强迫症。
27 |
28 | 其实,我的真实身份是一枚前端攻城狮,狂热的技术爱好者。如今正是前端遍地开花的时代,一个月不吸收点新知识发发,回头再看前端就是一脸懵逼的状态。因此也提醒自己达摩克利斯之剑一直悬在头上。平常喜欢折腾技术,比如这个blog(该站建成于2017.6,基于React
29 | + Node +
30 | Mongodb,其中之前的技术文章来源于本人2014年至今用wordpress记录的文章)就是用腻了wordpress,hexo等等套路,想搞一些不仅仅限于技术文章,完全自己控制的个人站,比如Laboratory,会持续放出自己实验性的项目。
31 |
32 |
33 |
Power (随时更新)
34 |
37 |
38 |
39 |
Contact Me
40 |
Github: 3fuyu
41 |
42 |
QQ: 326141543
43 |
E-mail: sdlgdxzhangyu@163.com
44 | {/*
Social: segmentfault */}
45 | {/*| 知乎*/}
46 | {/*
*/}
47 |
48 |
49 |
Attention
50 |
51 |

52 |

53 |

54 |

55 |

56 |

57 |

58 |
59 |
60 |
61 |
62 |
63 |
Remembering that you are going to die
64 |
Stay Hungry Stay Foolish
65 |
66 |
70 |
71 |
72 |

73 |
Copyright © 2014 - {new Date().getFullYear()} ICP 16097049. All Rights Reserved. Powered By 3Fuyu.
74 |
75 |
76 |
77 |
78 | );
79 | }
80 | }
81 |
82 | export default About;
83 |
--------------------------------------------------------------------------------
/web/src/app/js/components/index/About_power.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/7/7.
3 | */
4 |
5 | import {Component} from 'react';
6 |
7 | let canvas,
8 | mW = 380,
9 | mH = 380,
10 | mData = [
11 | ['es6/7', 65],
12 | ['html/html5', 82],
13 | ['react', 78],
14 | ['js', 90],
15 | ['css/css3', 81],
16 | ['nodejs', 60],
17 | ],
18 |
19 | mCount = mData.length, //边数
20 | mCenter = mW / 2, //中心点
21 | mRadius = mCenter - 50, //半径(减去的值用于给绘制的文本留空间)
22 | mAngle = Math.PI * 2 / mCount, //角度
23 | mCtx = null,
24 | mColorPolygon = '#B8B8B8', //多边形颜色
25 | mColorLines = '#B8B8B8', //顶点连线颜色
26 | mColorText = '#000000';
27 |
28 | class About extends Component {
29 | componentDidMount() {
30 | this.initDraw();
31 | }
32 |
33 | initDraw() {
34 | canvas = document.createElement('canvas');
35 | document.getElementsByClassName('power')[0].appendChild(canvas);
36 | canvas.height = mH;
37 | canvas.width = mW;
38 | mCtx = canvas.getContext('2d');
39 |
40 | this.drawPolygon(mCtx);
41 | this.drawLines(mCtx);
42 | this.drawText(mCtx);
43 | this.drawRegion(mCtx);
44 | this.drawCircle(mCtx);
45 | }
46 |
47 | drawPolygon(ctx) {
48 | ctx.save();
49 |
50 | ctx.strokeStyle = mColorPolygon;
51 | var r = mRadius / mCount; //单位半径
52 | //画6个圈
53 | for (var i = 0; i < mCount; i++) {
54 | ctx.beginPath();
55 | var currR = r * ( i + 1); //当前半径
56 | //画6条边
57 | for (var j = 0; j < mCount; j++) {
58 | var x = mCenter + currR * Math.cos(mAngle * j);
59 | var y = mCenter + currR * Math.sin(mAngle * j);
60 |
61 | ctx.lineTo(x, y);
62 | }
63 | ctx.closePath()
64 | ctx.stroke();
65 | }
66 |
67 | ctx.restore();
68 | }
69 |
70 | //顶点连线
71 | drawLines(ctx) {
72 | ctx.save();
73 |
74 | ctx.beginPath();
75 | ctx.strokeStyle = mColorLines;
76 |
77 | for (var i = 0; i < mCount; i++) {
78 | var x = mCenter + mRadius * Math.cos(mAngle * i);
79 | var y = mCenter + mRadius * Math.sin(mAngle * i);
80 |
81 | ctx.moveTo(mCenter, mCenter);
82 | ctx.lineTo(x, y);
83 | }
84 |
85 | ctx.stroke();
86 | ctx.restore();
87 | }
88 |
89 | //绘制文本
90 | drawText(ctx) {
91 | ctx.save();
92 |
93 | var fontSize = mCenter / 12;
94 | ctx.font = fontSize + 'px Microsoft Yahei';
95 | ctx.fillStyle = mColorText;
96 |
97 | for (var i = 0; i < mCount; i++) {
98 | var x = mCenter + mRadius * Math.cos(mAngle * i);
99 | var y = mCenter + mRadius * Math.sin(mAngle * i);
100 |
101 | if (mAngle * i >= 0 && mAngle * i <= Math.PI / 2) {
102 | ctx.fillText(mData[i][0], x, y + fontSize);
103 | } else if (mAngle * i > Math.PI / 2 && mAngle * i <= Math.PI) {
104 | ctx.fillText(mData[i][0], x - ctx.measureText(mData[i][0]).width, y + fontSize);
105 | } else if (mAngle * i > Math.PI && mAngle * i <= Math.PI * 3 / 2) {
106 | ctx.fillText(mData[i][0], x - ctx.measureText(mData[i][0]).width, y);
107 | } else {
108 | ctx.fillText(mData[i][0], x, y);
109 | }
110 |
111 | }
112 |
113 | ctx.restore();
114 | }
115 |
116 | //绘制数据区域
117 | drawRegion(ctx) {
118 | ctx.save();
119 |
120 | ctx.beginPath();
121 | for (var i = 0; i < mCount; i++) {
122 | var x = mCenter + mRadius * Math.cos(mAngle * i) * mData[i][1] / 100;
123 | var y = mCenter + mRadius * Math.sin(mAngle * i) * mData[i][1] / 100;
124 |
125 | ctx.lineTo(x, y);
126 | }
127 | ctx.closePath();
128 | ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
129 | ctx.fill();
130 |
131 | ctx.restore();
132 | }
133 |
134 | //画点
135 | drawCircle(ctx) {
136 | ctx.save();
137 |
138 | var r = mCenter / 40;
139 | for (var i = 0; i < mCount; i++) {
140 | var x = mCenter + mRadius * Math.cos(mAngle * i) * mData[i][1] / 100;
141 | var y = mCenter + mRadius * Math.sin(mAngle * i) * mData[i][1] / 100;
142 |
143 | ctx.beginPath();
144 | ctx.arc(x, y, r, 0, Math.PI * 2);
145 | ctx.fillStyle = 'rgba(255, 0, 0, 0.8)';
146 | ctx.fill();
147 | }
148 |
149 | ctx.restore();
150 | }
151 |
152 | render() {
153 | return (
154 |
155 | );
156 | }
157 | }
158 |
159 | export default About;
160 |
--------------------------------------------------------------------------------
/web/src/app/js/components/index/ArticleDetail.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2016/10/19.
3 | */
4 |
5 | import {Component} from "react";
6 | import DataServicce from "../../service/DataService";
7 | import moment from "moment";
8 | import "../../../css/articleDetail.less";
9 | import "../../../css/github-gist.css";
10 | import changyan from "../../lib/changyan";
11 |
12 | class ArticleDetail extends Component {
13 |
14 | state = {
15 | articleObj: {},
16 | categorys: ['java', 'javascript', 'python', 'ruby', 'c', 'c++', 'c#', 'ObjectC', 'go']
17 | };
18 |
19 | componentWillMount() {
20 | this.loadData();
21 | }
22 |
23 | componentDidMount() {
24 | this.initComment();
25 | }
26 |
27 | initComment() {
28 | let t = this,
29 | hash = window.location.hash;
30 |
31 | document.getElementById('SOHUCS').setAttribute('sid', hash.split('/')[hash.split('/').length - 1]);
32 |
33 | changyan.load();
34 |
35 | window.changyan.api.config({
36 | appid: 'cyt1S1w3M',
37 | conf: 'prod_73f06d34400f0e589effbae941fad7d8'
38 | });
39 | }
40 |
41 | loadData() {
42 | let t = this,
43 | id = '',
44 | hash = window.location.hash;
45 |
46 | id = hash.split('/')[hash.split('/').length - 1];
47 |
48 | window.scrollTo(0, 0);
49 |
50 | DataServicce.getArticleDetail({
51 | id: id
52 | }).then(function (data) {
53 | t.setState({
54 | articleObj: data
55 | });
56 | });
57 | }
58 |
59 | // componentWillReceiveProps() {
60 | // this.loadData();
61 | // }
62 |
63 | render() {
64 | return (
65 |
66 |
67 |
68 |
{this.state.articleObj.postTitle}
69 |
70 |
71 | {moment(this.state.articleObj.postDate).format('MMMM Do YYYY')}
72 |
73 |
74 |
76 |
77 |
78 |
79 |
80 |
81 | 标签
82 |
83 |
84 | {this.state.categorys.map(function (value, key) {
85 | return (
86 |
{value}
87 | );
88 | })}
89 |
90 |
91 |
92 |
94 |
95 |
96 | );
97 | }
98 | }
99 |
100 | export default ArticleDetail;
101 |
--------------------------------------------------------------------------------
/web/src/app/js/components/index/Laboratory.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/7/27.
3 | */
4 |
5 | import {Component} from 'react';
6 | import '../../../css/laboratory.less';
7 |
8 | class About extends Component {
9 | state = {
10 | laboratories: [{
11 | title: '胜率很高的五子棋',
12 | pic: './images/gomoku.jpg',
13 | discription: '纯js,利用五子棋核心算法,每一步棋计算当前和下一步共196种权重可能',
14 | url: 'http://3fuyu.com/laboratory/gomoku/index.html'
15 | }]
16 | }
17 |
18 | componentWillMount () {
19 | document.body.scrollTop = 0;
20 | }
21 | goto (url) {
22 | window.open(url);
23 | }
24 | render() {
25 | let t = this;
26 |
27 | return (
28 |
29 |
30 |
Laboratory
31 |
less but butter
32 |
33 |
34 | {this.state.laboratories.map(function (value, key) {
35 | return (
36 | - t.goto(value.url)}>
37 |
38 |
{value.title}
39 | {value.discription}
40 |
41 |
42 | );
43 | })}
44 |
45 |
46 | );
47 | }
48 | }
49 |
50 | export default About;
51 |
--------------------------------------------------------------------------------
/web/src/app/js/components/lib/Loading.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2016/11/3.
3 | */
4 |
5 | import {Component} from "react";
6 | import CircularProgress from "../../../../../node_modules/material-ui/CircularProgress";
7 |
8 | class Loading extends Component {
9 | render() {
10 | let style = _.extend({
11 | display: 'flex',
12 | justifyContent: 'center',
13 | flexDirection: 'column',
14 | alignItems: 'center',
15 | margin: '200px auto 800px'
16 | }, this.props.style);
17 |
18 | let contentStyle = {
19 | marginTop: '20px',
20 | color: '#1FBCD2',
21 | fontSie: '20px',
22 | fontWeight: 'bold'
23 | }
24 |
25 | return (
26 |
27 |
28 |
29 |
30 |
Loading...
31 |
32 | );
33 | }
34 | }
35 |
36 | export default Loading;
--------------------------------------------------------------------------------
/web/src/app/js/components/lib/upload.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/2/17.
3 | */
4 |
5 | var FILE = {
6 | fileInput: null, //html file控件
7 | dragDrop: null, //拖拽敏感区域
8 | upButton: null, //提交按钮
9 | url: "", //ajax地址
10 | fileFilter: [], //过滤后的文件数组
11 | filter: function (files) { //选择文件组的过滤方法
12 | return files;
13 | },
14 | onSelect: function () {}, //文件选择后
15 | onDelete: function () {}, //文件删除后
16 | onDragOver: function () {}, //文件拖拽到敏感区域时
17 | onDragLeave: function () {}, //文件离开到敏感区域时
18 | onProgress: function () {}, //文件上传进度
19 | onSuccess: function () {}, //文件上传成功时
20 | onFailure: function () {}, //文件上传失败时,
21 | onComplete: function () {}, //文件全部上传完毕时
22 |
23 | /* 开发参数和内置方法分界线 */
24 |
25 | //文件拖放
26 | funDragHover: function (e) {
27 | e.stopPropagation();
28 | e.preventDefault();
29 | this[e.type === "dragover" ? "onDragOver" : "onDragLeave"].call(e.target);
30 | return this;
31 | },
32 | //获取选择文件,file控件或拖放
33 | funGetFiles: function (e) {
34 | // 取消鼠标经过样式
35 | this.funDragHover(e);
36 |
37 | // 获取文件列表对象
38 | var files = e.target.files || e.dataTransfer.files;
39 | //继续添加文件
40 | this.fileFilter = this.fileFilter.concat(this.filter(files));
41 | this.funDealFiles();
42 | return this;
43 | },
44 |
45 | //选中文件的处理与回调
46 | funDealFiles: function () {
47 | for (var i = 0, file; file = this.fileFilter[i]; i++) {
48 | //增加唯一索引值
49 | file.index = i;
50 | }
51 | //执行选择回调
52 | this.onSelect(this.fileFilter);
53 | return this;
54 | },
55 |
56 | //删除对应的文件
57 | funDeleteFile: function (fileDelete) {
58 | var arrFile = [];
59 | for (var i = 0, file; file = this.fileFilter[i]; i++) {
60 | if (file != fileDelete) {
61 | arrFile.push(file);
62 | } else {
63 | this.onDelete(fileDelete);
64 | }
65 | }
66 | this.fileFilter = arrFile;
67 | return this;
68 | },
69 |
70 | //文件上传
71 | funUploadFile: function () {
72 | var self = this;
73 | if (location.host.indexOf("sitepointstatic") >= 0) {
74 | //非站点服务器上运行
75 | return;
76 | }
77 | for (var i = 0, file; file = this.fileFilter[i]; i++) {
78 | (function (file) {
79 | var xhr = new XMLHttpRequest();
80 | if (xhr.upload) {
81 | // 上传中
82 | xhr.upload.addEventListener("progress", function (e) {
83 | self.onProgress(file, e.loaded, e.total);
84 | }, false);
85 |
86 | // 文件上传成功或是失败
87 | xhr.onreadystatechange = function (e) {
88 | if (xhr.readyState == 4) {
89 | if (xhr.status == 200) {
90 | self.onSuccess(file, xhr.responseText);
91 | self.funDeleteFile(file);
92 | if (!self.fileFilter.length) {
93 | //全部完毕
94 | self.onComplete();
95 | }
96 | } else {
97 | self.onFailure(file, xhr.responseText);
98 | }
99 | }
100 | };
101 |
102 | // 开始上传
103 | xhr.open("POST", self.url, true);
104 | xhr.setRequestHeader("X_FILENAME", encodeURIComponent(file.name));
105 | xhr.send(file);
106 | }
107 | })(file);
108 | }
109 |
110 | },
111 |
112 | init: function () {
113 | var self = this;
114 |
115 | if (this.dragDrop) {
116 | this.dragDrop.addEventListener("dragover", function (e) { self.funDragHover(e); }, false);
117 | this.dragDrop.addEventListener("dragleave", function (e) { self.funDragHover(e); }, false);
118 | this.dragDrop.addEventListener("drop", function (e) { self.funGetFiles(e); }, false);
119 | }
120 |
121 | //文件选择控件选择
122 | if (this.fileInput) {
123 | this.fileInput.addEventListener("change", function (e) { self.funGetFiles(e); }, false);
124 | }
125 |
126 | //上传按钮提交
127 | if (this.upButton) {
128 | this.upButton.addEventListener("click", function (e) { self.funUploadFile(e); }, false);
129 | }
130 | }
131 | };
132 |
133 | module.exports = FILE;
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/web/src/app/js/components/management/AppNavDrawer.js:
--------------------------------------------------------------------------------
1 | import React, {Component, PropTypes} from 'react';
2 | import Drawer from '../../../../../node_modules/material-ui/Drawer';
3 | import {List, ListItem, MakeSelectable} from '../../../../../node_modules/material-ui/List';
4 | import {spacing, typography, zIndex} from '../../../../../node_modules/material-ui/styles';
5 | import {cyan500} from '../../../../../node_modules/material-ui/styles/colors';
6 | import DataService from '../../service/DataService';
7 |
8 | const SelectableList = MakeSelectable(List);
9 |
10 | const styles = {
11 | logo: {
12 | cursor: 'pointer',
13 | fontSize: 24,
14 | color: typography.textFullWhite,
15 | lineHeight: `${spacing.desktopKeylineIncrement}px`,
16 | fontWeight: typography.fontWeightLight,
17 | backgroundColor: cyan500,
18 | paddingLeft: spacing.desktopGutter,
19 | marginBottom: 8,
20 | },
21 | version: {
22 | paddingLeft: spacing.desktopGutterLess,
23 | fontSize: 16,
24 | },
25 | };
26 |
27 | class AppNavDrawer extends Component {
28 | static propTypes = {
29 | docked: PropTypes.bool.isRequired,
30 | location: PropTypes.object.isRequired,
31 | onChangeList: PropTypes.func.isRequired,
32 | onRequestChangeNavDrawer: PropTypes.func.isRequired,
33 | open: PropTypes.bool.isRequired,
34 | style: PropTypes.object,
35 | };
36 |
37 | static contextTypes = {
38 | muiTheme: PropTypes.object.isRequired,
39 | router: PropTypes.object.isRequired,
40 | };
41 |
42 | state = {
43 | muiVersions: [],
44 | leftOpen: true,
45 | login: '登出'
46 | };
47 |
48 | componentDidMount() {
49 | // DataService.getUserInfo({}).then(function (data) {
50 | // console.log(data);
51 | // });
52 | }
53 |
54 | onLogout() {
55 | DataService.logout({}).then(function (data) {
56 | window.location.href = '#/login';
57 | });
58 | }
59 |
60 | render() {
61 | const {
62 | location,
63 | docked,
64 | onRequestChangeNavDrawer,
65 | onChangeList,
66 | open,
67 | style,
68 | } = this.props;
69 |
70 | return (
71 |
78 |
79 | 3fuyu 管理后台
80 |
81 | {this.state.login}
82 |
83 |
84 |
88 | ,
97 |
102 | ]}
103 | />
104 |
111 |
117 |
124 |
125 |
126 | );
127 | }
128 | }
129 |
130 | export default AppNavDrawer;
131 |
--------------------------------------------------------------------------------
/web/src/app/js/components/management/ArticleCategory.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2016/11/15.
3 | */
4 |
5 | import {Component} from "react";
6 | import Avatar from "../../../../../node_modules/material-ui/Avatar";
7 | import Chip from "../../../../../node_modules/material-ui/Chip";
8 | import TextField from "../../../../../node_modules/material-ui/TextField";
9 | import "../../../css/articleCategory.less";
10 | import FYT from "../../service/FYToolService";
11 | import md5 from "md5";
12 | import DataService from "../../service/DataService";
13 |
14 | const styles = {
15 | chip: {
16 | margin: 4,
17 | color: '#fff'
18 | },
19 | wrapper: {
20 | display: 'flex',
21 | flexWrap: 'wrap',
22 | },
23 | labelColors: ['#3F53B1', '#2B98F0', '#1EBBD1', '#159487', '#663EB3', '#9A2EAD', '#E52464', '#F0443C']
24 | };
25 |
26 | class ArticleCategory extends Component {
27 | state = {
28 | data: [],
29 | nameErr: '',
30 | inputValue: ''
31 | };
32 |
33 | componentWillMount() {
34 | this.getTermsList();
35 | }
36 |
37 | getTermsList() {
38 | let t = this;
39 |
40 | DataService.adminQueryTermsList({}).then(function (data) {
41 | t.setState({
42 | data: data
43 | });
44 | });
45 | }
46 |
47 | handleRequestDelete(value) {
48 | let t = this,
49 | id = $(value.target).closest('.category-label-repeat').attr('data-id');
50 |
51 | DataService.adminDelTerm({
52 | id: id
53 | }).then(function (data) {
54 | FYT.tips('删除成功');
55 | t.getTermsList();
56 | });
57 | }
58 |
59 | handleTouchTap() {
60 | console.log('tap');
61 | }
62 |
63 | submitCategory(_event) {
64 | let t = this;
65 | let event = _.cloneDeep(_event);
66 |
67 | if (event.charCode === 13) {
68 | let value = event.target.value;
69 |
70 | if (value) {
71 | this.setState({
72 | nameErr: ''
73 | });
74 |
75 | DataService.adminTermsNew({
76 | name: value
77 | }).then(function (data) {
78 | FYT.tips('新建成功');
79 | $(event.target).val('');
80 | $(event.target).blur();
81 |
82 | t.getTermsList();
83 | });
84 | } else {
85 | this.setState({
86 | nameErr: '分类不能为空'
87 | });
88 | }
89 | }
90 | }
91 |
92 | render() {
93 | let t = this;
94 |
95 | return (
96 |
97 |
98 | this.submitCategory(event)}
101 | errorText={this.state.nameErr}
102 | />
103 |
104 |
105 |
106 |
107 |
108 | {this.state.data.map(function (value, key) {
109 | return (
110 |
t.handleRequestDelete(value)}>
120 | {value.name.substring(0, 1).toLocaleUpperCase()}
128 |
129 | {value.name}
130 |
131 | );
132 | })}
133 |
134 |
135 |
136 |
137 | );
138 | }
139 | }
140 |
141 | export default ArticleCategory;
--------------------------------------------------------------------------------
/web/src/app/js/components/management/ArticleList.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/10/11.
3 | */
4 |
5 | import {Component, PropTypes} from 'react';
6 | import {
7 | Table,
8 | TableBody,
9 | TableHeader,
10 | TableHeaderColumn,
11 | TableRow,
12 | TableRowColumn
13 | } from '../../../../../node_modules/material-ui/Table';
14 | import FlatButton from '../../../../../node_modules/material-ui/FlatButton';
15 | import '../../../css/main.less';
16 | import '../../../css/articleList.less';
17 | import DataService from '../../service/DataService';
18 | import moment from 'moment';
19 | import Tools from '../../service/FYToolService';
20 |
21 | class ArticleList extends Component {
22 | constructor(props) {
23 | super(props);
24 |
25 | this.state = {
26 | fixedHeader: false,
27 | fixedFooter: false,
28 | stripedRows: false,
29 | showRowHover: true,
30 | selectable: true,
31 | multiSelectable: true,
32 | enableSelectAll: true,
33 | deselectOnClickaway: true,
34 | showCheckboxes: true,
35 | tableData: []
36 | };
37 | }
38 |
39 | static contextTypes = {
40 | router: PropTypes.object.isRequired,
41 | };
42 |
43 | componentWillMount() {
44 | this.renderList();
45 | }
46 |
47 | renderList() {
48 | let t = this;
49 |
50 | DataService.adminQueryArticleList().then(function (data) {
51 | t.setState({
52 | tableData: data
53 | });
54 | });
55 | }
56 |
57 | delArticle(row) {
58 | let t = this;
59 |
60 | if (!row.id) return;
61 |
62 | Tools.confirm('删除确认', '确认删除该文章吗?', function () {
63 | DataService.adminDelArticle({
64 | id: row.id
65 | }).then(function (data) {
66 | Tools.tips('删除成功');
67 | t.renderList();
68 | });
69 | });
70 | }
71 |
72 | editArticle(row) {
73 | let t = this;
74 | if (!row.id) return;
75 |
76 | t.context.router.push('/management/new-article/' + row.id);
77 | }
78 |
79 | render() {
80 | return (
81 |
82 |
88 |
89 |
90 | ID
91 | 文章标题
92 | 时间
93 | 分类
94 | 操作
95 |
96 |
97 |
103 | {this.state.tableData.map((row, index) => (
104 |
105 | {row.id}
106 | {row.postTitle}
107 | {moment(row.postDate).format('YYYY-MM-DD hh:mm')}
108 | {row.postCategoryName}
109 |
110 | this.delArticle(row)}/>
111 | this.editArticle(row)} />
112 |
113 |
114 | ))}
115 |
116 |
117 |
118 | );
119 | }
120 | }
121 |
122 | export default ArticleList;
--------------------------------------------------------------------------------
/web/src/app/js/components/management/FullWidthSection.js:
--------------------------------------------------------------------------------
1 | import React, {Component, PropTypes} from 'react';
2 | import ClearFix from '../../../../../node_modules/material-ui/internal/ClearFix';
3 | import spacing from '../../../../../node_modules/material-ui/styles/spacing';
4 | import withWidth, {SMALL, LARGE} from '../../../../../node_modules/material-ui/utils/withWidth';
5 |
6 | const desktopGutter = spacing.desktopGutter;
7 |
8 | class FullWidthSection extends Component {
9 |
10 | static propTypes = {
11 | children: PropTypes.node,
12 | contentStyle: PropTypes.object,
13 | contentType: PropTypes.string,
14 | style: PropTypes.object,
15 | useContent: PropTypes.bool,
16 | width: PropTypes.number.isRequired,
17 | };
18 |
19 | static defaultProps = {
20 | useContent: false,
21 | contentType: 'div',
22 | };
23 |
24 | getStyles() {
25 | return {
26 | root: {
27 | padding: desktopGutter,
28 | boxSizing: 'border-box',
29 | },
30 | content: {
31 | maxWidth: 1200,
32 | margin: '0 auto',
33 | },
34 | rootWhenSmall: {
35 | paddingTop: desktopGutter * 2,
36 | paddingBottom: desktopGutter * 2,
37 | },
38 | rootWhenLarge: {
39 | paddingTop: desktopGutter * 3,
40 | paddingBottom: desktopGutter * 3,
41 | },
42 | };
43 | }
44 |
45 | render() {
46 | const {
47 | style,
48 | useContent,
49 | contentType,
50 | contentStyle,
51 | width,
52 | ...other,
53 | } = this.props;
54 |
55 | const styles = this.getStyles();
56 |
57 | let content;
58 | if (useContent) {
59 | content =
60 | React.createElement(
61 | contentType,
62 | {style: Object.assign(styles.content, contentStyle)},
63 | this.props.children
64 | );
65 | } else {
66 | content = this.props.children;
67 | }
68 |
69 | return (
70 |
79 | {content}
80 |
81 | );
82 | }
83 | }
84 |
85 | export default withWidth()(FullWidthSection);
86 |
--------------------------------------------------------------------------------
/web/src/app/js/components/management/Login.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | import React, {Component, PropTypes} from 'react';
4 | import TextField from '../../../../../node_modules/material-ui/TextField';
5 | import DataService from '../../service/DataService';
6 | import FYT from '../../service/FYToolService';
7 | import { Navigation } from "react-router";
8 | import '../../../css/login.less';
9 |
10 | class Login extends React.Component {
11 | static contextTypes = {
12 | router: PropTypes.object.isRequired
13 | };
14 |
15 | state = {
16 | name: '',
17 | password: '',
18 | loginStyle: {
19 | color: '#bbb'
20 | },
21 | nameErr: '',
22 | passwordErr: ''
23 | };
24 |
25 | handleChange(event) {
26 | let t = this;
27 |
28 | if (event.target.id === 'login-name') {
29 | this.setState({
30 | name: event.target.value
31 | });
32 | } else if (event.target.id === 'login-password') {
33 | this.setState({
34 | password: event.target.value
35 | });
36 | }
37 |
38 | setTimeout(function () {
39 | if (t.state.name && t.state.password) {
40 | t.setState({
41 | loginStyle: {
42 | color: '#ff4081'
43 | }
44 | });
45 | } else {
46 | t.setState({
47 | loginStyle: {
48 | color: '#bbb'
49 | }
50 | });
51 | }
52 | }, 0);
53 | }
54 |
55 | onLogin() {
56 | let t = this;
57 |
58 | t.state.name ? t.setState({nameErr: ''}) : t.setState({nameErr: '请输入用户名'});
59 | t.state.password ? t.setState({passwordErr: ''}) : t.setState({passwordErr: '请输入密码'});
60 |
61 | if (t.state.name && t.state.password) {
62 | DataService.login({
63 | name: t.state.name,
64 | password: t.state.password
65 | }).then(function (data) {
66 | FYT.tips('登录成功!');
67 | window.location.href = '#/management/article-list';
68 | }, function (data) {
69 | if (data.errorCode === 401) {
70 | FYT.tips(data.errorDescription);
71 | } else {
72 | throw (data.errorDescription);
73 | }
74 | });
75 | }
76 | }
77 | listenKeyPress(e) {
78 | if (e.nativeEvent.keyCode === 13) {
79 | this.onLogin();
80 | }
81 | }
82 |
83 | render() {
84 | return (
85 | this.listenKeyPress(e)}>
86 |
87 | 3fuyu's blog
88 |
89 |
90 |
this.handleChange(event)} />
98 |
99 | this.onLogin()} style={this.state.loginStyle}>
100 |
101 |
102 |
103 | this.handleChange(event)}/>
112 |
113 |
114 | );
115 | }
116 | }
117 | //
118 | // Login.contextTypes = {
119 | // router: React.PropTypes.func.isRequired
120 | // }
121 |
122 | export default Login;
--------------------------------------------------------------------------------
/web/src/app/js/components/management/MarkdownElement.js:
--------------------------------------------------------------------------------
1 | import React, {Component, PropTypes} from 'react';
2 | import marked from 'marked';
3 |
4 | require('./mui-github-markdown.css');
5 |
6 | const styles = {
7 | root: {
8 | marginTop: 20,
9 | marginBottom: 20,
10 | padding: '0 10px',
11 | },
12 | };
13 |
14 | class MarkdownElement extends Component {
15 |
16 | static propTypes = {
17 | style: PropTypes.object,
18 | text: PropTypes.string.isRequired,
19 | };
20 |
21 | static defaultProps = {
22 | text: '',
23 | };
24 |
25 | componentWillMount() {
26 | marked.setOptions({
27 | gfm: true,
28 | tables: true,
29 | breaks: false,
30 | pedantic: false,
31 | sanitize: false,
32 | smartLists: true,
33 | smartypants: false,
34 | highlight: function(code, lang) {
35 | return require('highlight.js').highlight(lang, code).value;
36 | },
37 | });
38 | }
39 |
40 | render() {
41 | const {
42 | style,
43 | text,
44 | } = this.props;
45 |
46 | /* eslint-disable react/no-danger */
47 | return (
48 |
53 | );
54 | /* eslint-enable */
55 | }
56 | }
57 |
58 | export default MarkdownElement;
59 |
--------------------------------------------------------------------------------
/web/src/app/js/components/management/NewArticle.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/10/5.
3 | */
4 |
5 | import React, {Component, PropTypes} from "react";
6 | import ReactDOM from "react-dom";
7 | import TextField from "../../../../../node_modules/material-ui/TextField";
8 | import FloatingActionButton from "../../../../../node_modules/material-ui/FloatingActionButton";
9 | import ContentAdd from "../../../../../node_modules/material-ui/svg-icons/content/add";
10 | import AutoComplete from "../../../../../node_modules/material-ui/AutoComplete";
11 | import DatePicker from "../../../../../node_modules/material-ui/DatePicker";
12 | import moment from "moment";
13 | import "../../../css/newArticle.less";
14 | import DataService from "../../service/DataService";
15 | import Util from "../../service/FYToolService";
16 |
17 | const dataSourceConfig = {
18 | text: 'name',
19 | value: 'id'
20 | };
21 |
22 | let categoryObj = {};
23 |
24 | class NewArticle extends Component {
25 | state = {
26 | title: '',
27 | date: new Date(),
28 | dataSource: [],
29 | content: ''
30 | };
31 |
32 | static contextTypes = {
33 | muiTheme: PropTypes.object.isRequired,
34 | router: PropTypes.object.isRequired
35 | };
36 |
37 | getDate() {
38 | let date = new Date(this.state.date || '');
39 |
40 | return moment(date).format('YYYY-MM-DD');
41 | }
42 |
43 | componentDidMount() {
44 | let target = ReactDOM.findDOMNode(document.getElementById('article-editor')),
45 | parentTitle = ReactDOM.findDOMNode(document.getElementsByClassName('article-title')[0]),
46 | parentDate = ReactDOM.findDOMNode(document.getElementsByClassName('article-date')[0]),
47 | parentCategory = ReactDOM.findDOMNode(document.getElementsByClassName('article-category')[0]);
48 |
49 | target.addEventListener('scroll', function () {
50 | let scrollTop = this.scrollTop;
51 |
52 | if (scrollTop < 20) {
53 | $(parentTitle).fadeIn(100);
54 | $(parentDate).fadeIn(100);
55 | $(parentCategory).fadeIn(100);
56 | } else {
57 | $(parentTitle).fadeOut(100);
58 | $(parentDate).fadeOut(100);
59 | $(parentCategory).fadeOut(100);
60 | }
61 | });
62 | }
63 |
64 | componentWillMount() {
65 | let type = this.props.params.type,
66 | t = this;
67 |
68 | if (type && type !== 'new') {
69 | DataService.adminGetArticle({
70 | id: type
71 | }).then(function (suc) {
72 | let data = suc[0];
73 | t.setState({
74 | content: data.postContent,
75 | date: data.postDate,
76 | title: data.postTitle
77 | });
78 | });
79 | }
80 |
81 | this.getCategoryList();
82 | }
83 |
84 | getCategoryList() {
85 | var t = this;
86 |
87 | DataService.adminQueryTermsList({}).then(function (data) {
88 | t.setState({
89 | dataSource: data
90 | });
91 | });
92 | }
93 |
94 | submit() {
95 | const t = this,
96 | type = this.props.params.type;
97 |
98 | if (type === 'new') {
99 | DataService.adminPostNew({
100 | title: t.state.title,
101 | content: t.refs.articleContent.value,
102 | categoryId: categoryObj.id,
103 | categoryName: categoryObj.name,
104 | date: +new Date(t.state.date)
105 | }).then(function (data) {
106 | Util.tips('发布成功');
107 | t.context.router.push('/management/article-list');
108 | });
109 | } else {
110 | DataService.adminPostUpdate({
111 | id: this.props.params.type,
112 | title: t.state.title,
113 | content: t.refs.articleContent.value,
114 | categoryId: categoryObj.id,
115 | categoryName: categoryObj.name,
116 | date: +new Date(t.state.date)
117 | }).then(function (data) {
118 | Util.tips('发布成功');
119 | t.context.router.push('/management/article-list');
120 | });
121 | }
122 | }
123 |
124 | titleChange(e) {
125 | this.setState({
126 | title: e.target.value
127 | });
128 | }
129 |
130 | contentChange(e) {
131 | this.setState({
132 | content: e.target.value
133 | })
134 | }
135 |
136 | dateChange(event, date) {
137 | this.setState({
138 | date: date
139 | });
140 | }
141 |
142 | handleUpdateInput(value) {
143 | // console.log(value);
144 | }
145 |
146 | selectedCategory(value) {
147 | categoryObj = value;
148 | }
149 |
150 | render() {
151 | var t = this,
152 | date = this.getDate();
153 |
154 | return (
155 |
156 |
this.titleChange(event)}
162 | />
163 |
164 | Date: {date}
165 |
166 | this.selectedCategory(value)}
174 | onUpdateInput={(value) => this.handleUpdateInput(value)}
175 | />
176 |
177 |
178 |
179 | this.submit()}>
180 |
181 |
182 |
183 | );
184 | }
185 | }
186 |
187 | export default NewArticle;
--------------------------------------------------------------------------------
/web/src/app/js/lib/ZeroClipboard.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/js/lib/ZeroClipboard.swf
--------------------------------------------------------------------------------
/web/src/app/js/lib/changyan.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/5/26.
3 | */
4 | define([], function () {
5 | //畅言滤重
6 | if (window.changyan !== undefined || window.cyan !== undefined) {
7 | return;
8 | }
9 | var createNs = function () {
10 | if (window.changyan !== undefined) {
11 | return;
12 | } else {
13 | window.changyan = {};
14 | window.changyan.api = {};
15 | window.changyan.api.config = function (conf) {
16 | window.changyan.api.tmpIsvPageConfig = conf;
17 | };
18 | window.changyan.api.ready = function (fn) {
19 | window.changyan.api.tmpHandles = window.changyan.api.tmpHandles || [];
20 | window.changyan.api.tmpHandles.push(fn);
21 | };
22 | window.changyan.ready = function (fn) {
23 | if (window.changyan.rendered) {
24 | fn && fn();
25 | } else {
26 | window.changyan.tmpHandles = window.changyan.tmpHandles || [];
27 | window.changyan.tmpHandles.push(fn);
28 | }
29 | }
30 | }
31 | };
32 |
33 | var createMobileNs = function () {
34 | if (window.cyan) {
35 | return;
36 | }
37 |
38 | window.cyan = {};
39 | window.cyan.api = {};
40 | window.cyan.api.ready = function (fn) {
41 | window.cyan.api.tmpHandles = window.cyan.api.tmpHandles || [];
42 | window.cyan.api.tmpHandles.push(fn);
43 | };
44 | };
45 |
46 |
47 | var loadVersionJs = function () {
48 | var loadJs = function (src, fun) {
49 | var head = document.getElementsByTagName('head')[0] || document.head || document.documentElement;
50 |
51 | var script = document.createElement('script');
52 | script.setAttribute('type', 'text/javascript');
53 | script.setAttribute('charset', 'UTF-8');
54 | script.setAttribute('src', src);
55 |
56 | if (typeof fun === 'function') {
57 | if (window.attachEvent) {
58 | script.onreadystatechange = function () {
59 | var r = script.readyState;
60 | if (r === 'loaded' || r === 'complete') {
61 | script.onreadystatechange = null;
62 | fun();
63 | }
64 | };
65 | } else {
66 | script.onload = fun;
67 | }
68 | }
69 |
70 | head.appendChild(script);
71 | };
72 |
73 | var ver = +new Date() + window.Math.random().toFixed(16);
74 | var protocol = (('https:' == window.document.location.protocol) ? "https://" : "http://");
75 | var url = protocol + 'changyan.itc.cn/upload/version-v3.js?' + ver;
76 | loadJs(url);
77 | };
78 |
79 | return {
80 | load: function () {
81 | createNs();
82 | createMobileNs();
83 | loadVersionJs();
84 | }
85 | };
86 | });
87 |
88 |
--------------------------------------------------------------------------------
/web/src/app/js/reducers/reducers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/9/14.
3 | */
4 | "use strict";
5 |
6 | import { combineReducers } from 'redux';
7 | import todos from './todos';
8 |
9 | const blog = combineReducers({
10 | todos
11 | });
12 |
13 | export default blog;
--------------------------------------------------------------------------------
/web/src/app/js/reducers/todos.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/9/14.
3 | */
4 | "use strict";
5 |
6 | import { ADD_TODO, COMPLETE_TODO } from '../actions/actions';
7 |
8 |
9 | function todos(state = [], action) {
10 | switch (action.type) {
11 | case ADD_TODO:
12 | return [
13 | ...state,
14 | {
15 | text: action.text,
16 | completed: false
17 | }
18 | ];
19 | case COMPLETE_TODO:
20 | return [
21 | ...state.slice(0, action.index),
22 | Object.assign({}, state[action.index], {
23 | completed: true
24 | }),
25 | ...state.slice(action.index + 1)
26 | ];
27 | default:
28 | return state;
29 | }
30 | }
31 |
32 | export default todos;
--------------------------------------------------------------------------------
/web/src/app/js/service/CacheService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/03/10.
3 | */
4 | "use strict";
5 |
6 | var _ = require('lodash');
7 |
8 | var CacheService = {};
9 |
10 | var Params = {
11 | SelectAddress: null,
12 | AllAddress: null,
13 | SelectBill: null
14 | };
15 |
16 | _.each(Params, function (value, key) {
17 | CacheService[key] = {
18 | get: function () {
19 | return Params[key];
20 | },
21 | set: function (_value) {
22 | Params[key] = _value;
23 | },
24 | getReset: function () {
25 | var _cookie = Params[key];
26 | Params[key] = null;
27 | return _cookie;
28 | }
29 | };
30 | });
31 |
32 | module.exports = CacheService;
33 |
--------------------------------------------------------------------------------
/web/src/app/js/service/EnumService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/03/17.
3 | */
4 |
5 | var ENUM = {};
6 |
7 | ENUM.TaskStatus = {
8 | 0: '无',
9 | 1: '待执行',
10 | 2: '整改中',
11 | 3: '整改完成待核查',
12 | 4: '整改关闭待核查',
13 | 5: '关闭'
14 | };
15 |
16 | ENUM.TaskResult = {
17 | 0: '无',
18 | 1: '核查完成',
19 | 2: '核查关闭',
20 | 3: '整改完成',
21 | 4: '整改关闭',
22 | 5: '核查延误',
23 | 6: '复查延误',
24 | 7: '整改延误'
25 | };
26 |
27 | ENUM.TaskProcessResult = {
28 | 0: '无',
29 | 1: '整改中',
30 | 2: '整改关闭',
31 | 3: '整改合格',
32 | 4: '整改延误'
33 | };
34 |
35 | module.exports = ENUM;
--------------------------------------------------------------------------------
/web/src/app/js/service/RouterService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/03/11.
3 | */
4 |
5 | var RouterService = {};
6 |
7 | //RouterService.config = {
8 | // main: {
9 | // url: '/',
10 | // name:
11 | // }
12 | //};
--------------------------------------------------------------------------------
/web/src/app/js/service/StorageService.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 16/03/10.
3 | */
4 | "use strict";
5 |
6 | var Storage = require('store');
7 | var _ = require('lodash');
8 |
9 | var StorageService = {};
10 |
11 | var Params = {
12 | TASK_LIST_DATA: null,
13 | GROUP_USERS: null,
14 | DRAFTS_BOX: null,
15 | SIGNATURE: null
16 | };
17 |
18 | _.each(Params, function (value, key) {
19 | StorageService[key] = {
20 | set: function (value) {
21 | Storage.set(key, value);
22 | },
23 | get: function () {
24 | return Storage.get(key);
25 | },
26 | getReset: function () {
27 | var _value = Storage.get(key);
28 | Storage.remove(key);
29 | return _value;
30 | },
31 | clear: function () {
32 | Storage.remove(key);
33 | },
34 | clearAll: function () {
35 | Storage.clear();
36 | },
37 | has: function () {
38 | return Storage.has(key);
39 | }
40 | };
41 | });
42 |
43 | module.exports = StorageService;
--------------------------------------------------------------------------------
/web/src/app/js/upload.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 3fuyu on 2017/2/17.
3 | */
4 |
5 | var FILE = {
6 | fileInput: null, //html file控件
7 | dragDrop: null, //拖拽敏感区域
8 | upButton: null, //提交按钮
9 | url: "", //ajax地址
10 | fileFilter: [], //过滤后的文件数组
11 | filter: function (files) { //选择文件组的过滤方法
12 | return files;
13 | },
14 | onSelect: function () {}, //文件选择后
15 | onDelete: function () {}, //文件删除后
16 | onDragOver: function () {}, //文件拖拽到敏感区域时
17 | onDragLeave: function () {}, //文件离开到敏感区域时
18 | onProgress: function () {}, //文件上传进度
19 | onSuccess: function () {}, //文件上传成功时
20 | onFailure: function () {}, //文件上传失败时,
21 | onComplete: function () {}, //文件全部上传完毕时
22 |
23 | /* 开发参数和内置方法分界线 */
24 |
25 | //文件拖放
26 | funDragHover: function (e) {
27 | e.stopPropagation();
28 | e.preventDefault();
29 | this[e.type === "dragover" ? "onDragOver" : "onDragLeave"].call(e.target);
30 | return this;
31 | },
32 | //获取选择文件,file控件或拖放
33 | funGetFiles: function (e) {
34 | // 取消鼠标经过样式
35 | this.funDragHover(e);
36 |
37 | // 获取文件列表对象
38 | var files = e.target.files || e.dataTransfer.files;
39 | //继续添加文件
40 | this.fileFilter = this.fileFilter.concat(this.filter(files));
41 | this.funDealFiles();
42 | return this;
43 | },
44 |
45 | //选中文件的处理与回调
46 | funDealFiles: function () {
47 | for (var i = 0, file; file = this.fileFilter[i]; i++) {
48 | //增加唯一索引值
49 | file.index = i;
50 | }
51 | //执行选择回调
52 | this.onSelect(this.fileFilter);
53 | return this;
54 | },
55 |
56 | //删除对应的文件
57 | funDeleteFile: function (fileDelete) {
58 | var arrFile = [];
59 | for (var i = 0, file; file = this.fileFilter[i]; i++) {
60 | if (file != fileDelete) {
61 | arrFile.push(file);
62 | } else {
63 | this.onDelete(fileDelete);
64 | }
65 | }
66 | this.fileFilter = arrFile;
67 | return this;
68 | },
69 |
70 | //文件上传
71 | funUploadFile: function () {
72 | var self = this;
73 | if (location.host.indexOf("sitepointstatic") >= 0) {
74 | //非站点服务器上运行
75 | return;
76 | }
77 | for (var i = 0, file; file = this.fileFilter[i]; i++) {
78 | (function (file) {
79 | var xhr = new XMLHttpRequest();
80 | if (xhr.upload) {
81 | // 上传中
82 | xhr.upload.addEventListener("progress", function (e) {
83 | self.onProgress(file, e.loaded, e.total);
84 | }, false);
85 |
86 | // 文件上传成功或是失败
87 | xhr.onreadystatechange = function (e) {
88 | if (xhr.readyState == 4) {
89 | if (xhr.status == 200) {
90 | self.onSuccess(file, xhr.responseText);
91 | self.funDeleteFile(file);
92 | if (!self.fileFilter.length) {
93 | //全部完毕
94 | self.onComplete();
95 | }
96 | } else {
97 | self.onFailure(file, xhr.responseText);
98 | }
99 | }
100 | };
101 |
102 | // 开始上传
103 | xhr.open("POST", self.url, true);
104 | xhr.setRequestHeader("X_FILENAME", encodeURIComponent(file.name));
105 | xhr.send(file);
106 | }
107 | })(file);
108 | }
109 |
110 | },
111 |
112 | init: function () {
113 | var self = this;
114 |
115 | if (this.dragDrop) {
116 | this.dragDrop.addEventListener("dragover", function (e) { self.funDragHover(e); }, false);
117 | this.dragDrop.addEventListener("dragleave", function (e) { self.funDragHover(e); }, false);
118 | this.dragDrop.addEventListener("drop", function (e) { self.funGetFiles(e); }, false);
119 | }
120 |
121 | //文件选择控件选择
122 | if (this.fileInput) {
123 | this.fileInput.addEventListener("change", function (e) { self.funGetFiles(e); }, false);
124 | }
125 |
126 | //上传按钮提交
127 | if (this.upButton) {
128 | this.upButton.addEventListener("click", function (e) { self.funUploadFile(e); }, false);
129 | }
130 | }
131 | };
--------------------------------------------------------------------------------
/web/src/app/laboratory/gomoku/index.css:
--------------------------------------------------------------------------------
1 | .main-content {
2 | position: relative;
3 | background-image: url(./wood.jpg);
4 | background-repeat: no-repeat;
5 | background-size: 700px;
6 | margin: 0 auto;
7 | height: 100%;
8 | box-shadow: 0px 0px 10px #000;
9 | }
10 |
11 | .options {
12 | position: absolute;
13 | top: 80px;
14 | right: 50px;
15 | }
16 |
17 | .options div {
18 | width: 150px;
19 | height: 40px;
20 | font-size: 16px;
21 | border-radius: 10px;
22 | cursor: pointer;
23 | box-shadow: 0 1px 1px #333;
24 | line-height: 40px;
25 | text-align: center;
26 | }
27 |
28 | .board-content {
29 | font-size: 0;
30 | width: 600px;
31 | margin-left: 50px;
32 | padding: 55px;
33 | }
34 |
35 | .board-item {
36 | display: inline-block;
37 | width: 40px;
38 | height: 40px;
39 | position: relative;
40 | }
41 |
42 | .row {
43 | position: absolute;
44 | height: 1px;
45 | width: 100%;
46 | content: ' ';
47 | background-color: #444;
48 | top: 20px;
49 | }
50 |
51 | .column {
52 | position: absolute;
53 | width: 1px;
54 | height: 100%;
55 | content: ' ';
56 | background-color: #444;
57 | left: 19px;
58 | }
59 |
60 | .row-left-top {
61 | position: absolute;
62 | width: 2px;
63 | height: 50%;
64 | content: ' ';
65 | background-color: #444;
66 | left: 20px;
67 | top: 20px;
68 | }
69 |
70 | .column-left-top {
71 | position: absolute;
72 | height: 2px;
73 | width: 50%;
74 | content: ' ';
75 | background-color: #444;
76 | left: 20px;
77 | top: 20px;
78 | }
79 |
80 | .row-right-top {
81 | position: absolute;
82 | width: 2px;
83 | height: 50%;
84 | content: ' ';
85 | background-color: #444;
86 | right: 20px;
87 | top: 20px;
88 | }
89 |
90 | .column-right-top {
91 | position: absolute;
92 | height: 2px;
93 | width: 50%;
94 | content: ' ';
95 | background-color: #444;
96 | right: 20px;
97 | top: 20px;
98 | }
99 |
100 | .row-left-bottom {
101 | position: absolute;
102 | width: 2px;
103 | height: 50%;
104 | content: ' ';
105 | background-color: #444;
106 | left: 20px;
107 | bottom: 20px;
108 | }
109 |
110 | .column-left-bottom {
111 | position: absolute;
112 | height: 2px;
113 | width: 50%;
114 | content: ' ';
115 | background-color: #444;
116 | left: 20px;
117 | bottom: 20px;
118 | }
119 |
120 | .row-right-bottom {
121 | position: absolute;
122 | width: 2px;
123 | height: 50%;
124 | content: ' ';
125 | background-color: #444;
126 | right: 20px;
127 | bottom: 20px;
128 | }
129 |
130 | .column-right-bottom {
131 | position: absolute;
132 | height: 2px;
133 | width: 50%;
134 | content: ' ';
135 | background-color: #444;
136 | right: 20px;
137 | bottom: 20px;
138 | }
139 |
140 | .row-top {
141 | position: absolute;
142 | height: 2px;
143 | width: 100%;
144 | content: ' ';
145 | background-color: #444;
146 | top: 20px;
147 | }
148 |
149 | .column-top {
150 | position: absolute;
151 | width: 1px;
152 | height: 50%;
153 | content: ' ';
154 | background-color: #444;
155 | top: 20px;
156 | left: 19px;
157 | }
158 |
159 | .row-bottom {
160 | position: absolute;
161 | height: 2px;
162 | width: 100%;
163 | content: ' ';
164 | background-color: #444;
165 | bottom: 20px;
166 | }
167 |
168 | .column-bottom {
169 | position: absolute;
170 | width: 1px;
171 | height: 50%;
172 | content: ' ';
173 | background-color: #444;
174 | bottom: 20px;
175 | left: 19px;
176 | }
177 |
178 | .row-left {
179 | position: absolute;
180 | height: 1px;
181 | width: 50%;
182 | content: ' ';
183 | background-color: #444;
184 | left: 20px;
185 | top: 20px;
186 | }
187 |
188 | .column-left {
189 | position: absolute;
190 | width: 2px;
191 | height: 100%;
192 | content: ' ';
193 | background-color: #444;
194 | left: 20px;
195 | }
196 |
197 | .row-right {
198 | position: absolute;
199 | height: 1px;
200 | width: 50%;
201 | content: ' ';
202 | background-color: #444;
203 | right: 20px;
204 | top: 20px;
205 | }
206 |
207 | .column-right {
208 | position: absolute;
209 | width: 2px;
210 | height: 100%;
211 | content: ' ';
212 | background-color: #444;
213 | right: 20px;
214 | }
215 |
216 | .black:before {
217 | position: absolute;
218 | width: 100%;
219 | height: 100%;
220 | border-radius: 1000px;
221 | content: ' ';
222 | z-index: 1;
223 | background: -webkit-radial-gradient(30% 25%, circle closest-corner, #777, #222);
224 | background: -moz-radial-gradient(30% 25%, circle closest-corner, #777, #222);
225 | background: -o-radial-gradient(30% 25%, circle closest-corner, #777, #222);
226 | background: -ms-radial-gradient(30% 25%, circle closest-corner, #777, #222);
227 | background: radial-gradient(30% 25%, circle closest-corner, #777, #222);
228 | -webkit-box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 10, .4), 0 0 2px rgba(0, 0, 0, .5);
229 | box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 10, .4), 0 0 2px rgba(0, 0, 0, .5);
230 | -webkit-transform: scale(.9);
231 | -moz-transform: scale(.9);
232 | -o-transform: scale(.9);
233 | -ms-transform: scale(.9);
234 | transform: scale(.9);
235 | }
236 |
237 | .white:before {
238 | position: absolute;
239 | width: 100%;
240 | height: 100%;
241 | border-radius: 1000px;
242 | content: ' ';
243 | z-index: 1;
244 | background: -webkit-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
245 | background: -moz-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
246 | background: -o-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
247 | background: -ms-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
248 | background: radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
249 | -webkit-box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 100, .4), 0 0 2px rgba(0, 0, 0, .5);
250 | box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 100, .4), 0 0 2px rgba(0, 0, 0, .5);
251 | -webkit-transform: scale(.9);
252 | -moz-transform: scale(.9);
253 | -o-transform: scale(.9);
254 | -ms-transform: scale(.9);
255 | transform: scale(.9);
256 | }
257 |
258 | .options > div {
259 | border: 1px solid #c27426;
260 | background: #c27426;
261 | font-weight: 700;
262 | color: #fff;
263 | text-shadow: 0 1px 1px #444;
264 | background-image: -webkit-gradient(linear, left top, left bottom, from(#D57F29), to(#AE6822));
265 | background-image: -webkit-linear-gradient(#D57F29, #AE6822);
266 | background-image: -moz-linear-gradient(#D57F29, #AE6822);
267 | background-image: -ms-linear-gradient(#D57F29, #AE6822);
268 | background-image: -o-linear-gradient(#D57F29, #AE6822);
269 | background-image: linear-gradient(#D57F29, #AE6822);
270 | margin-bottom: 30px;
271 | }
--------------------------------------------------------------------------------
/web/src/app/laboratory/gomoku/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gomoku
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
人机
13 |
重新开始
14 |
悔棋
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/web/src/app/laboratory/gomoku/wood.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/app/laboratory/gomoku/wood.jpg
--------------------------------------------------------------------------------
/web/src/www/css/font-icons/fonts/material-ui-icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/css/font-icons/fonts/material-ui-icons.eot
--------------------------------------------------------------------------------
/web/src/www/css/font-icons/fonts/material-ui-icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/web/src/www/css/font-icons/fonts/material-ui-icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/css/font-icons/fonts/material-ui-icons.ttf
--------------------------------------------------------------------------------
/web/src/www/css/font-icons/fonts/material-ui-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/css/font-icons/fonts/material-ui-icons.woff
--------------------------------------------------------------------------------
/web/src/www/css/font-icons/style.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'material-ui-icons';
3 | src: url('fonts/material-ui-icons.eot');
4 | }
5 | @font-face {
6 | font-family: 'material-ui-icons';
7 | src: url(data:application/x-font-ttf;charset=utf-8;base64,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) format('truetype'),
8 | url(data:application/font-woff;charset=utf-8;base64,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) format('woff');
9 | font-weight: normal;
10 | font-style: normal;
11 | }
12 |
13 | [class^="muidocs-icon-"], [class*=" muidocs-icon-"] {
14 | font-family: 'material-ui-icons';
15 | speak: none;
16 | font-style: normal;
17 | font-weight: normal;
18 | font-variant: normal;
19 | text-transform: none;
20 | line-height: 1;
21 |
22 | /* Better Font Rendering =========== */
23 | -webkit-font-smoothing: antialiased;
24 | -moz-osx-font-smoothing: grayscale;
25 | }
26 |
27 | .muidocs-icon-communication-phone:before {
28 | content: "\e601";
29 | }
30 |
31 | .muidocs-icon-communication-voicemail:before {
32 | content: "\e602";
33 | }
34 |
35 | .muidocs-icon-navigation-expand-more:before {
36 | content: "\e603";
37 | }
38 |
39 | .muidocs-icon-action-grade:before {
40 | content: "\e604";
41 | }
42 |
43 | .muidocs-icon-action-home:before {
44 | content: "\e605";
45 | }
46 |
47 | .muidocs-icon-action-stars:before {
48 | content: "\e606";
49 | }
50 |
51 | .muidocs-icon-action-thumb-up:before {
52 | content: "\e607";
53 | }
54 |
55 | .muidocs-icon-custom-sort:before {
56 | content: "\e600";
57 | }
58 |
59 | .muidocs-icon-custom-github:before {
60 | content: "\e625";
61 | }
62 |
63 | .muidocs-icon-custom-arrow-drop-right:before {
64 | content: "\e60b";
65 | }
66 |
67 | .muidocs-icon-custom-pie:before {
68 | content: "\e610";
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/web/src/www/css/github.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | github.com style (c) Vasily Polovnyov
4 |
5 | */
6 |
7 | .hljs {
8 | display: block;
9 | overflow-x: auto;
10 | padding: 0.5em;
11 | color: #333;
12 | background: #f8f8f8;
13 | -webkit-text-size-adjust: none;
14 | }
15 |
16 | .hljs-comment,
17 | .hljs-template_comment,
18 | .diff .hljs-header,
19 | .hljs-javadoc {
20 | color: #998;
21 | font-style: italic;
22 | }
23 |
24 | .hljs-keyword,
25 | .css .rule .hljs-keyword,
26 | .hljs-winutils,
27 | .nginx .hljs-title,
28 | .hljs-subst,
29 | .hljs-request,
30 | .hljs-status {
31 | color: #333;
32 | font-weight: bold;
33 | }
34 |
35 | .hljs-number,
36 | .hljs-hexcolor,
37 | .ruby .hljs-constant {
38 | color: #008080;
39 | }
40 |
41 | .hljs-string,
42 | .hljs-tag .hljs-value,
43 | .hljs-phpdoc,
44 | .hljs-dartdoc,
45 | .tex .hljs-formula {
46 | color: #d14;
47 | }
48 |
49 | .hljs-title,
50 | .hljs-id,
51 | .scss .hljs-preprocessor {
52 | color: #900;
53 | font-weight: bold;
54 | }
55 |
56 | .hljs-list .hljs-keyword,
57 | .hljs-subst {
58 | font-weight: normal;
59 | }
60 |
61 | .hljs-class .hljs-title,
62 | .hljs-type,
63 | .vhdl .hljs-literal,
64 | .tex .hljs-command {
65 | color: #458;
66 | font-weight: bold;
67 | }
68 |
69 | .hljs-tag,
70 | .hljs-tag .hljs-title,
71 | .hljs-rules .hljs-property,
72 | .django .hljs-tag .hljs-keyword {
73 | color: #000080;
74 | font-weight: normal;
75 | }
76 |
77 | .hljs-attribute,
78 | .hljs-variable,
79 | .lisp .hljs-body {
80 | color: #008080;
81 | }
82 |
83 | .hljs-regexp {
84 | color: #009926;
85 | }
86 |
87 | .hljs-symbol,
88 | .ruby .hljs-symbol .hljs-string,
89 | .lisp .hljs-keyword,
90 | .clojure .hljs-keyword,
91 | .scheme .hljs-keyword,
92 | .tex .hljs-special,
93 | .hljs-prompt {
94 | color: #990073;
95 | }
96 |
97 | .hljs-built_in {
98 | color: #0086b3;
99 | }
100 |
101 | .hljs-preprocessor,
102 | .hljs-pragma,
103 | .hljs-pi,
104 | .hljs-doctype,
105 | .hljs-shebang,
106 | .hljs-cdata {
107 | color: #999;
108 | font-weight: bold;
109 | }
110 |
111 | .hljs-deletion {
112 | background: #fdd;
113 | }
114 |
115 | .hljs-addition {
116 | background: #dfd;
117 | }
118 |
119 | .diff .hljs-change {
120 | background: #0086b3;
121 | }
122 |
123 | .hljs-chunk {
124 | color: #aaa;
125 | }
126 |
--------------------------------------------------------------------------------
/web/src/www/css/main.css:
--------------------------------------------------------------------------------
1 | /* custom font icons */
2 | @import "font-icons/style.css";
3 |
4 | /* hightlight.js for syntax highlighting */
5 | @import "github.css";
6 |
7 | a {
8 | color: #ff4081;
9 | text-decoration: none;
10 | }
11 |
12 | a:hover {
13 | text-decoration: underline;
14 | }
15 |
16 | html {
17 | font-family: 'Roboto', sans-serif;
18 | -webkit-font-smoothing: antialiased;
19 | }
20 |
21 | body, h1, h2, h3, h4, h5, h6 {
22 | margin: 0;
23 | }
24 |
25 | body {
26 | font-size: 15px;
27 | line-height: 24px;
28 | }
29 |
30 | /* Used in our inline-styles.jsx as an example */
31 | .muidocs-checkbox-example {
32 | border: 2px solid #FF9800;
33 | background-color: #4CAF50;
34 | }
35 |
--------------------------------------------------------------------------------
/web/src/www/fonts/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/fonts/iconfont.eot
--------------------------------------------------------------------------------
/web/src/www/fonts/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/fonts/iconfont.ttf
--------------------------------------------------------------------------------
/web/src/www/fonts/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/fonts/iconfont.woff
--------------------------------------------------------------------------------
/web/src/www/images/3fuyu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/3fuyu.png
--------------------------------------------------------------------------------
/web/src/www/images/3fuyu_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/3fuyu_bg.jpg
--------------------------------------------------------------------------------
/web/src/www/images/3fuyu_small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/3fuyu_small.jpg
--------------------------------------------------------------------------------
/web/src/www/images/angular.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/angular.jpg
--------------------------------------------------------------------------------
/web/src/www/images/banner_small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/banner_small.jpg
--------------------------------------------------------------------------------
/web/src/www/images/banner_small_two.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/banner_small_two.jpg
--------------------------------------------------------------------------------
/web/src/www/images/electron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/electron.png
--------------------------------------------------------------------------------
/web/src/www/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/favicon.ico
--------------------------------------------------------------------------------
/web/src/www/images/gomoku.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/gomoku.jpg
--------------------------------------------------------------------------------
/web/src/www/images/mongodb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/mongodb.jpg
--------------------------------------------------------------------------------
/web/src/www/images/nodejs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/nodejs.jpg
--------------------------------------------------------------------------------
/web/src/www/images/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/react.png
--------------------------------------------------------------------------------
/web/src/www/images/vue.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/vue.jpg
--------------------------------------------------------------------------------
/web/src/www/images/weex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/images/weex.png
--------------------------------------------------------------------------------
/web/src/www/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 3fuyu
8 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/web/src/www/laboratory/gomoku/index.css:
--------------------------------------------------------------------------------
1 | .main-content {
2 | position: relative;
3 | background-image: url(./wood.jpg);
4 | background-repeat: no-repeat;
5 | background-size: 700px;
6 | margin: 0 auto;
7 | height: 100%;
8 | box-shadow: 0px 0px 10px #000;
9 | }
10 |
11 | .options {
12 | position: absolute;
13 | top: 80px;
14 | right: 50px;
15 | }
16 |
17 | .options div {
18 | width: 150px;
19 | height: 40px;
20 | font-size: 16px;
21 | border-radius: 10px;
22 | cursor: pointer;
23 | box-shadow: 0 1px 1px #333;
24 | line-height: 40px;
25 | text-align: center;
26 | }
27 |
28 | .board-content {
29 | font-size: 0;
30 | width: 600px;
31 | margin-left: 50px;
32 | padding: 55px;
33 | }
34 |
35 | .board-item {
36 | display: inline-block;
37 | width: 40px;
38 | height: 40px;
39 | position: relative;
40 | }
41 |
42 | .row {
43 | position: absolute;
44 | height: 1px;
45 | width: 100%;
46 | content: ' ';
47 | background-color: #444;
48 | top: 20px;
49 | }
50 |
51 | .column {
52 | position: absolute;
53 | width: 1px;
54 | height: 100%;
55 | content: ' ';
56 | background-color: #444;
57 | left: 19px;
58 | }
59 |
60 | .row-left-top {
61 | position: absolute;
62 | width: 2px;
63 | height: 50%;
64 | content: ' ';
65 | background-color: #444;
66 | left: 20px;
67 | top: 20px;
68 | }
69 |
70 | .column-left-top {
71 | position: absolute;
72 | height: 2px;
73 | width: 50%;
74 | content: ' ';
75 | background-color: #444;
76 | left: 20px;
77 | top: 20px;
78 | }
79 |
80 | .row-right-top {
81 | position: absolute;
82 | width: 2px;
83 | height: 50%;
84 | content: ' ';
85 | background-color: #444;
86 | right: 20px;
87 | top: 20px;
88 | }
89 |
90 | .column-right-top {
91 | position: absolute;
92 | height: 2px;
93 | width: 50%;
94 | content: ' ';
95 | background-color: #444;
96 | right: 20px;
97 | top: 20px;
98 | }
99 |
100 | .row-left-bottom {
101 | position: absolute;
102 | width: 2px;
103 | height: 50%;
104 | content: ' ';
105 | background-color: #444;
106 | left: 20px;
107 | bottom: 20px;
108 | }
109 |
110 | .column-left-bottom {
111 | position: absolute;
112 | height: 2px;
113 | width: 50%;
114 | content: ' ';
115 | background-color: #444;
116 | left: 20px;
117 | bottom: 20px;
118 | }
119 |
120 | .row-right-bottom {
121 | position: absolute;
122 | width: 2px;
123 | height: 50%;
124 | content: ' ';
125 | background-color: #444;
126 | right: 20px;
127 | bottom: 20px;
128 | }
129 |
130 | .column-right-bottom {
131 | position: absolute;
132 | height: 2px;
133 | width: 50%;
134 | content: ' ';
135 | background-color: #444;
136 | right: 20px;
137 | bottom: 20px;
138 | }
139 |
140 | .row-top {
141 | position: absolute;
142 | height: 2px;
143 | width: 100%;
144 | content: ' ';
145 | background-color: #444;
146 | top: 20px;
147 | }
148 |
149 | .column-top {
150 | position: absolute;
151 | width: 1px;
152 | height: 50%;
153 | content: ' ';
154 | background-color: #444;
155 | top: 20px;
156 | left: 19px;
157 | }
158 |
159 | .row-bottom {
160 | position: absolute;
161 | height: 2px;
162 | width: 100%;
163 | content: ' ';
164 | background-color: #444;
165 | bottom: 20px;
166 | }
167 |
168 | .column-bottom {
169 | position: absolute;
170 | width: 1px;
171 | height: 50%;
172 | content: ' ';
173 | background-color: #444;
174 | bottom: 20px;
175 | left: 19px;
176 | }
177 |
178 | .row-left {
179 | position: absolute;
180 | height: 1px;
181 | width: 50%;
182 | content: ' ';
183 | background-color: #444;
184 | left: 20px;
185 | top: 20px;
186 | }
187 |
188 | .column-left {
189 | position: absolute;
190 | width: 2px;
191 | height: 100%;
192 | content: ' ';
193 | background-color: #444;
194 | left: 20px;
195 | }
196 |
197 | .row-right {
198 | position: absolute;
199 | height: 1px;
200 | width: 50%;
201 | content: ' ';
202 | background-color: #444;
203 | right: 20px;
204 | top: 20px;
205 | }
206 |
207 | .column-right {
208 | position: absolute;
209 | width: 2px;
210 | height: 100%;
211 | content: ' ';
212 | background-color: #444;
213 | right: 20px;
214 | }
215 |
216 | .black:before {
217 | position: absolute;
218 | width: 100%;
219 | height: 100%;
220 | border-radius: 1000px;
221 | content: ' ';
222 | z-index: 1;
223 | background: -webkit-radial-gradient(30% 25%, circle closest-corner, #777, #222);
224 | background: -moz-radial-gradient(30% 25%, circle closest-corner, #777, #222);
225 | background: -o-radial-gradient(30% 25%, circle closest-corner, #777, #222);
226 | background: -ms-radial-gradient(30% 25%, circle closest-corner, #777, #222);
227 | background: radial-gradient(30% 25%, circle closest-corner, #777, #222);
228 | -webkit-box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 10, .4), 0 0 2px rgba(0, 0, 0, .5);
229 | box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 10, .4), 0 0 2px rgba(0, 0, 0, .5);
230 | -webkit-transform: scale(.9);
231 | -moz-transform: scale(.9);
232 | -o-transform: scale(.9);
233 | -ms-transform: scale(.9);
234 | transform: scale(.9);
235 | }
236 |
237 | .white:before {
238 | position: absolute;
239 | width: 100%;
240 | height: 100%;
241 | border-radius: 1000px;
242 | content: ' ';
243 | z-index: 1;
244 | background: -webkit-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
245 | background: -moz-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
246 | background: -o-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
247 | background: -ms-radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
248 | background: radial-gradient(30% 25%, circle closest-corner, #fff, #eee);
249 | -webkit-box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 100, .4), 0 0 2px rgba(0, 0, 0, .5);
250 | box-shadow: inset 0 -2px 15px rgba(255, 255, 255, .3), inset -2px -1px 40px rgba(10, 10, 100, .4), 0 0 2px rgba(0, 0, 0, .5);
251 | -webkit-transform: scale(.9);
252 | -moz-transform: scale(.9);
253 | -o-transform: scale(.9);
254 | -ms-transform: scale(.9);
255 | transform: scale(.9);
256 | }
257 |
258 | .options > div {
259 | border: 1px solid #c27426;
260 | background: #c27426;
261 | font-weight: 700;
262 | color: #fff;
263 | text-shadow: 0 1px 1px #444;
264 | background-image: -webkit-gradient(linear, left top, left bottom, from(#D57F29), to(#AE6822));
265 | background-image: -webkit-linear-gradient(#D57F29, #AE6822);
266 | background-image: -moz-linear-gradient(#D57F29, #AE6822);
267 | background-image: -ms-linear-gradient(#D57F29, #AE6822);
268 | background-image: -o-linear-gradient(#D57F29, #AE6822);
269 | background-image: linear-gradient(#D57F29, #AE6822);
270 | margin-bottom: 30px;
271 | }
--------------------------------------------------------------------------------
/web/src/www/laboratory/gomoku/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gomoku
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
人机
13 |
重新开始
14 |
悔棋
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/web/src/www/laboratory/gomoku/wood.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3fuyu/blog/772c4a2562a46a739c80139026ab7a5a9cfa798f/web/src/www/laboratory/gomoku/wood.jpg
--------------------------------------------------------------------------------
/web/src/www/management.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 3fuyu
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/web/src/www/versions.json:
--------------------------------------------------------------------------------
1 | [
2 | "HEAD",
3 | "v0.15.4",
4 | "v0.15.3",
5 | "v0.15.2",
6 | "v0.15.1",
7 | "v0.15.0",
8 | "v0.14.4",
9 | "v0.14.3",
10 | "v0.14.2",
11 | "v0.14.1",
12 | "v0.14.0",
13 | "v0.13.4",
14 | "v0.13.3",
15 | "v0.13.2",
16 | "v0.13.1",
17 | "v0.13.0",
18 | "v0.12.5",
19 | "v0.12.4",
20 | "v0.12.3",
21 | "v0.12.2",
22 | "v0.12.1",
23 | "v0.12.0",
24 | "v0.11.1",
25 | "v0.11.0",
26 | "v0.10.4",
27 | "v0.10.3",
28 | "v0.10.2",
29 | "v0.10.1",
30 | "v0.10.0",
31 | "v0.9.2",
32 | "v0.9.1",
33 | "v0.9.0",
34 | "v0.8.0",
35 | "v0.7.5",
36 | "v0.7.2",
37 | "v0.7.1",
38 | "v0.5.0",
39 | "v0.7.4",
40 | "v0.7.3",
41 | "v0.7.0",
42 | "v0.6.1",
43 | "v0.6.0",
44 | "v0.4.1",
45 | "v0.4.0",
46 | "v0.3.3",
47 | "v0.3.2",
48 | "v0.3.1",
49 | "v0.3.0"
50 | ]
51 |
--------------------------------------------------------------------------------
/web/test/testHightlight.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/web/testHS.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HashAndSearch
6 |
7 |
8 |
9 |
10 | ya
11 |
20 |
21 |
--------------------------------------------------------------------------------
/web/webpack-production.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const buildPath = path.resolve(__dirname, 'build');
4 | const CopyWebpackPlugin = require('copy-webpack-plugin');
5 | const HtmlWebpackPlugin = require('html-webpack-plugin');
6 |
7 | const config = {
8 | // Entry point to the project
9 | entry: [
10 | './node_modules/babel-polyfill/lib/index.js',
11 | path.resolve(__dirname, 'src/app/app.js'),
12 | ],
13 | // Webpack config options on how to obtain modules
14 | resolve: {
15 | // When requiring, you don't need to add these extensions
16 | extensions: ['', '.js', '.md', '.txt'],
17 | alias: {
18 | // material-ui requires will be searched in src folder, not in node_modules
19 | 'material-ui': path.resolve(__dirname, '../src'),
20 | },
21 | },
22 | devtool: 'source-map',
23 | // Configuration for server
24 | devServer: {
25 | contentBase: 'build',
26 | // Required for webpack-dev-server
27 | outputPath: buildPath,
28 | },
29 | // Output file config
30 | output: {
31 | path: buildPath, // Path of output file
32 | filename: 'app.js', // Name of output file
33 | },
34 | plugins: [
35 | new webpack.optimize.OccurenceOrderPlugin(),
36 | new webpack.optimize.DedupePlugin(),
37 | new webpack.optimize.UglifyJsPlugin({
38 | compress: {
39 | warnings: false,
40 | },
41 | output: {
42 | comments: false,
43 | },
44 | }),
45 | new webpack.DefinePlugin({
46 | 'process.env': {
47 | NODE_ENV: JSON.stringify('production'),
48 | },
49 | }),
50 |
51 | // Allows error warnings but does not stop compiling. Will remove when eslint is added
52 | new webpack.NoErrorsPlugin(),
53 | // Transfer Files
54 | new CopyWebpackPlugin([
55 | {from: 'src/www/css', to: 'css'},
56 | {from: 'src/www/images', to: 'images'},
57 | {from: 'src/www/index.html'},
58 | {from: 'src/www/versions.json'},
59 | {from: 'src/app/js/lib/ZeroClipboard.swf'},
60 | ]),
61 |
62 | ],
63 | module: {
64 | // Allow loading of non-es5 js files.
65 | loaders: [
66 | {
67 | test: /\.js$/,
68 | loader: 'babel-loader',
69 | exclude: /node_modules/,
70 | },
71 | {
72 | test: /\.json$/,
73 | loader: 'json-loader',
74 | },
75 | {
76 | test: /\.txt$/,
77 | loader: 'raw-loader',
78 | include: path.resolve(__dirname, 'src/app/components/raw-code'),
79 | },
80 | {
81 | test: /\.md$/,
82 | loader: 'raw-loader',
83 | },
84 | {
85 | test: /\.css$/,
86 | loader: 'style-loader!css-loader',
87 | },
88 | {
89 | test: /\.(less)$/,
90 | loader: 'style-loader!css-loader!less-loader'
91 | }
92 | ],
93 | },
94 | eslint: {
95 | configFile: '../.eslintrc',
96 | },
97 | };
98 |
99 | module.exports = config;
100 |
--------------------------------------------------------------------------------
/web/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const buildPath = path.resolve(__dirname, 'src/www');
4 | const CopyWebpackPlugin = require('copy-webpack-plugin');
5 |
6 | const config = {
7 | // Entry point to the project
8 | entry: [
9 | 'webpack/hot/dev-server',
10 | 'webpack/hot/only-dev-server',
11 | './node_modules/babel-polyfill/lib/index.js',
12 | path.resolve(__dirname, 'src/app/app.js'),
13 | ],
14 | // Webpack config options on how to obtain modules
15 | resolve: {
16 | // When requiring, you don't need to add these extensions
17 | extensions: ['', '.js', '.md', '.txt'],
18 | alias: {
19 | // material-ui requires will be searched in src folder, not in node_modules
20 | 'material-ui': path.resolve(__dirname, '../src'),
21 | },
22 | },
23 | // Configuration for dev server
24 | devServer: {
25 | contentBase: 'src/www',
26 | devtool: 'eval',
27 | hot: true,
28 | inline: true,
29 | port: 3000,
30 | // Required for webpack-dev-server.
31 | outputPath: buildPath,
32 | },
33 | devtool: 'eval',
34 | // Output file config
35 | output: {
36 | path: buildPath, // Path of output file
37 | filename: 'app.js', // Name of output file
38 | },
39 | plugins: [
40 | // Allows for sync with browser while developing (like BrowserSync)
41 | new webpack.HotModuleReplacementPlugin(),
42 | // Allows error warninggs but does not stop compiling. Will remove when eslint is added
43 | new webpack.NoErrorsPlugin(),
44 | new CopyWebpackPlugin([
45 | {from: 'src/www/index.html'},
46 | ]),
47 | ],
48 | module: {
49 | // Allow loading of non-es
50 | loaders: [
51 | {
52 | test: /\.js$/,
53 | loaders: [
54 | 'babel-loader',
55 | ],
56 | exclude: /node_modules/,
57 | },
58 | {
59 | test: /\.json$/,
60 | loader: 'json-loader',
61 | },
62 | {
63 | test: /\.txt$/,
64 | loader: 'raw-loader',
65 | include: path.resolve(__dirname, 'src/app/components/raw-code'),
66 | },
67 | {
68 | test: /\.md$/,
69 | loader: 'raw-loader',
70 | },
71 | {
72 | test: /\.css$/,
73 | loader: 'style-loader!css-loader',
74 | },
75 | {
76 | test: /\.(less)$/,
77 | loader: 'style-loader!css-loader!less-loader'
78 | }
79 | ],
80 | },
81 | eslint: {
82 | configFile: '../.eslintrc',
83 | },
84 | };
85 |
86 | module.exports = config;
87 |
--------------------------------------------------------------------------------