├── public
├── favicon.ico
├── default
│ ├── js
│ │ └── index.js
│ ├── icons
│ │ ├── weibo.png
│ │ └── github.png
│ ├── fonts
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.ttf
│ │ ├── glyphicons-halflings-regular.woff
│ │ └── glyphicons-halflings-regular.woff2
│ └── css
│ │ └── index.css
├── robots.txt
├── layer
│ └── skin
│ │ └── default
│ │ ├── icon.png
│ │ ├── icon-ext.png
│ │ ├── loading-0.gif
│ │ ├── loading-1.gif
│ │ └── loading-2.gif
├── mix-manifest.json
├── share.js
│ └── fonts
│ │ ├── iconfont.eot
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
├── fonts
│ └── vendor
│ │ ├── Ionicons
│ │ ├── ionicons.eot
│ │ ├── ionicons.ttf
│ │ └── ionicons.woff
│ │ ├── font-awesome
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
│ │ └── bootstrap
│ │ └── dist
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.ttf
│ │ ├── glyphicons-halflings-regular.woff
│ │ └── glyphicons-halflings-regular.woff2
├── images
│ └── vendor
│ │ └── _admin-lte@2.4.8@admin-lte
│ │ └── plugins
│ │ └── iCheck
│ │ └── square
│ │ ├── blue.png
│ │ └── blue@2x.png
├── .htaccess
├── web.config
├── js
│ └── moell.js
└── index.php
├── database
├── seeds
│ ├── .gitkeep
│ ├── UserTableSeeder.php
│ ├── DatabaseSeeder.php
│ └── SystemTableSeeder.php
├── .gitignore
├── migrations
│ ├── .gitkeep
│ ├── 2016_09_10_113755_create_systems_table.php
│ ├── 2016_07_25_143011_create_tags_table.php
│ ├── 2016_08_14_123836_add_users_table.php
│ ├── 2016_08_24_162228_add_tags_table.php
│ ├── 2016_11_14_142731_change_valus_field_to_systems_table.php
│ ├── 2014_10_12_100000_create_password_resets_table.php
│ ├── 2016_08_31_143604_create_links_table.php
│ ├── 2016_09_21_134642_add_html_content_to_articles_table.php
│ ├── 2014_10_12_000000_create_users_table.php
│ ├── 2016_09_03_051144_create_navigations_table.php
│ ├── 2016_08_28_145612_create_article_tags_table.php
│ ├── 2016_09_24_132253_create_pages_table.php
│ ├── 2016_07_30_064321_create_categories_table.php
│ └── 2016_07_25_130523_create_articles_table.php
└── factories
│ └── UserFactory.php
├── resources
├── js
│ ├── simplemde.js
│ ├── components
│ │ └── ExampleComponent.vue
│ ├── app.js
│ ├── moell.js
│ └── bootstrap.js
├── views
│ ├── vendor
│ │ └── .gitkeep
│ ├── backend
│ │ ├── home.blade.php~
│ │ ├── alert
│ │ │ ├── success.blade.php
│ │ │ └── warning.blade.php
│ │ ├── tag
│ │ │ ├── create.blade.php
│ │ │ └── edit.blade.php
│ │ ├── category
│ │ │ ├── create.blade.php
│ │ │ ├── edit.blade.php
│ │ │ └── index.blade.php
│ │ ├── link
│ │ │ ├── create.blade.php
│ │ │ ├── edit.blade.php
│ │ │ └── index.blade.php
│ │ ├── upload
│ │ │ └── upload.blade.php
│ │ ├── home.blade.php
│ │ ├── page
│ │ │ └── index.blade.php
│ │ ├── user
│ │ │ └── create.blade.php
│ │ └── navigation
│ │ │ └── create.blade.php
│ ├── default
│ │ ├── comment
│ │ │ ├── index.blade.php
│ │ │ ├── disqus.blade.php
│ │ │ └── duoshuo.blade.php
│ │ ├── link.blade.php
│ │ ├── tag.blade.php
│ │ ├── footer.blade.php
│ │ ├── search_article.blade.php
│ │ ├── home.blade.php
│ │ ├── tag_article.blade.php
│ │ ├── hot.blade.php
│ │ ├── category_article.blade.php
│ │ ├── navigation.blade.php
│ │ ├── author.blade.php
│ │ ├── article.blade.php
│ │ ├── show_page.blade.php
│ │ └── show_article.blade.php
│ ├── home.blade.php
│ ├── welcome.blade.php
│ ├── errors
│ │ └── 503.blade.php
│ └── layouts
│ │ └── app.blade.php
├── sass
│ ├── app.scss
│ ├── _variables.scss
│ └── backend.scss
└── lang
│ └── en
│ ├── pagination.php
│ ├── auth.php
│ └── passwords.php
├── bootstrap
├── cache
│ └── .gitignore
└── app.php
├── storage
├── debugbar
│ └── .gitignore
├── logs
│ └── .gitignore
├── app
│ ├── public
│ │ └── .gitignore
│ └── .gitignore
└── framework
│ ├── cache
│ └── .gitignore
│ ├── views
│ └── .gitignore
│ ├── sessions
│ └── .gitignore
│ └── .gitignore
├── .gitattributes
├── .gitignore
├── app
├── Http
│ ├── Requests
│ │ ├── Request.php
│ │ └── Backend
│ │ │ ├── Upload
│ │ │ ├── DirDeleteRequest.php
│ │ │ ├── FileDeleteRequest.php
│ │ │ ├── UploadStoreRequest.php
│ │ │ └── MakeDirRequest.php
│ │ │ ├── Category
│ │ │ ├── CreateRequest.php
│ │ │ └── UpdateRequest.php
│ │ │ ├── Tag
│ │ │ ├── CreateRequest.php
│ │ │ └── UpdateRequest.php
│ │ │ ├── Page
│ │ │ ├── CreateRequest.php
│ │ │ └── UpdateRequest.php
│ │ │ ├── Link
│ │ │ ├── CreateRequest.php
│ │ │ └── UpdateRequest.php
│ │ │ ├── Navigation
│ │ │ ├── CreateRequest.php
│ │ │ └── UpdateRequest.php
│ │ │ ├── Article
│ │ │ ├── CreateRequest.php
│ │ │ └── UpdateRequest.php
│ │ │ └── User
│ │ │ ├── UpdateRequest.php
│ │ │ └── CreateRequest.php
│ ├── Controllers
│ │ ├── Backend
│ │ │ ├── HomeController.php
│ │ │ ├── UploadController.php
│ │ │ ├── SystemController.php
│ │ │ ├── AuthController.php
│ │ │ ├── TagController.php
│ │ │ ├── LinkController.php
│ │ │ ├── NavigationController.php
│ │ │ └── PageController.php
│ │ ├── ArticleController.php
│ │ ├── Controller.php
│ │ ├── SearchController.php
│ │ ├── TagController.php
│ │ ├── CategoryController.php
│ │ ├── HomeController.php
│ │ ├── PageController.php
│ │ ├── Auth
│ │ │ ├── ForgotPasswordController.php
│ │ │ ├── LoginController.php
│ │ │ ├── ResetPasswordController.php
│ │ │ ├── VerificationController.php
│ │ │ └── RegisterController.php
│ │ └── RssController.php
│ ├── Middleware
│ │ ├── EncryptCookies.php
│ │ ├── CheckForMaintenanceMode.php
│ │ ├── TrimStrings.php
│ │ ├── Authenticate.php
│ │ ├── TrustProxies.php
│ │ ├── VerifyCsrfToken.php
│ │ ├── RejectNullValues.php
│ │ └── RedirectIfAuthenticated.php
│ └── Kernel.php
├── Models
│ ├── Link.php
│ ├── Page.php
│ ├── ArticleTag.php
│ ├── Navigation.php
│ ├── Category.php
│ ├── Tag.php
│ ├── User.php
│ ├── System.php
│ └── Article.php
├── Presenters
│ ├── ArticleTagPresenter.php
│ ├── LinkPresenter.php
│ ├── NavigationPresenter.php
│ ├── PagePresenter.php
│ ├── TagPresenter.php
│ ├── UserPresenter.php
│ ├── ArticlePresenter.php
│ ├── SystemPresenter.php
│ ├── CategoryPresenter.php
│ └── BackendPresenter.php
├── Providers
│ ├── BroadcastServiceProvider.php
│ ├── AppServiceProvider.php
│ ├── AuthServiceProvider.php
│ ├── EventServiceProvider.php
│ └── RouteServiceProvider.php
├── Console
│ └── Kernel.php
└── Exceptions
│ └── Handler.php
├── tests
├── TestCase.php
├── Unit
│ └── ExampleTest.php
├── Feature
│ └── ExampleTest.php
└── CreatesApplication.php
├── .editorconfig
├── routes
├── api.php
├── channels.php
├── console.php
└── web.php
├── gulpfile.js
├── server.php
├── webpack.mix.js
├── .env.example
├── package.json
├── config
├── compile.php
├── view.php
├── services.php
├── hashing.php
├── broadcasting.php
├── blog.php
├── logging.php
├── queue.php
└── cache.php
├── phpunit.xml
├── artisan
├── readme.md
└── composer.json
/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/seeds/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/default/js/index.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/js/simplemde.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite
2 |
--------------------------------------------------------------------------------
/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/resources/views/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/bootstrap/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/debugbar/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/storage/app/public/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !public/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/storage/framework/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/views/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/sessions/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/public/default/icons/weibo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/default/icons/weibo.png
--------------------------------------------------------------------------------
/public/default/icons/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/default/icons/github.png
--------------------------------------------------------------------------------
/public/layer/skin/default/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/layer/skin/default/icon.png
--------------------------------------------------------------------------------
/public/mix-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "/js/backend.js": "/js/backend.js",
3 | "/css/backend.css": "/css/backend.css"
4 | }
5 |
--------------------------------------------------------------------------------
/public/share.js/fonts/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/share.js/fonts/iconfont.eot
--------------------------------------------------------------------------------
/public/share.js/fonts/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/share.js/fonts/iconfont.ttf
--------------------------------------------------------------------------------
/public/share.js/fonts/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/share.js/fonts/iconfont.woff
--------------------------------------------------------------------------------
/public/layer/skin/default/icon-ext.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/layer/skin/default/icon-ext.png
--------------------------------------------------------------------------------
/public/layer/skin/default/loading-0.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/layer/skin/default/loading-0.gif
--------------------------------------------------------------------------------
/public/layer/skin/default/loading-1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/layer/skin/default/loading-1.gif
--------------------------------------------------------------------------------
/public/layer/skin/default/loading-2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/layer/skin/default/loading-2.gif
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.css linguist-vendored
3 | *.scss linguist-vendored
4 | *.js linguist-vendored
5 | *.html linguist-vendored
6 |
--------------------------------------------------------------------------------
/public/fonts/vendor/Ionicons/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/Ionicons/ionicons.eot
--------------------------------------------------------------------------------
/public/fonts/vendor/Ionicons/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/Ionicons/ionicons.ttf
--------------------------------------------------------------------------------
/public/fonts/vendor/Ionicons/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/Ionicons/ionicons.woff
--------------------------------------------------------------------------------
/public/default/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/default/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/default/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/default/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/storage/framework/.gitignore:
--------------------------------------------------------------------------------
1 | config.php
2 | routes.php
3 | schedule-*
4 | compiled.php
5 | services.json
6 | events.scanned.php
7 | routes.scanned.php
8 | down
9 |
--------------------------------------------------------------------------------
/public/default/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/default/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/default/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/default/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/public/fonts/vendor/font-awesome/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/font-awesome/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/public/fonts/vendor/font-awesome/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/font-awesome/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/public/fonts/vendor/font-awesome/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/font-awesome/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/public/fonts/vendor/font-awesome/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/font-awesome/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/fonts/vendor/bootstrap/dist/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /node_modules
3 | /public/storage
4 | Homestead.yaml
5 | Homestead.json
6 | .env
7 | /.idea
8 | /public/uploads
9 | composer.lock
10 | _ide_helper.php
11 | .phpstorm.meta.php
--------------------------------------------------------------------------------
/public/images/vendor/_admin-lte@2.4.8@admin-lte/plugins/iCheck/square/blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moell-peng/moell-blog/HEAD/public/images/vendor/_admin-lte@2.4.8@admin-lte/plugins/iCheck/square/blue.png
--------------------------------------------------------------------------------
/app/Http/Requests/Request.php:
--------------------------------------------------------------------------------
1 |
7 | Home
8 | Moell Blog
9 |
10 | @endsection
11 |
12 | @section('content')
13 | ddd
14 | @endsection
15 |
--------------------------------------------------------------------------------
/resources/sass/app.scss:
--------------------------------------------------------------------------------
1 |
2 | // Fonts
3 | @import url('https://fonts.googleapis.com/css?family=Nunito');
4 |
5 | // Variables
6 | @import 'variables';
7 |
8 | // Bootstrap
9 | @import '~bootstrap/scss/bootstrap';
10 |
11 | .navbar-laravel {
12 | background-color: #fff;
13 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
14 | }
15 |
--------------------------------------------------------------------------------
/resources/views/backend/alert/success.blade.php:
--------------------------------------------------------------------------------
1 | @if(session('success'))
2 |
3 |
×
4 |
5 | 提示消息!
6 |
{{ session('success') }}
7 |
8 | @endif
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/HomeController.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/Presenters/ArticleTagPresenter.php:
--------------------------------------------------------------------------------
1 | where('tag_id', $tagId)->count();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/resources/views/backend/alert/warning.blade.php:
--------------------------------------------------------------------------------
1 | @if($errors->any())
2 |
3 |
×
4 |
5 | 错误提示!
6 | @foreach($errors->all() as $error)
7 |
{{ $error }}
8 | @endforeach
9 |
10 | @endif
--------------------------------------------------------------------------------
/app/Models/Navigation.php:
--------------------------------------------------------------------------------
1 | belongsTo('App\Models\Category', 'article_cate_id', 'id');
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/Http/Controllers/ArticleController.php:
--------------------------------------------------------------------------------
1 | increment("read_count");
15 |
16 | return view('default.show_article', compact('article'));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/resources/sass/_variables.scss:
--------------------------------------------------------------------------------
1 |
2 | // Body
3 | $body-bg: #f8fafc;
4 |
5 | // Typography
6 | $font-family-sans-serif: "Nunito", sans-serif;
7 | $font-size-base: 0.9rem;
8 | $line-height-base: 1.6;
9 |
10 | // Colors
11 | $blue: #3490dc;
12 | $indigo: #6574cd;
13 | $purple: #9561e2;
14 | $pink: #f66D9b;
15 | $red: #e3342f;
16 | $orange: #f6993f;
17 | $yellow: #ffed4a;
18 | $green: #38c172;
19 | $teal: #4dc0b5;
20 | $cyan: #6cb2eb;
21 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | hasOne('App\Models\Article', 'cate_id', 'id');
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/Http/Controllers/SearchController.php:
--------------------------------------------------------------------------------
1 | keyword}%")->paginate();
13 |
14 | return view('default.search_article', compact('articles'));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/Feature/ExampleTest.php:
--------------------------------------------------------------------------------
1 | get('/');
18 |
19 | $response->assertStatus(200);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/resources/views/default/comment/index.blade.php:
--------------------------------------------------------------------------------
1 |
2 | getKeyValue('comment_plugin');
4 | $shortName = $systemPresenter->getKeyValue($commentPlugin.'_short_name');
5 | ?>
6 | @if($commentPlugin !='' && $shortName != '')
7 | @if($commentPlugin == 'duoshuo')
8 | @include('default.comment.duoshuo')
9 | @elseif($commentPlugin == 'disqus')
10 | @include('default.comment.disqus')
11 | @endif
12 | @endif
--------------------------------------------------------------------------------
/database/seeds/UserTableSeeder.php:
--------------------------------------------------------------------------------
1 | insert([
15 | 'name' => 'admin',
16 | 'email' => 'moell@foxmail.com',
17 | 'password' => bcrypt('moell.cn')
18 | ]);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/Presenters/LinkPresenter.php:
--------------------------------------------------------------------------------
1 | orderBy('sequence', 'desc')->get(['name','url']);
22 | return $links;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/routes/api.php:
--------------------------------------------------------------------------------
1 | call(UserTableSeeder::class);
18 | $this->call(SystemTableSeeder::class);
19 |
20 | Model::reguard();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/CreatesApplication.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class)->bootstrap();
19 |
20 | return $app;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/Providers/BroadcastServiceProvider.php:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
Dashboard
9 |
10 |
11 | You are logged in!
12 |
13 |
14 |
15 |
16 |
17 | @endsection
18 |
--------------------------------------------------------------------------------
/database/seeds/SystemTableSeeder.php:
--------------------------------------------------------------------------------
1 | 'blog_name', 'value' => 'Moell Blog'],
16 | ['key' => 'motto', '欢迎使用Moell Blog,欢迎Star。']
17 | ];
18 | DB::table('systems')->insert($systems);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/Http/Controllers/TagController.php:
--------------------------------------------------------------------------------
1 | article()
14 | ->orderBy('sort','desc')
15 | ->orderBy('id', 'desc')
16 | ->paginate(15);
17 |
18 | return view('default.tag_article', compact('articles', 'tag'));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/resources/views/welcome.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.app')
2 |
3 | @section('content')
4 |
5 |
6 |
7 |
8 |
Welcome
9 |
10 |
11 | Your Application's Landing Page.
12 |
13 |
14 |
15 |
16 |
17 | @endsection
18 |
--------------------------------------------------------------------------------
/app/Http/Middleware/Authenticate.php:
--------------------------------------------------------------------------------
1 | article()
15 | ->orderBy('sort','desc')
16 | ->orderBy('id', 'desc')
17 | ->paginate();
18 |
19 | return view('default.category_article', compact('articles', 'category'));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/Http/Middleware/TrustProxies.php:
--------------------------------------------------------------------------------
1 | belongsToMany('App\Models\Article','article_tags', 'tag_id', 'article_id');
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/Presenters/NavigationPresenter.php:
--------------------------------------------------------------------------------
1 | where('state', 0)
23 | ->orderBy('sequence', 'desc')
24 | ->get( ['name', 'url']);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var elixir = require('laravel-elixir');
2 |
3 | /*
4 | |--------------------------------------------------------------------------
5 | | Elixir Asset Management
6 | |--------------------------------------------------------------------------
7 | |
8 | | Elixir provides a clean, fluent API for defining some basic Gulp tasks
9 | | for your Laravel application. By default, we are compiling the Sass
10 | | file for our application, as well as publishing vendor resources.
11 | |
12 | */
13 |
14 | elixir(function(mix) {
15 | mix.sass('app.scss');
16 | });
17 |
--------------------------------------------------------------------------------
/routes/channels.php:
--------------------------------------------------------------------------------
1 | id === (int) $id;
16 | });
17 |
--------------------------------------------------------------------------------
/app/Http/Middleware/VerifyCsrfToken.php:
--------------------------------------------------------------------------------
1 | $alias]);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/resources/lang/en/pagination.php:
--------------------------------------------------------------------------------
1 | '« Previous',
17 | 'next' => 'Next »',
18 |
19 | ];
20 |
--------------------------------------------------------------------------------
/app/Http/Middleware/RejectNullValues.php:
--------------------------------------------------------------------------------
1 | map(function ($item) {
19 | return is_null($item) ? '' : $item;
20 | });
21 | $request->replace($params->all());
22 | return $next($request);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/routes/console.php:
--------------------------------------------------------------------------------
1 | comment(Inspiring::quote());
18 | })->describe('Display an inspiring quote');
19 |
--------------------------------------------------------------------------------
/resources/views/default/link.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
友情链接
4 |
5 | @inject('linkPresenter', 'App\Presenters\LinkPresenter')
6 |
7 |
8 |
9 | linkList() ?>
10 |
11 | @if ($links)
12 | @foreach ($links as $link)
13 |
14 | {{ $link->name }}
15 |
16 | @endforeach
17 | @endif
18 |
19 |
--------------------------------------------------------------------------------
/resources/views/default/tag.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
标签
4 |
5 |
6 | @inject('tagPresenter', 'App\Presenters\TagPresenter')
7 |
8 | tagList();?>
9 | @if ($tagList)
10 | @foreach ($tagList as $tl)
11 |
12 | {{ $tl->tag_name }}
13 |
14 | @endforeach
15 | @endif
16 |
17 |
--------------------------------------------------------------------------------
/server.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 |
10 | $uri = urldecode(
11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
12 | );
13 |
14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the
15 | // built-in PHP web server. This provides a convenient way to test a Laravel
16 | // application without having installed a "real" web server software here.
17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
18 | return false;
19 | }
20 |
21 | require_once __DIR__.'/public/index.php';
22 |
--------------------------------------------------------------------------------
/app/Http/Controllers/HomeController.php:
--------------------------------------------------------------------------------
1 | with([
19 | 'category'
20 | ])
21 | ->orderBy('sort','desc')
22 | ->orderBy('id', 'desc')
23 | ->paginate();
24 |
25 | return view('default.home', compact('articles'));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/Presenters/TagPresenter.php:
--------------------------------------------------------------------------------
1 | tag()->pluck('tag_name');
18 |
19 | return $tag ? implode(';', $tag->toArray()) : '';
20 | }
21 |
22 | /**
23 | * 获取标签列表
24 | *
25 | * @return mixed
26 | */
27 | public function tagList()
28 | {
29 | return Tag::query()->get(['id', 'tag_name']);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/Http/Middleware/RedirectIfAuthenticated.php:
--------------------------------------------------------------------------------
1 | check()) {
21 | return redirect('/home');
22 | }
23 |
24 | return $next($request);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/resources/views/default/comment/disqus.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews -Indexes
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Handle Authorization Header
9 | RewriteCond %{HTTP:Authorization} .
10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
11 |
12 | # Redirect Trailing Slashes If Not A Folder...
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 | RewriteCond %{REQUEST_URI} (.+)/$
15 | RewriteRule ^ %1 [L,R=301]
16 |
17 | # Handle Front Controller...
18 | RewriteCond %{REQUEST_FILENAME} !-d
19 | RewriteCond %{REQUEST_FILENAME} !-f
20 | RewriteRule ^ index.php [L]
21 |
22 |
--------------------------------------------------------------------------------
/resources/js/components/ExampleComponent.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | I'm an example component.
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
24 |
--------------------------------------------------------------------------------
/resources/lang/en/auth.php:
--------------------------------------------------------------------------------
1 | 'These credentials do not match our records.',
17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
18 |
19 | ];
20 |
--------------------------------------------------------------------------------
/webpack.mix.js:
--------------------------------------------------------------------------------
1 | const mix = require('laravel-mix');
2 |
3 | /*
4 | |--------------------------------------------------------------------------
5 | | Mix Asset Management
6 | |--------------------------------------------------------------------------
7 | |
8 | | Mix provides a clean, fluent API for defining some Webpack build steps
9 | | for your Laravel application. By default, we are compiling the Sass
10 | | file for the application as well as bundling up all the JS files.
11 | |
12 | */
13 |
14 | /*mix.js('resources/js/app.js', 'public/js')
15 | .sass('resources/sass/app.scss', 'public/css');*/
16 |
17 | mix.js('resources/js/backend.js', 'public/js')
18 | .sass('resources/sass/backend.scss', 'public/css');
19 |
--------------------------------------------------------------------------------
/app/Presenters/UserPresenter.php:
--------------------------------------------------------------------------------
1 | first();
17 |
18 | if ($user) {
19 | return $user->name;
20 | }
21 | }
22 |
23 | public function getUserInfo($userId = 0) {
24 | $columns = ['id', 'name', 'user_pic'];
25 |
26 | if ($userId > 0) {
27 | return User::where("id", $userId)->first($columns);
28 | }
29 | return User::first($columns);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/resources/js/app.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * First we will load all of this project's JavaScript dependencies which
4 | * includes Vue and other libraries. It is a great starting point when
5 | * building robust, powerful web applications using Vue and Laravel.
6 | */
7 |
8 | require('./bootstrap');
9 |
10 | window.Vue = require('vue');
11 |
12 | /**
13 | * Next, we will create a fresh Vue application instance and attach it to
14 | * the page. Then, you may begin adding components to this application
15 | * or customize the JavaScript scaffolding to fit your unique needs.
16 | */
17 |
18 | Vue.component('example-component', require('./components/ExampleComponent.vue'));
19 |
20 | const app = new Vue({
21 | el: '#app'
22 | });
23 |
--------------------------------------------------------------------------------
/app/Providers/AuthServiceProvider.php:
--------------------------------------------------------------------------------
1 | 'App\Policies\ModelPolicy',
17 | ];
18 |
19 | /**
20 | * Register any authentication / authorization services.
21 | *
22 | * @return void
23 | */
24 | public function boot()
25 | {
26 | $this->registerPolicies();
27 |
28 | //
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/database/migrations/2016_09_10_113755_create_systems_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('key');
19 | $table->string('value');
20 | $table->unique('key');
21 | });
22 | }
23 |
24 | /**
25 | * Reverse the migrations.
26 | *
27 | * @return void
28 | */
29 | public function down()
30 | {
31 | Schema::drop('systems');
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2016_07_25_143011_create_tags_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->string('tag_name')->unique()->comment('标签名字');
18 | });
19 | }
20 |
21 | /**
22 | * Reverse the migrations.
23 | *
24 | * @return void
25 | */
26 | public function down()
27 | {
28 | Schema::drop('tags');
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/resources/views/default/footer.blade.php:
--------------------------------------------------------------------------------
1 |
16 | {!! $systemPresenter->getKeyValue('statistics_script') !!}
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/UploadController.php:
--------------------------------------------------------------------------------
1 | hasFile('file')
14 | && $request->file('file')->isValid()
15 | && in_array($request->file->extension(), ["png", "jpg", "jpeg", "gif"])
16 | ) {
17 | $path = $request->file->store(date('Ymd'), config('blog.disk'));
18 |
19 | $url = Storage::disk(config('blog.disk'))->url($path);
20 |
21 | return response()->json(['filename' => $url]);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/resources/views/default/search_article.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.app')
2 |
3 | @section('title', request('keyword'))
4 |
5 | @section('description', request('keyword'))
6 |
7 | @section('keywords', request('keyword'))
8 |
9 | @section('header-text')
10 |
11 |
12 |
13 |
14 |
15 |
16 | {{ request('keyword') }}
17 |
18 |
19 |
20 |
21 | @endsection
22 |
23 | @section('content')
24 | @include('default.article')
25 | @endsection
26 |
--------------------------------------------------------------------------------
/app/Http/Controllers/PageController.php:
--------------------------------------------------------------------------------
1 | first();
17 |
18 | if (!$page) {
19 | abort('404');
20 | }
21 |
22 | return view('default.show_page', compact('page'));
23 | }
24 |
25 | /**
26 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
27 | */
28 | public function about()
29 | {
30 | return $this->index('about');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/database/migrations/2016_08_14_123836_add_users_table.php:
--------------------------------------------------------------------------------
1 | string('user_pic')->default('')->comment('博客用户头像');
17 | });
18 | }
19 |
20 | /**
21 | * Reverse the migrations.
22 | *
23 | * @return void
24 | */
25 | public function down()
26 | {
27 | Schema::table('users', function (Blueprint $table) {
28 | $table->dropColumn('user_pic');
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/resources/views/default/home.blade.php:
--------------------------------------------------------------------------------
1 | @inject('systemPresenter', 'App\Presenters\SystemPresenter')
2 |
3 | @extends('layouts.app')
4 |
5 | @section('title', $systemPresenter->getKeyValue('title'))
6 |
7 | @section('description', $systemPresenter->getKeyValue('seo_desc'))
8 |
9 | @section('keywords', $systemPresenter->getKeyValue('seo_keyword'))
10 |
11 | @section('header-text')
12 |
13 |
14 |
15 |
16 | {{ $systemPresenter->getKeyValue('motto') }}
17 |
18 |
19 |
20 |
21 | @endsection
22 |
23 | @section('content')
24 | @include('default.article')
25 | @endsection
26 |
--------------------------------------------------------------------------------
/database/migrations/2016_08_24_162228_add_tags_table.php:
--------------------------------------------------------------------------------
1 | timestamps();
17 | });
18 | }
19 |
20 | /**
21 | * Reverse the migrations.
22 | *
23 | * @return void
24 | */
25 | public function down()
26 | {
27 | Schema::table('tags', function (Blueprint $table) {
28 | $table->dropColumn('created_at');
29 | $table->dropColumn('updated_at');
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Upload/DirDeleteRequest.php:
--------------------------------------------------------------------------------
1 | 'required'
28 | ];
29 | }
30 |
31 | public function messages()
32 | {
33 | return [
34 | 'dir.required' => '非法请求'
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/database/migrations/2016_11_14_142731_change_valus_field_to_systems_table.php:
--------------------------------------------------------------------------------
1 | text('value')->change();
17 | });
18 | }
19 |
20 | /**
21 | * Reverse the migrations.
22 | *
23 | * @return void
24 | */
25 | public function down()
26 | {
27 | Schema::table('systems', function (Blueprint $table) {
28 | $table->string('value')->change();
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/SystemController.php:
--------------------------------------------------------------------------------
1 | all() as $key => $value) {
21 | if (in_array($key, config('blog.system_key'))) {
22 | System::updateOrCreate(['key' => $key], ['value' => $value]);
23 | }
24 | }
25 |
26 | return redirect()->back()->with('success', '操作成功');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Category/CreateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | ];
29 | }
30 |
31 | public function messages()
32 | {
33 | return [
34 | 'name.required' => '分类名不能为空'
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Category/UpdateRequest.php:
--------------------------------------------------------------------------------
1 | 'required'
28 | ];
29 | }
30 |
31 | public function messages()
32 | {
33 | return [
34 | 'name.required' => '请填写分类名称'
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Upload/FileDeleteRequest.php:
--------------------------------------------------------------------------------
1 | 'required'
28 | ];
29 | }
30 |
31 | public function messages()
32 | {
33 | return [
34 | 'file.required' => '非法请求'
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | APP_NAME=Laravel
2 | APP_ENV=local
3 | APP_KEY=
4 | APP_DEBUG=true
5 | APP_URL=http://localhost
6 |
7 | LOG_CHANNEL=stack
8 |
9 | DB_CONNECTION=mysql
10 | DB_HOST=127.0.0.1
11 | DB_PORT=3306
12 | DB_DATABASE=homestead
13 | DB_USERNAME=homestead
14 | DB_PASSWORD=secret
15 |
16 | BROADCAST_DRIVER=log
17 | CACHE_DRIVER=file
18 | QUEUE_CONNECTION=sync
19 | SESSION_DRIVER=file
20 | SESSION_LIFETIME=120
21 |
22 | REDIS_HOST=127.0.0.1
23 | REDIS_PASSWORD=null
24 | REDIS_PORT=6379
25 |
26 | MAIL_DRIVER=smtp
27 | MAIL_HOST=smtp.mailtrap.io
28 | MAIL_PORT=2525
29 | MAIL_USERNAME=null
30 | MAIL_PASSWORD=null
31 | MAIL_ENCRYPTION=null
32 |
33 | PUSHER_APP_ID=
34 | PUSHER_APP_KEY=
35 | PUSHER_APP_SECRET=
36 | PUSHER_APP_CLUSTER=mt1
37 |
38 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
39 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
40 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_100000_create_password_resets_table.php:
--------------------------------------------------------------------------------
1 | string('email')->index();
17 | $table->string('token')->index();
18 | $table->timestamp('created_at');
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | *
25 | * @return void
26 | */
27 | public function down()
28 | {
29 | Schema::drop('password_resets');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/resources/views/default/tag_article.blade.php:
--------------------------------------------------------------------------------
1 | @inject('systemPresenter', 'App\Presenters\SystemPresenter')
2 |
3 | @extends('layouts.app')
4 |
5 | @section('title', $tag->tag_name)
6 |
7 | @section('description', $systemPresenter->getKeyValue('seo_desc'))
8 |
9 | @section('keywords', $systemPresenter->getKeyValue('seo_keyword'))
10 |
11 | @section('header-text')
12 |
13 |
14 |
15 |
16 |
17 | {{ $tag->tag_name }}
18 |
19 |
20 |
21 |
22 | @endsection
23 |
24 | @section('content')
25 | @include('default.article')
26 | @endsection
27 |
--------------------------------------------------------------------------------
/database/migrations/2016_08_31_143604_create_links_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->string('name');
18 | $table->string('url');
19 | $table->smallInteger('sequence');
20 | $table->timestamps();
21 | });
22 | }
23 |
24 | /**
25 | * Reverse the migrations.
26 | *
27 | * @return void
28 | */
29 | public function down()
30 | {
31 | Schema::drop('links');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/resources/views/default/comment/duoshuo.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
20 |
--------------------------------------------------------------------------------
/resources/views/default/hot.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
热门文章
4 |
5 | @inject('hotArticle', 'App\Presenters\ArticlePresenter')
6 |
7 | hotArticleList(); ?>
8 |
9 |
21 |
--------------------------------------------------------------------------------
/database/factories/UserFactory.php:
--------------------------------------------------------------------------------
1 | define(App\User::class, function (Faker $faker) {
17 | return [
18 | 'name' => $faker->name,
19 | 'email' => $faker->unique()->safeEmail,
20 | 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
21 | 'remember_token' => str_random(10),
22 | ];
23 | });
24 |
--------------------------------------------------------------------------------
/app/Presenters/ArticlePresenter.php:
--------------------------------------------------------------------------------
1 | orderBy('read_count', 'desc')
23 | ->paginate(8, [
24 | 'id',
25 | 'title',
26 | 'read_count'
27 | ]);
28 | }
29 |
30 | public function formatTitle($title)
31 | {
32 | if (strlen($title) <= 20) {
33 | return $title;
34 | } else {
35 | return mb_substr($title, 0, 20, 'utf-8')."...";
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2016_09_21_134642_add_html_content_to_articles_table.php:
--------------------------------------------------------------------------------
1 | longText('html_content')->nullable()->comment('文章内容,html格式');
17 | });
18 | }
19 |
20 | /**
21 | * Reverse the migrations.
22 | *
23 | * @return void
24 | */
25 | public function down()
26 | {
27 | Schema::table('articles', function (Blueprint $table) {
28 | $table->dropColumn('html_content');
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/resources/sass/backend.scss:
--------------------------------------------------------------------------------
1 | // Variables
2 | @import 'variables';
3 |
4 | // Bootstrap
5 | @import '~admin-lte/bower_components/bootstrap/dist/css/bootstrap.min.css';
6 |
7 | @import '~admin-lte/bower_components/font-awesome/css/font-awesome.min.css';
8 |
9 | @import '~admin-lte/bower_components/Ionicons/css/ionicons.min.css';
10 |
11 | @import '~admin-lte/dist/css/AdminLTE.min.css';
12 |
13 | @import '~admin-lte/dist/css/skins/_all-skins.min.css';
14 |
15 | @import '~admin-lte/plugins/iCheck/square/blue.css';
16 |
17 | @import '~bootstrapvalidator/dist/css/bootstrapValidator.min.css';
18 |
19 | /*@import '~simplemde/dist/simplemde.min.css';
20 |
21 | @import '~highlight.js/styles/solarized-dark.css';*/
22 |
23 | .markdown-editor {
24 | padding: 15px;
25 |
26 | .CodeMirror-fullscreen, .editor-toolbar.fullscreen {
27 | z-index:2000;
28 | }
29 | }
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Tag/CreateRequest.php:
--------------------------------------------------------------------------------
1 | 'required|unique:tags,tag_name',
28 | ];
29 | }
30 |
31 | public function messages()
32 | {
33 | return [
34 | 'name.required' => '标签不能为空',
35 | 'name.unique' => '标签名必须唯一'
36 | ];
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/Providers/EventServiceProvider.php:
--------------------------------------------------------------------------------
1 | [
19 | SendEmailVerificationNotification::class,
20 | ],
21 | ];
22 |
23 | /**
24 | * Register any events for your application.
25 | *
26 | * @return void
27 | */
28 | public function boot()
29 | {
30 | parent::boot();
31 |
32 | //
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/resources/lang/en/passwords.php:
--------------------------------------------------------------------------------
1 | 'Passwords must be at least six characters and match the confirmation.',
17 | 'reset' => 'Your password has been reset!',
18 | 'sent' => 'We have e-mailed your password reset link!',
19 | 'token' => 'This password reset token is invalid.',
20 | 'user' => "We can't find a user with that e-mail address.",
21 |
22 | ];
23 |
--------------------------------------------------------------------------------
/database/migrations/2014_10_12_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->string('name');
18 | $table->string('email')->unique();
19 | $table->string('password');
20 | $table->rememberToken();
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::drop('users');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Page/CreateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'link_alias' => 'unique:pages'
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'title.required' => '页面标题必须填写',
36 | 'link_alias.unique' => '链接别名必须唯一'
37 | ];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Upload/UploadStoreRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'file' => 'required'
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'dir.required' => '保存目录不能为空',
36 | 'file.required' => '请选择上传的文件'
37 | ];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Tag/UpdateRequest.php:
--------------------------------------------------------------------------------
1 | route('tag');
27 | return [
28 | 'name' => 'required|unique:tags,tag_name,'.$id,
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'name.required' => '请填写分类名称',
36 | 'name.unique' => '标签名必须唯一'
37 | ];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/resources/views/default/category_article.blade.php:
--------------------------------------------------------------------------------
1 | @inject('systemPresenter', 'App\Presenters\SystemPresenter')
2 |
3 | @extends('layouts.app')
4 |
5 | @section('title', $systemPresenter->checkReturnValue('title', $category->name))
6 |
7 | @section('description', $systemPresenter->checkReturnValue('seo_desc', $category->name))
8 |
9 | @section('keywords', $systemPresenter->checkReturnValue('seo_keyword', $category->name))
10 |
11 | @section('header-text')
12 |
13 |
14 |
15 |
16 |
17 | {{ $category->name }}
18 |
19 |
20 |
21 |
22 | @endsection
23 |
24 | @section('content')
25 | @include('default.article')
26 | @endsection
27 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Upload/MakeDirRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
29 | 'dir_name' => 'required'
30 | ];
31 | }
32 |
33 | public function messages()
34 | {
35 | return [
36 | 'dir.required' => '目录不能为空',
37 | 'dir_name.required' => '目录名不能为空',
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Link/CreateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'url' => 'required|url'
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'name.required' => '友情链接名字不能为空',
36 | 'url.required' => 'URL不能为空',
37 | 'url.url' => '请输入合法的URL'
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Link/UpdateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'url' => 'required|url'
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'name.required' => '友情链接名字不能为空',
36 | 'url.required' => 'URL不能为空',
37 | 'url.url' => '请输入合法的URL'
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Navigation/CreateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'url' => 'required | url'
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'name.required' => '请输入导航名',
36 | 'url.reqiured' => '请输入URL',
37 | 'url.url' => '请输入合法的URL'
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Navigation/UpdateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'url' => 'required | url'
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'name.required' => '请输入导航名',
36 | 'url.reqiured' => '请输入URL',
37 | 'url.url' => '请输入合法的URL'
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Models/System.php:
--------------------------------------------------------------------------------
1 | first())->value;
16 | }
17 |
18 | public static function optionList()
19 | {
20 | $list = System::all(['key', 'value']);
21 | $system = call_user_func(function () {
22 | $init = [];
23 | $config = array_flip(config('blog.system_key'));
24 | foreach ($config as $key => $value) {
25 | $init[$key] = '';
26 | }
27 | return $init;
28 | });
29 |
30 | foreach ($list as $item) {
31 | $system[$item['key']] = $item['value'];
32 | }
33 |
34 | return $system;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Page/UpdateRequest.php:
--------------------------------------------------------------------------------
1 | route('page');
27 | return [
28 | 'title' => 'required',
29 | 'link_alias' => 'unique:pages,link_alias,'.$id
30 | ];
31 | }
32 |
33 | public function messages()
34 | {
35 | return [
36 | 'title.required' => '页面标题必须填写',
37 | 'link_alias.unique' => '链接别名必须唯一'
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Article/CreateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'cate_id' => 'required|numeric',
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'title.required' => '请输入文章标题',
36 | 'cate_id.required' => '请选择文章分类',
37 | 'cate_id.numeric' => '请选择合法的分类'
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/Article/UpdateRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
28 | 'cate_id' => 'required|numeric',
29 | ];
30 | }
31 |
32 | public function messages()
33 | {
34 | return [
35 | 'title.required' => '请输入文章标题',
36 | 'cate_id.required' => '请选择文章分类',
37 | 'cate_id.numeric' => '请选择合法的分类'
38 | ];
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/public/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/ForgotPasswordController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/Presenters/SystemPresenter.php:
--------------------------------------------------------------------------------
1 | list = System::optionList();
19 |
20 | }
21 |
22 | /**
23 | * 根据key获取value
24 | *
25 | * @param $key
26 | * @return mixed
27 | */
28 | public function getKeyValue($key)
29 | {
30 | return isset($this->list[$key]) ? $this->list[$key] : '';
31 | }
32 |
33 | /**
34 | * 检查返回相应的value
35 | *
36 | * @param $key
37 | * @param $defaultValue
38 | * @return mixed
39 | */
40 | public function checkReturnValue($key, $defaultValue)
41 | {
42 | if ($defaultValue != "") {
43 | return $defaultValue;
44 | }
45 |
46 | return $this->getKeyValue($key);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | command('inspire')
28 | // ->hourly();
29 | }
30 |
31 | /**
32 | * Register the commands for the application.
33 | *
34 | * @return void
35 | */
36 | protected function commands()
37 | {
38 | $this->load(__DIR__.'/Commands');
39 |
40 | require base_path('routes/console.php');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/database/migrations/2016_09_03_051144_create_navigations_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('name');
19 | $table->string('url');
20 | $table->tinyInteger('state')->default(0)->comment('0-正常显示;1-隐藏');
21 | $table->smallInteger('sequence')->comment('排序');
22 | $table->tinyInteger('nav_type')->default(0)->comment('导航类型;0-自定义;1-分类导航');
23 | $table->integer('article_cate_id')->default(0)->comment('文章分类id');
24 | $table->timestamps();
25 | });
26 | }
27 |
28 | /**
29 | * Reverse the migrations.
30 | *
31 | * @return void
32 | */
33 | public function down()
34 | {
35 | Schema::drop('navigations');
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2016_08_28_145612_create_article_tags_table.php:
--------------------------------------------------------------------------------
1 | integer('article_id')->unsigned();
17 | $table->integer('tag_id')->unsigned();
18 | $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
19 | $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
20 | $table->index('article_id');
21 | $table->index('tag_id');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::drop('article_tags');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "npm run development",
5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
6 | "watch": "npm run development -- --watch",
7 | "watch-poll": "npm run watch -- --watch-poll",
8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
9 | "prod": "npm run production",
10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
11 | },
12 | "devDependencies": {
13 | "admin-lte": "^2.4.8",
14 | "bootstrap": "^4.0.0",
15 | "bootstrapvalidator": "^0.5.4",
16 | "cross-env": "^5.1",
17 | "inline-attachment": "^2.0.3",
18 | "jquery": "^3.2",
19 | "laravel-mix": "^2.0",
20 | "popper.js": "^1.12"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/resources/views/default/navigation.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @inject('navPresenter', 'App\Presenters\NavigationPresenter')
3 |
4 | simpleNavList(); ?>
5 | @if ($navigations)
6 | @foreach ($navigations as $navigation)
7 | {{ $navigation->name }}
8 | @endforeach
9 | @endif
10 |
11 |
21 |
--------------------------------------------------------------------------------
/config/compile.php:
--------------------------------------------------------------------------------
1 | [
17 | //
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled File Providers
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may list service providers which define a "compiles" function
26 | | that returns additional files that should be compiled, providing an
27 | | easy way to get common files from any packages you are utilizing.
28 | |
29 | */
30 |
31 | 'providers' => [
32 | //
33 | ],
34 |
35 | ];
36 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/LoginController.php:
--------------------------------------------------------------------------------
1 | middleware('guest')->except('logout');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/config/view.php:
--------------------------------------------------------------------------------
1 | [
17 | resource_path('views'),
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled View Path
23 | |--------------------------------------------------------------------------
24 | |
25 | | This option determines where all the compiled Blade templates will be
26 | | stored for your application. Typically, this is within the storage
27 | | directory. However, as usual, you are free to change this value.
28 | |
29 | */
30 |
31 | 'compiled' => realpath(storage_path('framework/views')),
32 |
33 | ];
34 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/ResetPasswordController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/Presenters/CategoryPresenter.php:
--------------------------------------------------------------------------------
1 | ";
27 | $select .= "--".$nullText."-- ";
28 | if ($category) {
29 | foreach ($category as $key => $value) {
30 | $selected = $key == $defaultCategoryId ? " selected " : "";
31 | $select .= "".$value." ";
32 | }
33 | }
34 | $select .= "";
35 |
36 | return $select;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/config/services.php:
--------------------------------------------------------------------------------
1 | [
18 | 'domain' => env('MAILGUN_DOMAIN'),
19 | 'secret' => env('MAILGUN_SECRET'),
20 | ],
21 |
22 | 'ses' => [
23 | 'key' => env('SES_KEY'),
24 | 'secret' => env('SES_SECRET'),
25 | 'region' => env('SES_REGION', 'us-east-1'),
26 | ],
27 |
28 | 'sparkpost' => [
29 | 'secret' => env('SPARKPOST_SECRET'),
30 | ],
31 |
32 | 'stripe' => [
33 | 'model' => App\User::class,
34 | 'key' => env('STRIPE_KEY'),
35 | 'secret' => env('STRIPE_SECRET'),
36 | ],
37 |
38 | ];
39 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/User/UpdateRequest.php:
--------------------------------------------------------------------------------
1 | route('user');
27 | return [
28 | 'name' => "required|min:2",
29 | 'email' => "required|email|unique:users,email,".$id,
30 | 'password' => 'between:8,30'
31 | ];
32 | }
33 |
34 | public function messages()
35 | {
36 | return [
37 | 'name.required' => '姓名必须填写',
38 | 'name.min' => '姓名最小不能小于两字符',
39 | 'email.required'=> '登录邮箱必须填写',
40 | 'email.unique'=> '登录邮箱必须唯一',
41 | 'email.email'=> '请填写合法的邮箱',
42 | 'password.between'=> '请填写8-30位的密码'
43 | ];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/Http/Requests/Backend/User/CreateRequest.php:
--------------------------------------------------------------------------------
1 | "required|min:2",
28 | 'email' => "required|email|unique:users",
29 | 'password' => 'required|between:8,30'
30 | ];
31 | }
32 |
33 | public function messages()
34 | {
35 | return [
36 | 'name.required' => '姓名必须填写',
37 | 'name.min' => '姓名最小不能小于两字符',
38 | 'email.required'=> '登录邮箱必须填写',
39 | 'email.unique'=> '登录邮箱必须唯一',
40 | 'email.email'=> '请填写合法的邮箱',
41 | 'password.required'=> '请填写登录密码',
42 | 'password.between'=> '请填写8-30位的密码'
43 | ];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/database/migrations/2016_09_24_132253_create_pages_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->string('title', 200)->default('')->comment('页面标题');
18 | $table->string('link_alias', 100)->nullable()->comment('链接别名');
19 | $table->string('keyword')->default('')->comment('keywords');
20 | $table->string('desc')->default('')->comment('描述');
21 | $table->longText('content')->nullable()->comment('页面markdown格式');
22 | $table->longText('html_content')->nullable()->comment('页面html');
23 | $table->timestamps();
24 | $table->unique('link_alias');
25 | $table->index('link_alias');
26 | });
27 | }
28 |
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::drop('pages');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests/Unit
14 |
15 |
16 |
17 | ./tests/Feature
18 |
19 |
20 |
21 |
22 | ./app
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/Exceptions/Handler.php:
--------------------------------------------------------------------------------
1 | middleware('auth');
39 | $this->middleware('signed')->only('verify');
40 | $this->middleware('throttle:6,1')->only('verify', 'resend');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/Http/Controllers/RssController.php:
--------------------------------------------------------------------------------
1 | System::keyValue('title'),
15 | 'link' => route('rss'),
16 | 'description' => $this->stringFormat(System::keyValue('seo_desc')),
17 | ];
18 |
19 | $rss = Rss::channel($channel);
20 |
21 | $articles = Article::query()->orderBy('id', 'desc')->simplePaginate(20);
22 | if ($articles) {
23 | foreach ($articles as $article) {
24 | $item = [
25 | 'title' => $article->title,
26 | 'description' => $this->stringFormat($article->desc),
27 | 'link' => route('article', ['id' => $article->id]),
28 | 'pubDate' => date('Y-m-d', strtotime($article->created_at))
29 | ];
30 |
31 | $rss->item($item);
32 | }
33 | }
34 |
35 | return response($rss, 200, ['Content-Type' => 'text/xml']);
36 | }
37 |
38 | private function stringFormat($string)
39 | {
40 | return sprintf("", $string);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/resources/views/errors/503.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Be right back.
5 |
6 |
7 |
8 |
39 |
40 |
41 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/database/migrations/2016_07_30_064321_create_categories_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
21 | $table->integer('parent_id')->nullable()->index();
22 | $table->integer('lft')->nullable()->index();
23 | $table->integer('rgt')->nullable()->index();
24 | $table->integer('depth')->nullable();
25 |
26 | // Add needed columns here (f.ex: name, slug, path, etc.)
27 | $table->string('name', 255);
28 |
29 | $table->timestamps();
30 | });
31 | }
32 |
33 | /**
34 | * Reverse the migrations.
35 | *
36 | * @return void
37 | */
38 | public function down() {
39 | Schema::drop('categories');
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/Models/Article.php:
--------------------------------------------------------------------------------
1 | hasMany('App\Models\ArticleTag', 'article_id', 'id');
24 | }
25 |
26 | public function getStatusAttribute($value)
27 | {
28 | return $value == 1 ? '私密' : '公开';
29 | }
30 |
31 | /**
32 | * article 与 tag 多对多关联
33 | *
34 | * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
35 | */
36 | public function tag()
37 | {
38 | return $this->belongsToMany('App\Models\Tag','article_tags', 'article_id', 'tag_id');
39 | }
40 |
41 | /**
42 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
43 | */
44 | public function category()
45 | {
46 | return $this->belongsTo('App\Models\Category', 'cate_id');
47 | }
48 |
49 | /**
50 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
51 | */
52 | public function user()
53 | {
54 | return $this->belongsTo('App\Models\User', 'user_id');
55 | }
56 |
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/resources/views/backend/tag/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '文章标签添加')
4 |
5 | @section('header')
6 |
7 | 文章标签添加
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.warning')
15 |
37 |
38 |
39 |
40 | @endsection
--------------------------------------------------------------------------------
/resources/views/default/author.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @inject('userPresenter', 'App\Presenters\UserPresenter')
3 | id) ? $user : $userPresenter->getUserInfo();
5 | ?>
6 |
7 |
{{ $author->name }}
8 |
9 |
10 |
11 |
12 |
13 |
33 |
34 |
--------------------------------------------------------------------------------
/resources/views/default/article.blade.php:
--------------------------------------------------------------------------------
1 | @if($articles)
2 |
3 | @foreach ($articles as $article)
4 |
5 |
10 |
11 | {{$article->desc}}
12 |
13 |
14 |
15 | {{ date('Y-m-d', strtotime($article->created_at)) }}
16 |
17 |
18 | @if($article->category)
19 |
20 |
21 |
22 | {{ $article->category->name }}
23 |
24 |
25 | @endif
26 |
27 | {{ $article->read_count }} views
28 |
29 |
30 |
31 | @endforeach
32 |
33 | {!! $articles->links() !!}
34 | @else
35 | 没有文章哟!!!
36 | @endif
--------------------------------------------------------------------------------
/resources/views/backend/tag/edit.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '文章标签修改')
4 |
5 | @section('header')
6 |
7 | 文章标签修改
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 | @include('backend.alert.warning')
14 |
39 |
40 | @endsection
--------------------------------------------------------------------------------
/resources/js/moell.js:
--------------------------------------------------------------------------------
1 | window.Moell = {};
2 |
3 | var _token = $("meta[name='csrf-token']").attr('content');
4 |
5 | (function(Moell) {
6 | Moell.ajax = {
7 | delete: function (url) {
8 |
9 | layer.confirm('你确认删除吗?', {
10 | btn: ['删除', '取消']
11 | }, function () {
12 | $.post(url, {'_method': "DELETE", '_token': _token}, function (data) {
13 | var msg;
14 | if (data.status == 0) {
15 | layer.msg('删除成功', {time: 5000, icon: 6});
16 | window.location.href = window.location.href;
17 | } else {
18 | msg = data.msg ? data.msg : '删除失败';
19 | layer.msg(msg, {time: 5000, icon: 5});
20 | }
21 | });
22 |
23 | }, function () {
24 | layer.close();
25 | })
26 | },
27 | postForm : function(url, data, method) {
28 | data._method = method;
29 | data._token = _token;
30 | $.post(url, data, function(data) {
31 | var msg;
32 | if (data.status == 0) {
33 | msg = data.msg ? data.msg : '操作成功';
34 | layer.msg(msg, {time: 5000, icon: 6});
35 | window.location.href = window.location.href;
36 | } else {
37 | msg = data.msg ? data.msg : '操作失败';
38 | layer.msg(msg, {time: 5000, icon: 5});
39 | }
40 | });
41 | },
42 | }
43 | })(Moell);
--------------------------------------------------------------------------------
/public/js/moell.js:
--------------------------------------------------------------------------------
1 | var Moell = window.Moell || {};
2 |
3 | var _token = $("meta[name='csrf-token']").attr('content');
4 |
5 | (function(Moell) {
6 | Moell.ajax = {
7 | delete: function (url) {
8 |
9 | layer.confirm('你确认删除吗?', {
10 | btn: ['删除', '取消']
11 | }, function () {
12 | $.post(url, {'_method': "DELETE", '_token': _token}, function (data) {
13 | var msg;
14 | if (data.status == 0) {
15 | layer.msg('删除成功', {time: 5000, icon: 6});
16 | window.location.href = window.location.href;
17 | } else {
18 | msg = data.msg ? data.msg : '删除失败';
19 | layer.msg(msg, {time: 5000, icon: 5});
20 | }
21 | });
22 |
23 | }, function () {
24 | layer.close();
25 | })
26 | },
27 | postForm : function(url, data, method) {
28 | data._method = method;
29 | data._token = _token;
30 | $.post(url, data, function(data) {
31 | var msg;
32 | if (data.status == 0) {
33 | msg = data.msg ? data.msg : '操作成功';
34 | layer.msg(msg, {time: 5000, icon: 6});
35 | window.location.href = window.location.href;
36 | } else {
37 | msg = data.msg ? data.msg : '操作失败';
38 | layer.msg(msg, {time: 5000, icon: 5});
39 | }
40 | });
41 | },
42 | }
43 | })(Moell);
--------------------------------------------------------------------------------
/database/migrations/2016_07_25_130523_create_articles_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
17 | $table->string('title', 200)->default('')->comment('文章标题');
18 | $table->string('keyword')->default('')->comment('keywords');
19 | $table->string('desc')->default('')->comment('描述');
20 | $table->longText('content')->nullable()->comment('文章内容,markdown格式');
21 | $table->integer('user_id')->default(0)->comment('文章编写人,对应users表');
22 | $table->integer('cate_id')->default(0)->comment('文章分类');
23 | $table->integer('comment_count')->default(0)->comment('评论数量');
24 | $table->integer('read_count')->default(0)->comment('阅读数量');
25 | $table->tinyInteger('status')->default(0)->comment('文章状态:0-公开;1-私密');
26 | $table->integer('sort')->default(0)->comment('排序');
27 | $table->timestamps();
28 | $table->index('cate_id');
29 | $table->index('user_id');
30 | $table->index('title');
31 | $table->index('created_at');
32 | });
33 | }
34 |
35 | /**
36 | * Reverse the migrations.
37 | *
38 | * @return void
39 | */
40 | public function down()
41 | {
42 | Schema::drop('articles');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/config/hashing.php:
--------------------------------------------------------------------------------
1 | 'bcrypt',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Bcrypt Options
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may specify the configuration options that should be used when
26 | | passwords are hashed using the Bcrypt algorithm. This will allow you
27 | | to control the amount of time it takes to hash the given password.
28 | |
29 | */
30 |
31 | 'bcrypt' => [
32 | 'rounds' => env('BCRYPT_ROUNDS', 10),
33 | ],
34 |
35 | /*
36 | |--------------------------------------------------------------------------
37 | | Argon Options
38 | |--------------------------------------------------------------------------
39 | |
40 | | Here you may specify the configuration options that should be used when
41 | | passwords are hashed using the Argon algorithm. These will allow you
42 | | to control the amount of time it takes to hash the given password.
43 | |
44 | */
45 |
46 | 'argon' => [
47 | 'memory' => 1024,
48 | 'threads' => 2,
49 | 'time' => 2,
50 | ],
51 |
52 | ];
53 |
--------------------------------------------------------------------------------
/resources/views/default/show_page.blade.php:
--------------------------------------------------------------------------------
1 | @inject('systemPresenter', 'App\Presenters\SystemPresenter')
2 |
3 | @extends('default.page')
4 |
5 | @section('title', $systemPresenter->checkReturnValue('title', $page->title))
6 |
7 | @section('description', $systemPresenter->checkReturnValue('seo_desc', $page->desc))
8 |
9 | @section('keywords', $systemPresenter->checkReturnValue('seo_keyword', $page->keyword))
10 |
11 | @section('style')
12 |
13 | @endsection
14 |
15 | @section('header-text')
16 |
17 |
18 |
19 |
20 | {{ $page->title }}
21 |
22 |
23 |
24 | {{ $page->desc }}
25 |
26 |
27 |
28 |
29 | @endsection
30 |
31 | @section('content')
32 |
33 | {!! $page->html_content !!}
34 |
35 |
36 |
39 |
40 | @include('default.comment.index', [
41 | 'commentId' => "page-".$page->id,
42 | 'commentTitle' => $page->title,
43 | 'commentUrl' => Request::getUri()
44 | ])
45 | @endsection
46 |
47 | @section('script')
48 |
49 |
50 |
55 |
56 | @endsection
57 |
--------------------------------------------------------------------------------
/bootstrap/app.php:
--------------------------------------------------------------------------------
1 | singleton(
30 | Illuminate\Contracts\Http\Kernel::class,
31 | App\Http\Kernel::class
32 | );
33 |
34 | $app->singleton(
35 | Illuminate\Contracts\Console\Kernel::class,
36 | App\Console\Kernel::class
37 | );
38 |
39 | $app->singleton(
40 | Illuminate\Contracts\Debug\ExceptionHandler::class,
41 | App\Exceptions\Handler::class
42 | );
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Return The Application
47 | |--------------------------------------------------------------------------
48 | |
49 | | This script returns the application instance. The instance is given to
50 | | the calling script so we can separate the building of the instances
51 | | from the actual running of the application and sending responses.
52 | |
53 | */
54 |
55 | return $app;
56 |
--------------------------------------------------------------------------------
/config/broadcasting.php:
--------------------------------------------------------------------------------
1 | env('BROADCAST_DRIVER', 'null'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Broadcast Connections
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may define all of the broadcast connections that will be used
26 | | to broadcast events to other systems or over websockets. Samples of
27 | | each available type of connection are provided inside this array.
28 | |
29 | */
30 |
31 | 'connections' => [
32 |
33 | 'pusher' => [
34 | 'driver' => 'pusher',
35 | 'key' => env('PUSHER_APP_KEY'),
36 | 'secret' => env('PUSHER_APP_SECRET'),
37 | 'app_id' => env('PUSHER_APP_ID'),
38 | 'options' => [
39 | 'cluster' => env('PUSHER_APP_CLUSTER'),
40 | 'encrypted' => true,
41 | ],
42 | ],
43 |
44 | 'redis' => [
45 | 'driver' => 'redis',
46 | 'connection' => 'default',
47 | ],
48 |
49 | 'log' => [
50 | 'driver' => 'log',
51 | ],
52 |
53 | 'null' => [
54 | 'driver' => 'null',
55 | ],
56 |
57 | ],
58 |
59 | ];
60 |
--------------------------------------------------------------------------------
/app/Providers/RouteServiceProvider.php:
--------------------------------------------------------------------------------
1 | mapApiRoutes();
39 |
40 | $this->mapWebRoutes();
41 |
42 | //
43 | }
44 |
45 | /**
46 | * Define the "web" routes for the application.
47 | *
48 | * These routes all receive session state, CSRF protection, etc.
49 | *
50 | * @return void
51 | */
52 | protected function mapWebRoutes()
53 | {
54 | Route::middleware('web')
55 | ->namespace($this->namespace)
56 | ->group(base_path('routes/web.php'));
57 | }
58 |
59 | /**
60 | * Define the "api" routes for the application.
61 | *
62 | * These routes are typically stateless.
63 | *
64 | * @return void
65 | */
66 | protected function mapApiRoutes()
67 | {
68 | Route::prefix('api')
69 | ->middleware('api')
70 | ->namespace($this->namespace)
71 | ->group(base_path('routes/api.php'));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(Illuminate\Contracts\Console\Kernel::class);
34 |
35 | $status = $kernel->handle(
36 | $input = new Symfony\Component\Console\Input\ArgvInput,
37 | new Symfony\Component\Console\Output\ConsoleOutput
38 | );
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Shutdown The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once Artisan has finished running, we will fire off the shutdown events
46 | | so that any final work may be done by the application before we shut
47 | | down the process. This is the last thing to happen to the request.
48 | |
49 | */
50 |
51 | $kernel->terminate($input, $status);
52 |
53 | exit($status);
54 |
--------------------------------------------------------------------------------
/resources/js/bootstrap.js:
--------------------------------------------------------------------------------
1 |
2 | window._ = require('lodash');
3 | window.Popper = require('popper.js').default;
4 |
5 | /**
6 | * We'll load jQuery and the Bootstrap jQuery plugin which provides support
7 | * for JavaScript based Bootstrap features such as modals and tabs. This
8 | * code may be modified to fit the specific needs of your application.
9 | */
10 |
11 | try {
12 | window.$ = window.jQuery = require('jquery');
13 |
14 | require('bootstrap');
15 | } catch (e) {}
16 |
17 | /**
18 | * We'll load the axios HTTP library which allows us to easily issue requests
19 | * to our Laravel back-end. This library automatically handles sending the
20 | * CSRF token as a header based on the value of the "XSRF" token cookie.
21 | */
22 |
23 | window.axios = require('axios');
24 |
25 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
26 |
27 | /**
28 | * Next we will register the CSRF Token as a common header with Axios so that
29 | * all outgoing HTTP requests automatically have it attached. This is just
30 | * a simple convenience so we don't have to attach every token manually.
31 | */
32 |
33 | let token = document.head.querySelector('meta[name="csrf-token"]');
34 |
35 | if (token) {
36 | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
37 | } else {
38 | console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
39 | }
40 |
41 | /**
42 | * Echo exposes an expressive API for subscribing to channels and listening
43 | * for events that are broadcast by Laravel. Echo and event broadcasting
44 | * allows your team to easily build robust real-time web applications.
45 | */
46 |
47 | // import Echo from 'laravel-echo'
48 |
49 | // window.Pusher = require('pusher-js');
50 |
51 | // window.Echo = new Echo({
52 | // broadcaster: 'pusher',
53 | // key: process.env.MIX_PUSHER_APP_KEY,
54 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER,
55 | // encrypted: true
56 | // });
57 |
--------------------------------------------------------------------------------
/resources/views/backend/category/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '文章分分类添加')
4 |
5 | @section('header')
6 |
7 | 文章分分类添加
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.warning')
15 |
46 |
47 |
48 |
49 | @endsection
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/AuthController.php:
--------------------------------------------------------------------------------
1 | 'required|max:255',
43 | 'email' => 'required|email|max:255|unique:users',
44 | 'password' => 'required|min:6|confirmed',
45 | ]);
46 | }
47 |
48 | /**
49 | * Create a new user instance after a valid registration.
50 | *
51 | * @param array $data
52 | * @return User
53 | */
54 | protected function create(array $data)
55 | {
56 | return User::create([
57 | 'name' => $data['name'],
58 | 'email' => $data['email'],
59 | 'password' => bcrypt($data['password']),
60 | ]);
61 | }
62 |
63 | public function showLoginForm()
64 | {
65 | return view('backend.login');
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 |
10 | define('LARAVEL_START', microtime(true));
11 |
12 | /*
13 | |--------------------------------------------------------------------------
14 | | Register The Auto Loader
15 | |--------------------------------------------------------------------------
16 | |
17 | | Composer provides a convenient, automatically generated class loader for
18 | | our application. We just need to utilize it! We'll simply require it
19 | | into the script here so that we don't have to worry about manual
20 | | loading any of our classes later on. It feels great to relax.
21 | |
22 | */
23 |
24 | require __DIR__.'/../vendor/autoload.php';
25 |
26 | /*
27 | |--------------------------------------------------------------------------
28 | | Turn On The Lights
29 | |--------------------------------------------------------------------------
30 | |
31 | | We need to illuminate PHP development, so let us turn on the lights.
32 | | This bootstraps the framework and gets it ready for use, then it
33 | | will load up this application so that we can run it and send
34 | | the responses back to the browser and delight our users.
35 | |
36 | */
37 |
38 | $app = require_once __DIR__.'/../bootstrap/app.php';
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Run The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once we have the application, we can handle the incoming request
46 | | through the kernel, and send the associated response back to
47 | | the client's browser allowing them to enjoy the creative
48 | | and wonderful application we have prepared for them.
49 | |
50 | */
51 |
52 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
53 |
54 | $response = $kernel->handle(
55 | $request = Illuminate\Http\Request::capture()
56 | );
57 |
58 | $response->send();
59 |
60 | $kernel->terminate($request, $response);
61 |
--------------------------------------------------------------------------------
/resources/views/backend/category/edit.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '文章分类修改')
4 |
5 | @section('header')
6 |
7 | 文章分类修改
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 | @include('backend.alert.warning')
14 |
48 |
49 | @endsection
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/RegisterController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
41 | }
42 |
43 | /**
44 | * Get a validator for an incoming registration request.
45 | *
46 | * @param array $data
47 | * @return \Illuminate\Contracts\Validation\Validator
48 | */
49 | protected function validator(array $data)
50 | {
51 | return Validator::make($data, [
52 | 'name' => 'required|string|max:255',
53 | 'email' => 'required|string|email|max:255|unique:users',
54 | 'password' => 'required|string|min:6|confirmed',
55 | ]);
56 | }
57 |
58 | /**
59 | * Create a new user instance after a valid registration.
60 | *
61 | * @param array $data
62 | * @return \App\User
63 | */
64 | protected function create(array $data)
65 | {
66 | return User::create([
67 | 'name' => $data['name'],
68 | 'email' => $data['email'],
69 | 'password' => Hash::make($data['password']),
70 | ]);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## Moell Blog
2 |
3 | Moell Blog 是一个基于Laravel5.7 开发并支持markdown语法的博客。
4 |
5 | ### 功能
6 | * 支持Markdown, 文章实时预览效果
7 | * 图片拖拽上传
8 | * 支持七牛云存储
9 | * 支持多种编程语言代码高亮
10 | * 文章搜索
11 | * 文章分类
12 | * 文章标签
13 | * 自定义导航,分类设置为导航
14 | * 友情链接
15 | * 自定义页面
16 | * RSS
17 | * 评论插件 disqus
18 |
19 | ### 截图
20 |
21 | 
22 |
23 | ### 前端演示地址
24 | 查看 [moell](http://moell.cn "moell")
25 |
26 | ### 安装
27 |
28 | 获取源码
29 | ```shell
30 | git clone https://github.com/moell-peng/moell-blog.git
31 | ```
32 |
33 | 进入项目目录
34 | ```shell
35 | cd moell-blog
36 | ```
37 |
38 | 安装项目依赖
39 | ```shell
40 | composer install
41 | ```
42 |
43 | 生成.env
44 | ```shell
45 | cp .env.example .env
46 | php artisan key:generate
47 | ```
48 |
49 | 编辑.env环境配置
50 |
51 | ```shell
52 | APP_URL=http://localhost #使用本地文件系统存储文件时,必须填写正确地址
53 | APP_DEBUG=true #关闭调试
54 |
55 | DB_HOST= #数据库地址
56 | DB_PORT=3306 #数据库端口
57 | DB_DATABASE= #数据库名称
58 | DB_USERNAME= #数据库用户
59 | DB_PASSWORD= #数据库密码
60 | ```
61 |
62 | 默认下使用了本地文件系统,需执行 `php artisan storage:link` 来创建符号链接。 可以通过 `BLOG_DISK` 来进行配置,支持 qiniu 和 public ,qiniu 配置请参照 filesystem.php 。
63 |
64 |
65 |
66 | 运行数据迁移和数据填充
67 | ```shell
68 | php artisan migrate
69 | php artisan db:seed
70 | ```
71 |
72 |
73 |
74 | 将项目根目录指向入口public目录
75 |
76 | **Nginx**
77 |
78 | ```shell
79 | location / {
80 | root /www/moell-blog/public;
81 | try_files $uri $uri/ /index.php?$query_string;
82 | index index.php index.html index.htm;
83 | }
84 | ```
85 |
86 | 设置目录权限
87 | ```shell
88 | chown -R nginx:nginx storage/
89 | chmod -R 755 public/
90 | chown -R nginx:nginx public/
91 | ```
92 | 调优
93 | > 部署到线上可选,本地测试无需执行
94 |
95 | ```shell
96 | php artisan optimize
97 | php artisan config:cache
98 | php artisan route:cache
99 | ```
100 |
101 |
102 | 后台登录, 后台地址: 域名/backend , email:moell@foxmail.com , password : moell.cn
103 |
104 |
105 |
106 | ### 讨论群
107 | QQ:339803849 (欢迎PHPer,Laravel爱好者加入)
108 |
109 | ### License
110 | * 使用Moell Blog构建应用,必须在页脚添加上Powered by Moell Blog字样,并且Moell Blog 必须链接到http://www.moell.cn
111 | * 在遵守以上规则的情况下,你可以享受等同于 [MIT license](http://opensource.org/licenses/MIT) 协议的授权。
112 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moell/moell-blog",
3 | "description": "The Moell Blog.",
4 | "keywords": ["blog", "laravel", "markdown blog", "php blog", "moell blog"],
5 | "license": "MIT",
6 | "type": "project",
7 | "require": {
8 | "php": "^7.1.3",
9 | "baum/baum": "~1.1",
10 | "doctrine/dbal": "^2.5",
11 | "fideloper/proxy": "^4.0",
12 | "laravel/framework": "5.7.*",
13 | "laravel/tinker": "^1.0",
14 | "moell/laravel-rss": "1.*",
15 | "zgldh/qiniu-laravel-storage": "^0.10.0"
16 | },
17 | "require-dev": {
18 | "barryvdh/laravel-debugbar": "^3.2",
19 | "barryvdh/laravel-ide-helper": "^2.5",
20 | "beyondcode/laravel-dump-server": "^1.0",
21 | "filp/whoops": "^2.0",
22 | "fzaninotto/faker": "^1.4",
23 | "mockery/mockery": "^1.0",
24 | "nunomaduro/collision": "^2.0",
25 | "phpunit/phpunit": "^7.0"
26 | },
27 | "autoload": {
28 | "classmap": [
29 | "database/seeds",
30 | "database/factories"
31 | ],
32 | "psr-4": {
33 | "App\\": "app/"
34 | }
35 | },
36 | "autoload-dev": {
37 | "psr-4": {
38 | "Tests\\": "tests/"
39 | }
40 | },
41 | "extra": {
42 | "laravel": {
43 | "dont-discover": [
44 | ]
45 | }
46 | },
47 | "scripts": {
48 | "post-root-package-install": [
49 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
50 | ],
51 | "post-create-project-cmd": [
52 | "@php artisan key:generate --ansi"
53 | ],
54 | "post-autoload-dump": [
55 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
56 | "@php artisan package:discover --ansi"
57 | ],
58 | "post-update-cmd": [
59 | "Illuminate\\Foundation\\ComposerScripts::postUpdate",
60 | "php artisan ide-helper:generate",
61 | "php artisan ide-helper:meta"
62 | ]
63 | },
64 | "config": {
65 | "preferred-install": "dist",
66 | "sort-packages": true,
67 | "optimize-autoloader": true
68 | },
69 | "minimum-stability": "dev",
70 | "prefer-stable": true
71 | }
72 |
--------------------------------------------------------------------------------
/resources/views/backend/link/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '友情链接添加')
4 |
5 | @section('header')
6 |
7 | 友情链接添加
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.warning')
15 |
53 |
54 |
55 |
56 | @endsection
--------------------------------------------------------------------------------
/resources/views/backend/upload/upload.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '文件资源上传')
4 |
5 | @section('header')
6 |
7 | 文件资源上传
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.warning')
15 | @include('backend.alert.success')
16 |
56 |
57 |
58 |
59 | @endsection
--------------------------------------------------------------------------------
/resources/views/backend/home.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', 'Moell Blog')
4 |
5 | @section('header')
6 |
7 | Home
8 | Moell Blog
9 |
10 | @endsection
11 |
12 | @section('content')
13 |
18 |
19 |
20 |
21 |
开发者信息
22 |
Name : moell
23 |
Email : moell91@foxmail.com
24 |
博客地址 : moell
25 |
项目地址 : Github
26 |
27 |
依赖开源程序
28 |
59 |
关于问题反馈
60 |
61 | 可以发送Email,或者在Github上反馈遇到的问题,看到后会逐一帮助解决问题,务必将问题描述清楚。
62 |
63 |
64 |
65 |
66 | @endsection
--------------------------------------------------------------------------------
/routes/web.php:
--------------------------------------------------------------------------------
1 | name('article');
17 |
18 | Route::get('/category/{id}', 'CategoryController@index')->name('category');
19 |
20 | Route::get('/tag/{id}', 'TagController@index')->name('tag');
21 |
22 | Route::get('/search', 'SearchController@index')->name('search');
23 |
24 | Route::get('/page/{alias}', 'PageController@index')->name('page.show');
25 |
26 | Route::get('/about', 'PageController@about')->name('about');
27 |
28 | Route::get('/rss', 'RssController@index')->name('rss');
29 |
30 | Route::namespace('Backend')->prefix('backend')->group(function () {
31 |
32 | Route::get('/login', 'AuthController@showLoginForm')->name('backend.login');
33 |
34 | Route::post('/login', 'AuthController@login');
35 |
36 | Route::get('/logout', 'AuthController@logout');
37 |
38 |
39 | Route::group(['middleware' => ['auth', 'reject-null-values']], function(){
40 |
41 | Route::get('/', 'HomeController@index')->name('backend.home');
42 |
43 | Route::post('/upload/image', 'UploadController@image');
44 |
45 | Route::resource('article', 'ArticleController', ['as' => 'backend']);
46 |
47 | Route::resource('category', 'CategoryController', ['as' => 'backend']);
48 |
49 | Route::get('category/set-nav/{id}', ['as' => 'backend.category.set-nav', 'uses' => 'CategoryController@setNavigation']);
50 |
51 | Route::resource('user', 'UserController', ['as' => 'backend']);
52 |
53 | Route::resource('tag', 'TagController', ['as' => 'backend']);
54 |
55 | Route::resource('link', 'LinkController', ['as' => 'backend']);
56 |
57 | Route::resource('navigation', 'NavigationController', ['as' => 'backend']);
58 |
59 | Route::resource('page', 'PageController', ['as' => 'backend']);
60 |
61 | Route::get('system', 'SystemController@index')->name('backend.system.index');
62 |
63 | Route::post('system', 'SystemController@store')->name('backend.system.store');
64 | });
65 | });
66 |
--------------------------------------------------------------------------------
/config/blog.php:
--------------------------------------------------------------------------------
1 | env('BLOG_DISK', 'public'),
5 | 'system_key' => [
6 | 'blog_name',
7 | 'motto',
8 | 'title',
9 | 'seo_keyword',
10 | 'seo_desc',
11 | 'icp',
12 | 'github_url',
13 | 'weibo_url',
14 | 'disqus_short_name',
15 | 'comment_plugin',
16 | 'statistics_script'
17 | ],
18 | 'menu' => [
19 | [
20 | 'backend.home' => [
21 | 'icon' => 'fa fa-home',
22 | 'name' => 'Home'
23 | ]
24 |
25 | ],
26 | [
27 | 'tree_title' => [
28 | 'icon' => 'fa fa-files-o',
29 | 'name' => '文章'
30 | ],
31 | 'backend.article.index' => [
32 | 'icon' => '',
33 | 'name' => '文章管理'
34 | ],
35 | 'backend.article.create' => [
36 | 'icon' => '',
37 | 'name' => '发布文章'
38 | ],
39 | 'backend.category.index' => [
40 | 'icon' => '',
41 | 'name' => '文章分类'
42 | ]
43 | ],
44 | [
45 | 'backend.tag.index' => [
46 | 'icon' => 'fa fa-tags',
47 | 'name' => '标签'
48 | ]
49 | ],
50 | [
51 | 'backend.navigation.index' => [
52 | 'icon' => 'fa fa-navicon',
53 | 'name' => '导航'
54 | ]
55 | ],
56 | [
57 | 'tree_title' => [
58 | 'icon' => 'fa fa-user',
59 | 'name' => '用户'
60 | ],
61 | 'backend.user.index' => [
62 | 'icon' => '',
63 | 'name' => '用户管理'
64 | ],
65 | 'backend.user.create' => [
66 | 'icon' => '',
67 | 'name' => '用户添加'
68 | ]
69 | ],
70 | [
71 | 'tree_title' => [
72 | 'icon' => 'fa fa-cog',
73 | 'name' => '设置'
74 | ],
75 | 'backend.system.index' => [
76 | 'icon' => '',
77 | 'name' => '系统设置'
78 | ],
79 | 'backend.link.index' => [
80 | 'icon' => '',
81 | 'name' => '友情链接'
82 | ],
83 | 'backend.page.index' => [
84 | 'icon' => '',
85 | 'name' => '自定义页面'
86 | ]
87 | ]
88 | ]
89 | ];
--------------------------------------------------------------------------------
/app/Presenters/BackendPresenter.php:
--------------------------------------------------------------------------------
1 | route = Route::currentRouteName();
14 | $menu = config('blog.menu');
15 |
16 | $menuString = '';
17 | foreach ($menu as $mList) {
18 |
19 | $count = count($mList);
20 | if ($count > 1) {
21 | $menuString .= $this->childrenShow($mList);
22 | } else {
23 | $menuString .= $this->parentShow($mList);
24 | }
25 | }
26 |
27 | return $menuString;
28 | }
29 |
30 | /**
31 | * @param $menu
32 | * @return string
33 | */
34 | private function childrenShow($menu)
35 | {
36 | $string = '';
37 | $string .= '
38 |
39 | '.$menu['tree_title']['name'].'
40 |
41 | ';
42 |
43 | unset($menu['tree_title']);
44 | $string .='';
45 | $liString = '';
46 | $active = '';
47 | foreach ($menu as $route => $m) {
48 | $activeString = $this->active($route);
49 | if ($activeString != "") {
50 | $active = $activeString;
51 | }
52 | $liString .= " ".$m['name']." ";
53 | }
54 |
55 | $string .= '';
56 | $string = sprintf($string, $active, $liString);
57 |
58 | return $string;
59 | }
60 |
61 | /**
62 | * @param $menu
63 | * @return string
64 | */
65 | private function parentShow($menu)
66 | {
67 | $string = '';
68 | foreach ($menu as $route => $m) {
69 | $string.= "
70 |
71 |
72 | ".$m['name']."
73 |
74 | ";
75 | }
76 |
77 | return $string;
78 | }
79 |
80 | /**
81 | * @param $route
82 | * @return string
83 | */
84 | private function active($route)
85 | {
86 | return $this->route == $route ? ' active' : '';
87 | }
88 | }
--------------------------------------------------------------------------------
/resources/views/backend/link/edit.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '友情链接修改')
4 |
5 | @section('header')
6 |
7 | 友情链接修改
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 | @include('backend.alert.warning')
14 |
55 |
56 | @endsection
--------------------------------------------------------------------------------
/config/logging.php:
--------------------------------------------------------------------------------
1 | env('LOG_CHANNEL', 'stack'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Log Channels
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may configure the log channels for your application. Out of
26 | | the box, Laravel uses the Monolog PHP logging library. This gives
27 | | you a variety of powerful log handlers / formatters to utilize.
28 | |
29 | | Available Drivers: "single", "daily", "slack", "syslog",
30 | | "errorlog", "monolog",
31 | | "custom", "stack"
32 | |
33 | */
34 |
35 | 'channels' => [
36 | 'stack' => [
37 | 'driver' => 'stack',
38 | 'channels' => ['single'],
39 | ],
40 |
41 | 'single' => [
42 | 'driver' => 'single',
43 | 'path' => storage_path('logs/laravel.log'),
44 | 'level' => 'debug',
45 | ],
46 |
47 | 'daily' => [
48 | 'driver' => 'daily',
49 | 'path' => storage_path('logs/laravel.log'),
50 | 'level' => 'debug',
51 | 'days' => 7,
52 | ],
53 |
54 | 'slack' => [
55 | 'driver' => 'slack',
56 | 'url' => env('LOG_SLACK_WEBHOOK_URL'),
57 | 'username' => 'Laravel Log',
58 | 'emoji' => ':boom:',
59 | 'level' => 'critical',
60 | ],
61 |
62 | 'stderr' => [
63 | 'driver' => 'monolog',
64 | 'handler' => StreamHandler::class,
65 | 'with' => [
66 | 'stream' => 'php://stderr',
67 | ],
68 | ],
69 |
70 | 'syslog' => [
71 | 'driver' => 'syslog',
72 | 'level' => 'debug',
73 | ],
74 |
75 | 'errorlog' => [
76 | 'driver' => 'errorlog',
77 | 'level' => 'debug',
78 | ],
79 | ],
80 |
81 | ];
82 |
--------------------------------------------------------------------------------
/app/Http/Kernel.php:
--------------------------------------------------------------------------------
1 | [
31 | \App\Http\Middleware\EncryptCookies::class,
32 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
33 | \Illuminate\Session\Middleware\StartSession::class,
34 | // \Illuminate\Session\Middleware\AuthenticateSession::class,
35 | \Illuminate\View\Middleware\ShareErrorsFromSession::class,
36 | \App\Http\Middleware\VerifyCsrfToken::class,
37 | \Illuminate\Routing\Middleware\SubstituteBindings::class,
38 | ],
39 |
40 | 'api' => [
41 | 'throttle:60,1',
42 | 'bindings',
43 | ],
44 | ];
45 |
46 | /**
47 | * The application's route middleware.
48 | *
49 | * These middleware may be assigned to groups or used individually.
50 | *
51 | * @var array
52 | */
53 | protected $routeMiddleware = [
54 | 'auth' => \App\Http\Middleware\Authenticate::class,
55 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
56 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
57 | 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
58 | 'can' => \Illuminate\Auth\Middleware\Authorize::class,
59 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
60 | 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
61 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
62 | 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
63 | 'reject-null-values' => \App\Http\Middleware\RejectNullValues::class
64 | ];
65 | }
66 |
--------------------------------------------------------------------------------
/resources/views/default/show_article.blade.php:
--------------------------------------------------------------------------------
1 | @inject('systemPresenter', 'App\Presenters\SystemPresenter')
2 |
3 | @extends('layouts.app')
4 |
5 | @section('title', $systemPresenter->checkReturnValue('title', $article->title))
6 |
7 | @section('description', $systemPresenter->checkReturnValue('seo_desc', $article->desc))
8 |
9 | @section('keywords', $systemPresenter->checkReturnValue('seo_keyword', $article->keyword))
10 |
11 | @section('style')
12 |
13 | @endsection
14 |
15 | @section('header-text')
16 |
45 | @endsection
46 |
47 | @section('content')
48 |
49 | {!! $article->html_content !!}
50 |
51 |
52 |
53 |
54 | @include('default.comment.index', [
55 | 'commentId' => $article->id,
56 | 'commentTitle' => $article->title,
57 | 'commentUrl' => Request::getUri()
58 | ])
59 | @endsection
60 |
61 | @section('script')
62 |
63 |
64 |
69 |
70 | @endsection
71 |
--------------------------------------------------------------------------------
/public/default/css/index.css:
--------------------------------------------------------------------------------
1 | .navbar {
2 | margin-bottom: 0;
3 | }
4 | .navbar-default, .jumbotron {
5 | background-color: #3D93A3;
6 | }
7 |
8 | .navbar-default, .jumbotron a{
9 | color: white;
10 | }
11 |
12 | .navbar-default .navbar-nav>li>a {
13 | color: white;
14 | }
15 |
16 | .navbar-default .navbar-brand {
17 | color: white;
18 | }
19 |
20 | .navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover {
21 | color: white;
22 | background-color: transparent;
23 | }
24 |
25 |
26 | .navbar-static-top {
27 | border-width: 0 0 0;
28 | }
29 |
30 | .panel {
31 | border-radius: 0;
32 | }
33 |
34 | .panel-heading {
35 | background-color: #fff;
36 | }
37 |
38 | .panel-default>.panel-heading {
39 | color: #3D93A3;
40 | background-color: white;
41 | border-color: #ddd
42 | }
43 |
44 | .color-white {
45 | color:white;
46 | }
47 |
48 | .article-list {
49 | padding-left: 0;
50 | list-style: none;
51 | }
52 |
53 | .article-list li {
54 | padding-bottom: 10px;
55 | }
56 |
57 | .m-t-25 {
58 | margin-top:25px;
59 | }
60 |
61 | .article-list .title {
62 | font-size:16px;
63 | }
64 |
65 | .article-list .desc {
66 | margin-top:15px;
67 | word-break:break-all;
68 | color:#616161;
69 | }
70 |
71 | .article-list .info {
72 | margin-top:15px;
73 | color:#616161;
74 | }
75 |
76 | .article-list .info span {
77 | padding-right: 5px;
78 | }
79 | .icon-github {
80 | background: url('/default/icons/github.png') no-repeat;
81 | background-size: 16px 16px;
82 | }
83 |
84 | .icon-sina-weibo {
85 | background: url('/default/icons/weibo.png') no-repeat;
86 | background-size: 16px 16px;
87 | }
88 |
89 | #footer {
90 | border-top:1px solid #ddd;
91 | margin-top:20px;
92 | height:60px;
93 | background-color: #fafafa;
94 | background: -webkit-linear-gradient(#fafafa, #ffffff); /* Safari 5.1 - 6.0 */
95 | background: -o-linear-gradient(#fafafa #ffffff); /* Opera 11.1 - 12.0 */
96 | background: -moz-linear-gradient(#fafafa, #ffffff); /* Firefox 3.6 - 15 */
97 | background: linear-gradient(#fafafa, #ffffff); /* 标准的语法 */
98 | }
99 |
100 | .author .author-footer{
101 | margin-top:20px;
102 | }
103 |
104 | .author .author-avatar {
105 | max-width:150px;
106 | }
107 |
108 | a {
109 | color: #34495e;
110 | }
111 |
112 | .markdown-preview img{
113 | max-width: 100%;
114 | }
115 |
116 | .markdown-preview table td, .markdown-preview table th {
117 | border: 1px solid #ddd;
118 | padding: 5px;
119 | }
120 |
121 | pre {
122 | padding:0;
123 | }
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/TagController.php:
--------------------------------------------------------------------------------
1 | paginate();
20 |
21 | return view('backend.tag.index', compact('tags'));
22 | }
23 |
24 | /**
25 | * Show the form for creating a new resource.
26 | *
27 | * @return \Illuminate\Http\Response
28 | */
29 | public function create()
30 | {
31 | return view('backend.tag.create');
32 | }
33 |
34 | /**
35 | * Store a newly created resource in storage.
36 | *
37 | * @param CreateRequest $request
38 | * @return \Illuminate\Http\RedirectResponse
39 | */
40 | public function store(CreateRequest $request)
41 | {
42 | Tag::create(['tag_name' => $request->name]);
43 |
44 | return redirect()->route('backend.tag.index')->with('success', '标签添加成功');
45 | }
46 |
47 | /**
48 | * Display the specified resource.
49 | *
50 | * @param int $id
51 | * @return \Illuminate\Http\Response
52 | */
53 | public function show($id)
54 | {
55 | //
56 | }
57 |
58 | /**
59 | * Show the form for editing the specified resource.
60 | *
61 | * @param int $id
62 | * @return \Illuminate\Http\Response
63 | */
64 | public function edit($id)
65 | {
66 | $tag = Tag::findOrFail($id);
67 |
68 | return view("backend.tag.edit", compact('tag'));
69 | }
70 |
71 | /**
72 | * Update the specified resource in storage.
73 | *
74 | * @param UpdateRequest $request
75 | * @param $id
76 | * @return \Illuminate\Http\RedirectResponse
77 | */
78 | public function update(UpdateRequest $request, $id)
79 | {
80 | $tag = Tag::findOrFail($id);
81 |
82 | $tag->tag_name = $request->name;
83 | $tag->save();
84 |
85 | return redirect()->route('backend.tag.index')->with('success', '标签修改成功');
86 | }
87 |
88 | /**
89 | * Remove the specified resource from storage.
90 | *
91 | * @param int $id
92 | * @return \Illuminate\Http\Response
93 | */
94 | public function destroy($id)
95 | {
96 | return Tag::destroy($id) ? response()->json(['status' => 0]) : response()->json(['status' => 1]);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/LinkController.php:
--------------------------------------------------------------------------------
1 | all());
44 |
45 | return redirect()->route('backend.link.index')->with('success', '友情链接添加成功');
46 | }
47 |
48 | /**
49 | * Display the specified resource.
50 | *
51 | * @param int $id
52 | * @return \Illuminate\Http\Response
53 | */
54 | public function show($id)
55 | {
56 | //
57 | }
58 |
59 | /**
60 | * Show the form for editing the specified resource.
61 | *
62 | * @param int $id
63 | * @return \Illuminate\Http\Response
64 | */
65 | public function edit($id)
66 | {
67 | $link = Link::find($id);
68 |
69 | return view('backend.link.edit', compact('link'));
70 | }
71 |
72 | /**
73 | * Update the specified resource in storage.
74 | *
75 | * @param UpdateRequest $request
76 | * @param $id
77 | * @return \Illuminate\Http\RedirectResponse
78 | */
79 | public function update(UpdateRequest $request, $id)
80 | {
81 | $link = Link::findOrFail($id);
82 |
83 | $link->fill($request->all());
84 | $link->save();
85 |
86 | return redirect()->route('backend.link.index')->with('success', '友情链接修改成功');
87 | }
88 |
89 | /**
90 | * Remove the specified resource from storage.
91 | *
92 | * @param int $id
93 | * @return \Illuminate\Http\Response
94 | */
95 | public function destroy($id)
96 | {
97 | return Link::destroy($id) ? response()->json(['status' => 0]) : response()->json(['status' => 0]);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/resources/views/backend/link/index.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '友情链接')
4 |
5 | @section('header')
6 |
7 | 友情链接
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.success')
15 |
16 |
17 |
26 |
27 |
28 |
29 | 名字
30 | 排序
31 | URL
32 | 操作
33 |
34 | @if ($links)
35 | @foreach($links as $link)
36 |
37 | {{ $link->name }}
38 | {{ $link->sequence }}
39 | {{ $link->url }}
40 |
41 |
42 | 修改
43 | 删除
45 |
46 |
47 | @endforeach
48 | @endif
49 |
50 |
51 |
52 |
53 |
54 |
55 | @endsection
56 |
57 | @section('javascript')
58 |
66 | @endsection
--------------------------------------------------------------------------------
/resources/views/backend/page/index.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '自定义页面管理')
4 |
5 | @section('header')
6 |
7 | 自定义页面管理
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.success')
15 |
16 |
23 |
24 |
25 |
26 |
27 | 标题
28 | 链接名
29 | 关键字
30 | 描述
31 | 操作
32 |
33 | @inject('pagePresenter', 'App\Presenters\PagePresenter')
34 | @if($pages)
35 | @foreach($pages as $page)
36 |
37 | {{ $page->title }}
38 | {{ $pagePresenter->getLink($page->id, $page->link_alias) }}
39 | {{ $page->keyword }}
40 | {{ $page->desc }}
41 |
42 |
43 | 修改
44 | 删除
46 |
47 |
48 | @endforeach
49 | @endif
50 |
51 |
52 |
53 |
54 |
55 |
56 | @endsection
57 |
58 | @section('javascript')
59 |
67 | @endsection
--------------------------------------------------------------------------------
/resources/views/backend/user/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '博客用户添加')
4 |
5 | @section('header')
6 |
7 | 博客用户添加
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.warning')
15 |
62 |
63 |
64 |
65 | @endsection
--------------------------------------------------------------------------------
/config/queue.php:
--------------------------------------------------------------------------------
1 | env('QUEUE_CONNECTION', 'sync'),
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Queue Connections
21 | |--------------------------------------------------------------------------
22 | |
23 | | Here you may configure the connection information for each server that
24 | | is used by your application. A default configuration has been added
25 | | for each back-end shipped with Laravel. You are free to add more.
26 | |
27 | | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
28 | |
29 | */
30 |
31 | 'connections' => [
32 |
33 | 'sync' => [
34 | 'driver' => 'sync',
35 | ],
36 |
37 | 'database' => [
38 | 'driver' => 'database',
39 | 'table' => 'jobs',
40 | 'queue' => 'default',
41 | 'retry_after' => 90,
42 | ],
43 |
44 | 'beanstalkd' => [
45 | 'driver' => 'beanstalkd',
46 | 'host' => 'localhost',
47 | 'queue' => 'default',
48 | 'retry_after' => 90,
49 | ],
50 |
51 | 'sqs' => [
52 | 'driver' => 'sqs',
53 | 'key' => env('SQS_KEY', 'your-public-key'),
54 | 'secret' => env('SQS_SECRET', 'your-secret-key'),
55 | 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
56 | 'queue' => env('SQS_QUEUE', 'your-queue-name'),
57 | 'region' => env('SQS_REGION', 'us-east-1'),
58 | ],
59 |
60 | 'redis' => [
61 | 'driver' => 'redis',
62 | 'connection' => 'default',
63 | 'queue' => 'default',
64 | 'retry_after' => 90,
65 | 'block_for' => null,
66 | ],
67 |
68 | ],
69 |
70 | /*
71 | |--------------------------------------------------------------------------
72 | | Failed Queue Jobs
73 | |--------------------------------------------------------------------------
74 | |
75 | | These options configure the behavior of failed queue job logging so you
76 | | can control which database and table are used to store the jobs that
77 | | have failed. You may change them to any database / table you wish.
78 | |
79 | */
80 |
81 | 'failed' => [
82 | 'database' => env('DB_CONNECTION', 'mysql'),
83 | 'table' => 'failed_jobs',
84 | ],
85 |
86 | ];
87 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/NavigationController.php:
--------------------------------------------------------------------------------
1 | with([
20 | 'category'
21 | ])->orderBy('sequence', 'desc')->get();
22 |
23 | return view('backend.navigation.index', compact('navigations'));
24 | }
25 |
26 | /**
27 | * Show the form for creating a new resource.
28 | *
29 | * @return \Illuminate\Http\Response
30 | */
31 | public function create()
32 | {
33 | return view('backend.navigation.create');
34 | }
35 |
36 | /**
37 | * Store a newly created resource in storage.
38 | *
39 | * @param CreateRequest $request
40 | * @return \Illuminate\Http\RedirectResponse
41 | */
42 | public function store(CreateRequest $request)
43 | {
44 | Navigation::create($request->all());
45 |
46 | return redirect()->route('backend.navigation.index')->with('success', '导航添加成功');
47 | }
48 |
49 | /**
50 | * Display the specified resource.
51 | *
52 | * @param int $id
53 | * @return \Illuminate\Http\Response
54 | */
55 | public function show($id)
56 | {
57 | //
58 | }
59 |
60 | /**
61 | * Show the form for editing the specified resource.
62 | *
63 | * @param int $id
64 | * @return \Illuminate\Http\Response
65 | */
66 | public function edit($id)
67 | {
68 | $navigation = Navigation::findOrFail($id);
69 |
70 | return view('backend.navigation.edit', compact('navigation'));
71 | }
72 |
73 | /**
74 | * Update the specified resource in storage.
75 | *
76 | * @param UpdateRequest $request
77 | * @param $id
78 | * @return \Illuminate\Http\RedirectResponse
79 | */
80 | public function update(UpdateRequest $request, $id)
81 | {
82 | $navigation = Navigation::findOrFail($id);
83 |
84 | $navigation->fill($request->all());
85 | $navigation->save();
86 |
87 | return redirect()->route('backend.navigation.index')->with('success', '导航修改成功');
88 | }
89 |
90 | /**
91 | * Remove the specified resource from storage.
92 | *
93 | * @param int $id
94 | * @return \Illuminate\Http\Response
95 | */
96 | public function destroy($id)
97 | {
98 | return Navigation::destroy($id) ? response()->json(['status' => 0]) : response()->json(['status' => 1]);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/resources/views/backend/navigation/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '导航添加')
4 |
5 | @section('header')
6 |
7 | 导航添加
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.warning')
15 |
64 |
65 |
66 |
67 | @endsection
--------------------------------------------------------------------------------
/config/cache.php:
--------------------------------------------------------------------------------
1 | env('CACHE_DRIVER', 'file'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Cache Stores
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may define all of the cache "stores" for your application as
26 | | well as their drivers. You may even define multiple stores for the
27 | | same cache driver to group types of items stored in your caches.
28 | |
29 | */
30 |
31 | 'stores' => [
32 |
33 | 'apc' => [
34 | 'driver' => 'apc',
35 | ],
36 |
37 | 'array' => [
38 | 'driver' => 'array',
39 | ],
40 |
41 | 'database' => [
42 | 'driver' => 'database',
43 | 'table' => 'cache',
44 | 'connection' => null,
45 | ],
46 |
47 | 'file' => [
48 | 'driver' => 'file',
49 | 'path' => storage_path('framework/cache/data'),
50 | ],
51 |
52 | 'memcached' => [
53 | 'driver' => 'memcached',
54 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
55 | 'sasl' => [
56 | env('MEMCACHED_USERNAME'),
57 | env('MEMCACHED_PASSWORD'),
58 | ],
59 | 'options' => [
60 | // Memcached::OPT_CONNECT_TIMEOUT => 2000,
61 | ],
62 | 'servers' => [
63 | [
64 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'),
65 | 'port' => env('MEMCACHED_PORT', 11211),
66 | 'weight' => 100,
67 | ],
68 | ],
69 | ],
70 |
71 | 'redis' => [
72 | 'driver' => 'redis',
73 | 'connection' => 'cache',
74 | ],
75 |
76 | ],
77 |
78 | /*
79 | |--------------------------------------------------------------------------
80 | | Cache Key Prefix
81 | |--------------------------------------------------------------------------
82 | |
83 | | When utilizing a RAM based store such as APC or Memcached, there might
84 | | be other applications utilizing the same cache. So, we'll specify a
85 | | value to get prefixed to all our keys so we can avoid collisions.
86 | |
87 | */
88 |
89 | 'prefix' => env(
90 | 'CACHE_PREFIX',
91 | str_slug(env('APP_NAME', 'laravel'), '_').'_cache'
92 | ),
93 |
94 | ];
95 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Backend/PageController.php:
--------------------------------------------------------------------------------
1 | basicFields($request));
44 |
45 | return redirect()->route('backend.page.index')->with('success', '创建成功');
46 | }
47 |
48 | /**
49 | * Display the specified resource.
50 | *
51 | * @param int $id
52 | * @return \Illuminate\Http\Response
53 | */
54 | public function show($id)
55 | {
56 | //
57 | }
58 |
59 | /**
60 | * Show the form for editing the specified resource.
61 | *
62 | * @param int $id
63 | * @return \Illuminate\Http\Response
64 | */
65 | public function edit($id)
66 | {
67 | $page = Page::findOrFail($id);
68 |
69 | return view('backend.page.edit', compact('page'));
70 | }
71 |
72 | /**
73 | * Update the specified resource in storage.
74 | *
75 | * @param UpdateRequest $request
76 | * @param $id
77 | * @return \Illuminate\Http\RedirectResponse
78 | */
79 | public function update(UpdateRequest $request, $id)
80 | {
81 | $page = Page::findOrFail($id);
82 |
83 | $page->fill($this->basicFields($request));
84 | $page->save();
85 |
86 | return redirect()->route('backend.page.index')->with('success', '修改成功');
87 | }
88 |
89 | private function basicFields(Request $request)
90 | {
91 | $html = $html = (new \Parsedown())->parse($request->get('content'));
92 |
93 | return array_merge($request->all(), ['html_content' => $html]);
94 | }
95 |
96 | /**
97 | * Remove the specified resource from storage.
98 | *
99 | * @param int $id
100 | * @return \Illuminate\Http\Response
101 | */
102 | public function destroy($id)
103 | {
104 | return Page::destroy($id) ? response()->json(['status' => 0]) : response()->json(['status' => 1]);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/resources/views/backend/category/index.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.backend')
2 |
3 | @section('title', '文章分类')
4 |
5 | @section('header')
6 |
7 | 文章分类
8 |
9 | @endsection
10 |
11 | @section('content')
12 |
13 |
14 | @include('backend.alert.success')
15 |
16 |
17 |
26 |
27 |
28 |
29 | 序号
30 | 分类名
31 | 操作
32 |
33 | @if ($category)
34 |
35 | @foreach($category as $id => $cate_name)
36 |
37 | {{ $line }}
38 | {!! $cate_name !!}
39 |
40 |
41 | 修改
42 |
43 | 设为导航
44 |
45 | 删除
47 |
48 |
49 |
50 | @endforeach
51 | @endif
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | @endsection
60 |
61 | @section('javascript')
62 |
70 | @endsection
--------------------------------------------------------------------------------
/resources/views/layouts/app.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | @yield('title')
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | @yield('style')
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | @inject('systemPresenter', 'App\Presenters\SystemPresenter')
30 |
31 |
32 |
41 | @include('default.navigation')
42 |
43 |
44 |
45 |
46 |
47 |
48 | @yield('header-text')
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | @yield('content')
57 |
58 |
59 | @include('default.author')
60 |
61 | @include('default.tag')
62 |
63 | @include('default.hot')
64 |
65 | @include('default.link')
66 |
67 |
68 |
69 |
70 |
71 | @include('default.footer')
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
86 |
87 | @yield('script')
88 |
89 |