├── public ├── favicon.ico ├── robots.txt ├── images │ └── logo.png ├── fonts │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ └── vendor │ │ ├── _social-share.js@1.0.16@social-share.js │ │ └── dist │ │ │ ├── iconfont.eot │ │ │ ├── iconfont.ttf │ │ │ └── iconfont.woff │ │ ├── _@fortawesome_fontawesome-free-webfonts@1.0.4@@fortawesome │ │ ├── fontawesome-free-webwebfa-solid-900.eot │ │ ├── fontawesome-free-webwebfa-solid-900.ttf │ │ ├── fontawesome-free-webwebfa-brands-400.eot │ │ ├── fontawesome-free-webwebfa-brands-400.ttf │ │ ├── fontawesome-free-webwebfa-brands-400.woff │ │ ├── fontawesome-free-webwebfa-regular-400.eot │ │ ├── fontawesome-free-webwebfa-regular-400.ttf │ │ ├── fontawesome-free-webwebfa-solid-900.woff │ │ ├── fontawesome-free-webwebfa-solid-900.woff2 │ │ ├── fontawesome-free-webwebfa-brands-400.woff2 │ │ ├── fontawesome-free-webwebfa-regular-400.woff │ │ └── fontawesome-free-webwebfa-regular-400.woff2 │ │ └── _@fortawesome_fontawesome-free-webfonts@1.0.5@@fortawesome │ │ ├── fontawesome-free-webwebfa-solid-900.eot │ │ ├── fontawesome-free-webwebfa-solid-900.ttf │ │ ├── fontawesome-free-webwebfa-brands-400.eot │ │ ├── fontawesome-free-webwebfa-brands-400.ttf │ │ ├── fontawesome-free-webwebfa-brands-400.woff │ │ ├── fontawesome-free-webwebfa-regular-400.eot │ │ ├── fontawesome-free-webwebfa-regular-400.ttf │ │ ├── fontawesome-free-webwebfa-solid-900.woff │ │ ├── fontawesome-free-webwebfa-solid-900.woff2 │ │ ├── fontawesome-free-webwebfa-brands-400.woff2 │ │ ├── fontawesome-free-webwebfa-regular-400.woff │ │ └── fontawesome-free-webwebfa-regular-400.woff2 ├── vendor │ └── horizon │ │ ├── css │ │ └── app.css.map │ │ ├── img │ │ └── favicon.png │ │ └── mix-manifest.json ├── mix-manifest.json ├── .htaccess └── js │ └── manifest.js ├── database ├── .gitignore ├── factories │ ├── CategoryFactory.php │ ├── TagFactory.php │ ├── ReplyFactory.php │ ├── DiscusstionFactory.php │ ├── UserFactory.php │ ├── ArticleFactory.php │ └── CommentFactory.php ├── seeds │ ├── CommentsTableSeeder.php │ ├── DiscusstionTableSeeder.php │ ├── TagsTableSeeder.php │ ├── CategoriesTableSeeder.php │ ├── DiscussionsTableSeeder.php │ ├── ArticlesTableSeeder.php │ ├── UsersTableSeeder.php │ ├── DatabaseSeeder.php │ └── MakeDiscussionSolvedSeeder.php └── migrations │ ├── 2017_05_28_025409_create_categories_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2017_05_28_031123_create_tags_table.php │ ├── 2017_05_28_030133_create_replies_table.php │ ├── 2017_05_28_031151_create_taggables_table.php │ ├── 2017_06_22_100627_create_special_pages_table.php │ ├── 2017_05_28_030521_create_activities_table.php │ ├── 2018_01_14_204314_create_notifications_table.php │ ├── 2018_02_27_171949_create_failed_jobs_table.php │ ├── 2017_05_28_030506_create_favorites_table.php │ ├── 2017_06_01_095839_create_comments_table.php │ ├── 2017_12_13_225211_create_subscriptions_table.php │ ├── 2017_12_10_223853_add_outh_field_to_users_table.php │ ├── 2017_11_19_115928_seed_special_pages_data.php │ ├── 2018_02_06_142849_create_drafts_table.php │ ├── 2018_01_29_211051_create_discussions_table.php │ ├── 2014_10_12_000000_create_users_table.php │ └── 2017_05_28_025758_create_articles_table.php ├── bootstrap ├── cache │ └── .gitignore └── autoload.php ├── resources ├── assets │ ├── js │ │ ├── libs.js │ │ ├── components │ │ │ ├── Home │ │ │ │ ├── DeleteUser.vue │ │ │ │ └── Menus.vue │ │ │ ├── Parse.vue │ │ │ ├── Example.vue │ │ │ ├── BestAnswer.vue │ │ │ └── Paginator.vue │ │ ├── router.js │ │ ├── global.js │ │ └── pages │ │ │ └── Article.vue │ └── sass │ │ ├── vender │ │ └── fontawesome │ │ │ ├── webfonts │ │ │ ├── fa-brands-400.eot │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-brands-400.woff │ │ │ ├── fa-regular-400.eot │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-solid-900.eot │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff │ │ │ ├── fa-solid-900.woff2 │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.woff │ │ │ └── fa-regular-400.woff2 │ │ │ ├── _fixed-width.scss │ │ │ ├── _screen-reader.scss │ │ │ ├── _core.scss │ │ │ ├── _animated.scss │ │ │ ├── _list.scss │ │ │ ├── _larger.scss │ │ │ ├── fontawesome.scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _stacked.scss │ │ │ ├── fa-brands.scss │ │ │ ├── fa-solid.scss │ │ │ ├── fa-regular.scss │ │ │ ├── _rotated-flipped.scss │ │ │ └── _mixins.scss │ │ ├── _navbar.scss │ │ ├── helpers.scss │ │ ├── home.scss │ │ ├── overrite.scss │ │ ├── app.scss │ │ └── _variables.scss ├── views │ ├── vendor │ │ ├── mail │ │ │ ├── markdown │ │ │ │ ├── panel.blade.php │ │ │ │ ├── table.blade.php │ │ │ │ ├── footer.blade.php │ │ │ │ ├── promotion.blade.php │ │ │ │ ├── subcopy.blade.php │ │ │ │ ├── button.blade.php │ │ │ │ ├── header.blade.php │ │ │ │ ├── promotion │ │ │ │ │ └── button.blade.php │ │ │ │ ├── layout.blade.php │ │ │ │ └── message.blade.php │ │ │ └── html │ │ │ │ ├── table.blade.php │ │ │ │ ├── header.blade.php │ │ │ │ ├── subcopy.blade.php │ │ │ │ ├── promotion.blade.php │ │ │ │ ├── footer.blade.php │ │ │ │ ├── panel.blade.php │ │ │ │ ├── promotion │ │ │ │ └── button.blade.php │ │ │ │ ├── message.blade.php │ │ │ │ └── button.blade.php │ │ ├── flash │ │ │ ├── modal.blade.php │ │ │ └── message.blade.php │ │ ├── pagination │ │ │ ├── simple-bootstrap-4.blade.php │ │ │ ├── admin.blade.php │ │ │ ├── bootstrap-4.blade.php │ │ │ └── default.blade.php │ │ └── notifications │ │ │ └── email.blade.php │ ├── articles │ │ ├── partials │ │ │ ├── archive.blade.php │ │ │ └── user.blade.php │ │ ├── create_new.blade.php │ │ ├── create.blade.php │ │ └── edit.blade.php │ ├── users │ │ ├── activities │ │ │ ├── activity.blade.php │ │ │ ├── created_article.blade.php │ │ │ └── created_comment.blade.php │ │ ├── partials │ │ │ └── setting_nav.blade.php │ │ ├── editAvatar.blade.php │ │ └── show.blade.php │ ├── admin │ │ └── partials │ │ │ ├── errors.blade.php │ │ │ └── slide_menu.blade.php │ ├── drafts │ │ ├── edit.blade.php │ │ └── show.blade.php │ ├── notifications │ │ ├── partials │ │ │ ├── nav.blade.php │ │ │ ├── article_was_subscribed.blade.php │ │ │ ├── article_was_favorited.blade.php │ │ │ ├── comment_was_favorited.blade.php │ │ │ ├── discussion_was_favorited.blade.php │ │ │ ├── discussion_was_subscribed.blade.php │ │ │ ├── article_was_updated.blade.php │ │ │ └── answer_was_update_best.blade.php │ │ └── index.blade.php │ ├── home.blade.php │ ├── layouts │ │ └── partials │ │ │ ├── footer.blade.php │ │ │ └── category.blade.php │ ├── discussions │ │ └── index.blade.php │ └── special_pages │ │ └── edit.blade.php └── lang │ ├── en │ ├── pagination.php │ ├── auth.php │ └── passwords.php │ └── zh-CN │ ├── pagination.php │ ├── auth.php │ └── passwords.php ├── storage ├── debugbar │ └── .gitignore ├── logs │ └── .gitignore ├── app │ ├── public │ │ └── .gitignore │ └── .gitignore └── framework │ ├── cache │ └── .gitignore │ ├── testing │ └── .gitignore │ ├── views │ └── .gitignore │ ├── sessions │ └── .gitignore │ └── .gitignore ├── .rnd ├── .gitattributes ├── app ├── Models │ ├── Reply.php │ ├── SpecialPage.php │ ├── Favorite.php │ ├── Activity.php │ ├── Subscription.php │ ├── Category.php │ └── Tag.php ├── Notifications │ ├── NotificationMappable.php │ ├── ArticleWasFavorited.php │ ├── AnswerWasUpdateBest.php │ └── CommentWasFavorited.php ├── Http │ ├── Controllers │ │ ├── Web │ │ │ ├── ReplyController.php │ │ │ ├── ActivityController.php │ │ │ ├── FavoriteController.php │ │ │ ├── TagsController.php │ │ │ ├── CommentsController.php │ │ │ ├── HomeController.php │ │ │ ├── CategoriesController.php │ │ │ ├── DraftsController.php │ │ │ ├── NotificationsController.php │ │ │ ├── SpecialPagesController.php │ │ │ └── SessionsController.php │ │ ├── Api │ │ │ ├── ApiController.php │ │ │ ├── CategoriesController.php │ │ │ ├── TagsController.php │ │ │ ├── FilesController.php │ │ │ ├── AuthenticateController.php │ │ │ ├── SubscriptionsController.php │ │ │ ├── UsersController.php │ │ │ ├── DraftsController.php │ │ │ └── FavoriteController.php │ │ ├── Controller.php │ │ ├── HomeController.php │ │ ├── Admin │ │ │ ├── HomeController.php │ │ │ └── UsersController.php │ │ └── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ └── ResetPasswordController.php │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── VerifyCsrfToken.php │ │ ├── TrimStrings.php │ │ ├── MustBeAdmin.php │ │ └── RedirectIfAuthenticated.php │ ├── Resources │ │ ├── TagResource.php │ │ ├── UserResource.php │ │ ├── ArchiveResource.php │ │ ├── CategoryResource.php │ │ ├── SpecialPageResource.php │ │ ├── DraftResource.php │ │ ├── FavoriteResource.php │ │ ├── CommentResource.php │ │ ├── DiscussionResource.php │ │ └── ArticleResource.php │ ├── Flash.php │ └── Requests │ │ ├── UpdateUserRequest.php │ │ ├── SubscribeRequest.php │ │ └── FavoriteRequest.php ├── Observers │ ├── ArticleObserver.php │ └── DiscussionObserver.php ├── Providers │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ ├── OAuthServiceProvider.php │ └── AuthServiceProvider.php ├── Base │ ├── Exceptions │ │ ├── SubscribeException.php │ │ └── FavoriteException.php │ ├── Handler │ │ └── NotificationHandler.php │ ├── Filters │ │ ├── Filters.php │ │ └── ArticleFilters.php │ ├── Traits │ │ ├── SlugTransable.php │ │ ├── ContentSetable.php │ │ ├── GetModelByMorpType.php │ │ └── Subscribable.php │ ├── Helpers.php │ └── Service │ │ └── Markdowner.php ├── Policies │ ├── UserPolicy.php │ ├── SpecialPagePolicy.php │ ├── CommentPolicy.php │ ├── DiscussionPolicy.php │ ├── ArticlePolicy.php │ └── DraftPolicy.php ├── Scopes │ └── ArticleFitterScope.php ├── Console │ └── Kernel.php └── Jobs │ └── TranslateSlug.php ├── tests ├── TestCase.php ├── Feature │ ├── ArticlesTest.php │ └── ExampleTest.php ├── Unit │ └── ExampleTest.php └── CreatesApplication.php ├── .gitignore ├── config ├── note.php ├── hashing.php ├── image.php ├── view.php ├── trustedproxy.php └── hashids.php ├── routes ├── channels.php └── console.php ├── server.php ├── .eslintrc.json ├── webpack.mix.js ├── .env.example ├── phpunit.xml └── package.json /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /resources/assets/js/libs.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.rnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/.rnd -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/panel.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/table.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/footer.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/promotion.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/subcopy.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }} 2 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/button.blade.php: -------------------------------------------------------------------------------- 1 | {{ $slot }}: {{ $url }} 2 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/header.blade.php: -------------------------------------------------------------------------------- 1 | [{{ $slot }}]({{ $url }}) 2 | -------------------------------------------------------------------------------- /resources/assets/js/components/Home/DeleteUser.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/articles/partials/archive.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/images/logo.png -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/promotion/button.blade.php: -------------------------------------------------------------------------------- 1 | [{{ $slot }}]({{ $url }}) 2 | -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /public/vendor/horizon/css/app.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"/css/app.css","sources":[],"mappings":";;;;;A","sourceRoot":""} -------------------------------------------------------------------------------- /public/vendor/horizon/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/vendor/horizon/img/favicon.png -------------------------------------------------------------------------------- /resources/views/vendor/mail/html/table.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {{ Illuminate\Mail\Markdown::parse($slot) }} 3 |
4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /app/Models/Reply.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{ $heading }} 4 |
5 | 6 | {{ $body }} 7 | 8 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/html/header.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ $slot }} 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /public/fonts/vendor/_social-share.js@1.0.16@social-share.js/dist/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/fonts/vendor/_social-share.js@1.0.16@social-share.js/dist/iconfont.eot -------------------------------------------------------------------------------- /public/fonts/vendor/_social-share.js@1.0.16@social-share.js/dist/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/fonts/vendor/_social-share.js@1.0.16@social-share.js/dist/iconfont.ttf -------------------------------------------------------------------------------- /public/fonts/vendor/_social-share.js@1.0.16@social-share.js/dist/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowiwj/Note/HEAD/public/fonts/vendor/_social-share.js@1.0.16@social-share.js/dist/iconfont.woff -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | text-align: center; 5 | width: (20em / 16); 6 | } 7 | -------------------------------------------------------------------------------- /resources/views/articles/create_new.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | 4 | @section('content') 5 | 6 | 7 | 8 | 9 | 10 | @endsection -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only; } 5 | .sr-only-focusable { @include sr-only-focusable; } 6 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 0) 2 | @foreach($errors->all() as $value) 3 | 4 | 5 | {{$value}} 6 | 7 | @endforeach 8 | @endif -------------------------------------------------------------------------------- /resources/views/drafts/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | 4 | @section('content') 5 | 6 | <{{ $draft->source }}-draft-editor draft-ref="{{ $draft->ref }}"> 7 | 8 | source }}-draft-editor> 9 | 10 | @endsection -------------------------------------------------------------------------------- /app/Http/Controllers/Web/ReplyController.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ Illuminate\Mail\Markdown::parse($slot) }} 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/uploads 4 | /public/storage 5 | /storage/*.key 6 | /vendor 7 | /.idea 8 | /.vagrant 9 | Homestead.json 10 | Homestead.yaml 11 | npm-debug.log 12 | .env 13 | npm-debug.log 14 | .DS_Store 15 | */.DS_Store 16 | -------------------------------------------------------------------------------- /app/Http/Controllers/Web/ActivityController.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ Illuminate\Mail\Markdown::parse($slot) }} 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /config/note.php: -------------------------------------------------------------------------------- 1 | env('GOOGLE_ANALYTICS_ID'), 7 | 8 | 'meta' => [ 9 | 'keywords' => '简记,时光笔记,Note,WJNote,Notes,laravel', 10 | 'description' => '简记是一个简单的文章记录平台,你可以在上面发表想法与讨论,简洁沟通' 11 | ] 12 | 13 | 14 | ]; -------------------------------------------------------------------------------- /public/vendor/horizon/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.js?id=954d5c3669f5448e61ac", 3 | "/css/app.css": "/css/app.css?id=5ce9973b1bc9f6a46cb2", 4 | "/js/app.js.map": "/js/app.js.map?id=e00843e66e9dfd3e036c", 5 | "/css/app.css.map": "/css/app.css.map?id=5d0439ebaab1434c7ea0" 6 | } -------------------------------------------------------------------------------- /tests/Feature/ArticlesTest.php: -------------------------------------------------------------------------------- 1 | name }} 发表文章 4 | {{ $activity->subject->title }} 5 | @endslot 6 | 7 | @slot('body') 8 | @endslot 9 | @endcomponent -------------------------------------------------------------------------------- /app/Http/Controllers/Api/ApiController.php: -------------------------------------------------------------------------------- 1 | morphMany(Comment::class,'commentable'); 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /database/factories/CategoryFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Models\Category::class, function (Faker $faker) { 8 | $name = $faker->name; 9 | return [ 10 | 'name' => $name, 11 | 'slug' => str_slug($name), 12 | ]; 13 | }); -------------------------------------------------------------------------------- /database/seeds/CommentsTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /resources/assets/sass/_navbar.scss: -------------------------------------------------------------------------------- 1 | 2 | #nav-avatar-container{ 3 | 4 | 5 | } 6 | #nav-avatar-container .nav-avatar{ 7 | width: 26px; 8 | height: 26px; 9 | border: 1px solid white; 10 | border-radius: 50%; 11 | margin:0; 12 | margin-right: 5px; 13 | } 14 | 15 | nav{ 16 | 17 | margin-bottom: 20px; 18 | 19 | } 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/Models/Favorite.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /database/seeds/DiscusstionTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /database/seeds/TagsTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.js?id=391d511c7c552008ef80", 3 | "/css/app.css": "/css/app.css?id=cbb3a40984b8aead2e25", 4 | "/css/home.css": "/css/home.css?id=b09aa4e638216c2859bc", 5 | "/js/vendor.js": "/js/vendor.js?id=f9a981cdc29a4c9a34bf", 6 | "/js/home.js": "/js/home.js?id=07c8e77dd42181503b85", 7 | "/js/manifest.js": "/js/manifest.js?id=0225916a5d4fbc86a881" 8 | } -------------------------------------------------------------------------------- /resources/views/vendor/mail/html/footer.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | define(\App\Models\Tag::class, function (Faker $faker) { 8 | 9 | $name = $faker->name; 10 | 11 | return [ 12 | 'name' => $name, 13 | 'slug' => str_slug($faker->name), 14 | 'message' => $faker->sentence 15 | ]; 16 | }); 17 | -------------------------------------------------------------------------------- /database/seeds/CategoriesTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /database/seeds/DiscussionsTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Observers/ArticleObserver.php: -------------------------------------------------------------------------------- 1 | slug) { 15 | $article->slug = app(SlugTranslateHandler::class)->translate($article->title); 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/_animated.scss: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | animation: fa-spin 2s infinite linear; 6 | } 7 | 8 | .#{$fa-css-prefix}-pulse { 9 | animation: fa-spin 1s infinite steps(8); 10 | } 11 | 12 | @keyframes fa-spin { 13 | 0% { 14 | transform: rotate(0deg); 15 | } 16 | 17 | 100% { 18 | transform: rotate(360deg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | li { position: relative; } 10 | } 11 | 12 | .#{$fa-css-prefix}-li { 13 | left: -$fa-li-width; 14 | position: absolute; 15 | text-align: center; 16 | width: $fa-li-width; 17 | line-height: inherit; 18 | } 19 | -------------------------------------------------------------------------------- /tests/Unit/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/views/notifications/partials/nav.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/Observers/DiscussionObserver.php: -------------------------------------------------------------------------------- 1 | slug = app(SlugTranslateHandler::class)->translate($discussion->title); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /database/factories/ReplyFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Models\Reply::class, function (Faker $faker) { 8 | 9 | $user_id = App\Models\User::pluck('id')->random(); 10 | $article_id = App\Models\Article::pluck('id')->random(); 11 | return [ 12 | 'user_id' => $user_id, 13 | 'article_id' => $article_id, 14 | 'body' => $faker->paragraph 15 | ]; 16 | }); -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/html/panel.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 |
4 | 5 | 6 | 9 | 10 |
7 | {{ Illuminate\Mail\Markdown::parse($slot) }} 8 |
11 |
14 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/html/promotion/button.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 |
4 | 5 | 6 | 9 | 10 |
7 | {{ $slot }} 8 |
11 |
14 | -------------------------------------------------------------------------------- /resources/assets/js/router.js: -------------------------------------------------------------------------------- 1 | 2 | import Main from './components/Home.vue' 3 | import Parent from './components/Home/Parent.vue' 4 | 5 | 6 | export default [ 7 | { 8 | path: '/', 9 | component: Parent, 10 | children: [ 11 | { 12 | path: '/', 13 | redirect: '/home' 14 | }, 15 | { 16 | path: 'home', 17 | component: require('./components/Home/Main.vue') 18 | } 19 | ] 20 | 21 | } 22 | ] -------------------------------------------------------------------------------- /app/Base/Exceptions/SubscribeException.php: -------------------------------------------------------------------------------- 1 | failed($this->message,$this->code); 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /app/Policies/UserPolicy.php: -------------------------------------------------------------------------------- 1 | id == $currentUser->id; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | // makes the font 33% larger relative to the icon container 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -.0667em; 9 | } 10 | 11 | .#{$fa-css-prefix}-xs { 12 | font-size: .75em; 13 | } 14 | 15 | .#{$fa-css-prefix}-sm { 16 | font-size: .875em; 17 | } 18 | 19 | @for $i from 1 through 10 { 20 | .#{$fa-css-prefix}-#{$i}x { 21 | font-size: $i * 1em; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/fontawesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.6 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | @import 'mixins'; 7 | @import 'core'; 8 | @import 'larger'; 9 | @import 'fixed-width'; 10 | @import 'list'; 11 | @import 'bordered-pulled'; 12 | @import 'animated'; 13 | @import 'rotated-flipped'; 14 | @import 'stacked'; 15 | @import 'icons'; 16 | @import 'screen-reader'; 17 | -------------------------------------------------------------------------------- /resources/views/users/partials/setting_nav.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/layouts/partials/footer.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/seeds/ArticlesTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /database/seeds/UsersTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 16 | $user = \App\Models\User::find(1); 17 | $user->email="35649084@qq.com"; 18 | $user->password=bcrypt('123456'); 19 | $user->is_admin = 1; 20 | $user->save(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /database/factories/DiscusstionFactory.php: -------------------------------------------------------------------------------- 1 | define(\App\Models\Discussion::class, function (Faker $faker) { 8 | $user_id = App\Models\User::pluck('id')->random(); 9 | $title = $faker->sentence; 10 | 11 | return [ 12 | 'user_id' => $user_id, 13 | 'title' => $title, 14 | 'slug' => mt_rand(0,4) > 2 ? str_slug($title) : null, 15 | 'content' => $faker->paragraph 16 | 17 | ]; 18 | }); 19 | -------------------------------------------------------------------------------- /app/Policies/SpecialPagePolicy.php: -------------------------------------------------------------------------------- 1 | is_admin; 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Base/Exceptions/FavoriteException.php: -------------------------------------------------------------------------------- 1 | failed($this->message,$this->code); 21 | 22 | } 23 | 24 | 25 | } -------------------------------------------------------------------------------- /app/Http/Resources/TagResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 19 | 'name' => $this->name, 20 | 'slug' => $this->slug 21 | 22 | ]; 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Models\User::class, function (Faker $faker) { 8 | static $password; 9 | 10 | return [ 11 | 'name' => $faker->name, 12 | 'email' => $faker->unique()->safeEmail, 13 | 'password' => $password ?: $password = bcrypt('secret'), 14 | 'remember_token' => str_random(10), 15 | 'activated' => 1, 16 | 'avatar' => $faker->imageUrl(200,200), 17 | ]; 18 | }); -------------------------------------------------------------------------------- /resources/assets/sass/helpers.scss: -------------------------------------------------------------------------------- 1 | $spaceamounts: (5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100); // Adjust this to include the pixel amounts you need. 2 | $sides: (top, bottom, left, right); // Leave this variable alone 3 | 4 | @each $space in $spaceamounts { 5 | @each $side in $sides { 6 | .m-#{str-slice($side, 0, 1)}-#{$space} { 7 | margin-#{$side}: #{$space}px; 8 | } 9 | 10 | .p-#{str-slice($side, 0, 1)}-#{$space} { 11 | padding-#{$side}: #{$space}px; 12 | } 13 | } 14 | } 15 | 16 | .is-fullwidth { 17 | width: 100%; 18 | } -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | border: solid .08em $fa-border-color; 6 | border-radius: .1em; 7 | padding: .2em .25em .15em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix}, 14 | .fas, 15 | .far, 16 | .fal, 17 | .fab { 18 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 19 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 20 | 21 | $response->assertStatus(200); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | -------------------------------------------------------------------------------- /app/Http/Resources/UserResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 21 | 'name' => $this->name, 22 | 'avatar' => $this->avatar, 23 | 24 | ]; 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 16 | ]; -------------------------------------------------------------------------------- /app/Http/Resources/ArchiveResource.php: -------------------------------------------------------------------------------- 1 | $this->year, 19 | 'month' => $this->month, 20 | 'published' => $this->published 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/CategoriesController.php: -------------------------------------------------------------------------------- 1 | paginate(); 13 | return CategoryResource::collection($categories); 14 | } 15 | 16 | public function all() 17 | { 18 | $categories = Category::all(); 19 | return CategoryResource::collection($categories); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Policies/CommentPolicy.php: -------------------------------------------------------------------------------- 1 | id == $comment->user->id; 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Controllers/HomeController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 17 | } 18 | 19 | /** 20 | * Show the application dashboard. 21 | * 22 | * @return \Illuminate\Http\Response 23 | */ 24 | public function index() 25 | { 26 | return view('home'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Http/Middleware/MustBeAdmin.php: -------------------------------------------------------------------------------- 1 | is_admin){ 21 | abort(404); 22 | } 23 | 24 | 25 | return $next($request); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /config/image.php: -------------------------------------------------------------------------------- 1 | 'gd' 19 | 20 | ); 21 | -------------------------------------------------------------------------------- /app/Scopes/ArticleFitterScope.php: -------------------------------------------------------------------------------- 1 | where('category_id', '!=', null); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/zh-CN/pagination.php: -------------------------------------------------------------------------------- 1 | '« 上一页', 17 | 'next' => '下一页 »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /app/Http/Resources/CategoryResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 19 | 'name' => $this->name, 20 | 'slug' => $this->slug, 21 | 'created_at' => $this->created_at->toDateTimeString() 22 | ]; 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | define(App\Models\Article::class, function (Faker $faker) { 8 | 9 | $user_id = App\Models\User::pluck('id')->random(); 10 | $category_id = App\Models\Category::pluck('id')->random(); 11 | $title = $faker->sentence; 12 | 13 | return [ 14 | 'user_id' => $user_id, 15 | 'category_id' => $category_id, 16 | 'title' => $title, 17 | 'slug' => mt_rand(0,4) > 2 ? str_slug($title) : null, 18 | 'content' => $faker->paragraph 19 | ]; 20 | }); -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Redirect Trailing Slashes If Not A Folder... 9 | RewriteCond %{REQUEST_FILENAME} !-d 10 | RewriteRule ^(.*)/$ /$1 [L,R=301] 11 | 12 | # Handle Front Controller... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_FILENAME} !-f 15 | RewriteRule ^ index.php [L] 16 | 17 | # Handle Authorization Header 18 | RewriteCond %{HTTP:Authorization} . 19 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 20 | 21 | -------------------------------------------------------------------------------- /resources/lang/zh-CN/auth.php: -------------------------------------------------------------------------------- 1 | '用户名或密码错误。', 17 | 'throttle' => '您的尝试登录次数过多. 请 :seconds 秒后再试。', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /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/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Policies/DiscussionPolicy.php: -------------------------------------------------------------------------------- 1 | is_admin; 14 | } 15 | 16 | /** 17 | * Create a new policy instance. 18 | * 19 | * @return void 20 | */ 21 | public function __construct() 22 | { 23 | // 24 | } 25 | 26 | 27 | public function update(User $user,Discussion $discussion) 28 | { 29 | 30 | return $user->id == $discussion->user->id; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | display: inline-block; 6 | height: 2em; 7 | line-height: 2em; 8 | position: relative; 9 | vertical-align: middle; 10 | width: 2em; 11 | } 12 | 13 | .#{$fa-css-prefix}-stack-1x, 14 | .#{$fa-css-prefix}-stack-2x { 15 | left: 0; 16 | position: absolute; 17 | text-align: center; 18 | width: 100%; 19 | } 20 | 21 | .#{$fa-css-prefix}-stack-1x { 22 | line-height: inherit; 23 | } 24 | 25 | .#{$fa-css-prefix}-stack-2x { 26 | font-size: 2em; 27 | } 28 | 29 | .#{$fa-css-prefix}-inverse { 30 | color: $fa-inverse; 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Resources/SpecialPageResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 19 | 'title' => $this->title, 20 | 'route' => $this->route, 21 | 'body' => $this->body, 22 | 'isShowNav' => (bool)$this->show_nav 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/TagsController.php: -------------------------------------------------------------------------------- 1 | orWhere('slug','like','%'.$q.'%') 20 | ->paginate($limit); 21 | 22 | return TagCollection::collection($tags); 23 | 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/Models/Activity.php: -------------------------------------------------------------------------------- 1 | morphTo(); 14 | } 15 | 16 | public static function feed(User $user,$take=50) 17 | { 18 | return static::where('user_id',$user->id) 19 | ->latest() 20 | ->with('subject') 21 | ->take($take) 22 | ->get() 23 | ->groupBy(function ($activity){ 24 | return $activity->created_at->format('Y-m-d'); 25 | }); 26 | } 27 | 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/Models/Subscription.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 16 | } 17 | 18 | public function notify($comment){ 19 | $this->user->notify(new ArticleWasUpdated($comment)); 20 | } 21 | 22 | 23 | public function notifyUpdateBestAnswer($discussion,$user){ 24 | $this->user->notify(new AnswerWasUpdateBest($discussion,$user)); 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /database/factories/CommentFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Models\Comment::class, function (Faker $faker) { 8 | 9 | $user_id = App\Models\User::pluck('id')->random(); 10 | 11 | $types = [ 12 | \App\Models\Article::class, 13 | \App\Models\Discussion::class 14 | ]; 15 | 16 | $type = $types[random_int(0,1)]; 17 | $type_id = $type::pluck('id')->random(); 18 | return [ 19 | 'user_id' => $user_id, 20 | 'commentable_id' => $type_id, 21 | 'commentable_type' => $type, 22 | 'content' => $faker->paragraph 23 | ]; 24 | }); -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:vue/recommended" 11 | 12 | ], 13 | "parserOptions": { 14 | "ecmaFeatures": { 15 | "jsx": true 16 | }, 17 | "sourceType": "module" 18 | }, 19 | "rules": { 20 | "no-const-assign": "warn", 21 | "no-this-before-super": "warn", 22 | "no-undef": "warn", 23 | "no-unreachable": "warn", 24 | "no-unused-vars": "warn", 25 | "constructor-super": "warn", 26 | "valid-typeof": "warn" 27 | } 28 | } -------------------------------------------------------------------------------- /app/Http/Resources/DraftResource.php: -------------------------------------------------------------------------------- 1 | $this->ref, 20 | 'user' => new UserResource($this->whenLoaded('user')), 21 | 'title' => $this->title, 22 | 'body' => $this->body, 23 | 'relation' => $this->relation 24 | ]; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/Policies/ArticlePolicy.php: -------------------------------------------------------------------------------- 1 | is_admin; 18 | } 19 | 20 | /** 21 | * Create a new policy instance. 22 | * 23 | * @return void 24 | */ 25 | public function __construct() 26 | { 27 | // 28 | } 29 | 30 | 31 | public function update(User $user,Article $article) 32 | { 33 | 34 | return $user->id == $article->user->id; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Http/Resources/FavoriteResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 20 | 'created_at' => $this->created_at->toDateTimeString(), 21 | 'type' => snake_case(class_basename($this->favorited_type)), 22 | 'user' => new UserResource($this->whenLoaded('user')) 23 | ]; 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Models/Category.php: -------------------------------------------------------------------------------- 1 | hasMany(Article::class); 18 | } 19 | 20 | public function getRouteKeyName() 21 | { 22 | return 'slug'; 23 | } 24 | 25 | public function path(){ 26 | 27 | return '/articles/'.$this->slug; 28 | } 29 | 30 | protected static function boot() 31 | { 32 | parent::boot(); 33 | 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /resources/views/users/editAvatar.blade.php: -------------------------------------------------------------------------------- 1 | 2 | @extends('layouts.app') 3 | 4 | @section('content') 5 | 6 | 7 |
8 | 9 |
10 | @include('users.partials.setting_nav') 11 | 12 |
13 |
14 | 15 |

16 | 修改您的头像 17 |

18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | @endsection 33 | 34 | -------------------------------------------------------------------------------- /resources/lang/zh-CN/passwords.php: -------------------------------------------------------------------------------- 1 | '密码至少是六位字符并且匹配。', 17 | 'reset' => '密码重置成功!', 18 | 'sent' => '密码重置邮件已发送!', 19 | 'token' => '密码重置令牌无效。', 20 | 'user' => '找不到该邮箱对应的用户。', 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 16 | $this->call(TagsTableSeeder::class); 17 | $this->call(CategoriesTableSeeder::class); 18 | $this->call(ArticlesTableSeeder::class); 19 | $this->call(DiscussionsTableSeeder::class); 20 | $this->call(CommentsTableSeeder::class); 21 | 22 | factory(\App\Models\Reply::class,60)->create(); 23 | 24 | $this->call(MakeDiscussionSolvedSeeder::class); 25 | 26 | 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /resources/views/drafts/show.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 |

草稿预览

6 | 7 | @endsection 8 | 9 | @section('scripts') 10 | 11 | 34 | 35 | @endsection -------------------------------------------------------------------------------- /resources/views/vendor/flash/modal.blade.php: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'App\Listeners\EventListener', 18 | ], 19 | ]; 20 | 21 | /** 22 | * Register any events for your application. 23 | * 24 | * @return void 25 | */ 26 | public function boot() 27 | { 28 | parent::boot(); 29 | 30 | // 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/seeds/MakeDiscussionSolvedSeeder.php: -------------------------------------------------------------------------------- 1 | whereHas('comments')->inRandomOrder()->get(); 15 | $generateCount = $discussions->count() * 0.3; 16 | 17 | for ($i = 0;$i < $generateCount;$i++){ 18 | $discussion = $discussions[$i]; 19 | $bestAnswer = $discussion->comments()->inRandomOrder()->first(); 20 | $discussion->solved_id = $bestAnswer->id; 21 | $discussion->save(); 22 | 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/HomeController.php: -------------------------------------------------------------------------------- 1 | count(); 17 | 18 | $articleCount = Article::query()->count(); 19 | 20 | $discussionCount = Discussion::query()->count(); 21 | 22 | $commentCount = Comment::query()->count(); 23 | 24 | 25 | 26 | return view('admin.home.index',compact('userCount','articleCount','discussionCount','commentCount')); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Http/Controllers/Web/CommentsController.php: -------------------------------------------------------------------------------- 1 | validate($request,[ 16 | 'body' => 'required' 17 | ]); 18 | 19 | 20 | $article->comments()->create([ 21 | 'content' => $request->body, 22 | 'user_id' => Auth::user()->id 23 | ]); 24 | 25 | alert('评论添加成功','success'); 26 | 27 | return back(); 28 | 29 | 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/Controllers/Web/HomeController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 19 | } 20 | 21 | /** 22 | * Show the application dashboard. 23 | * 24 | * @return \Illuminate\Http\Response 25 | */ 26 | public function index() 27 | { 28 | alert('欢迎回来','success'); 29 | return view('home.index'); 30 | } 31 | 32 | 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/Policies/DraftPolicy.php: -------------------------------------------------------------------------------- 1 | is_admin; 26 | } 27 | 28 | public function show(User $user,Draft $draft){ 29 | return $user->id == $draft->user->id; 30 | } 31 | 32 | public function update(User $user,Draft $draft) 33 | { 34 | return $user->id == $draft->user->id; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /public/js/manifest.js: -------------------------------------------------------------------------------- 1 | !function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a config('app.url')]) 5 | {{ config('app.name') }} 6 | @endcomponent 7 | @endslot 8 | 9 | {{-- Body --}} 10 | {{ $slot }} 11 | 12 | {{-- Subcopy --}} 13 | @isset($subcopy) 14 | @slot('subcopy') 15 | @component('mail::subcopy') 16 | {{ $subcopy }} 17 | @endcomponent 18 | @endslot 19 | @endisset 20 | 21 | {{-- Footer --}} 22 | @slot('footer') 23 | @component('mail::footer') 24 | © {{ date('Y') }} {{ config('app.name') }}. All rights reserved. 25 | @endcomponent 26 | @endslot 27 | @endcomponent 28 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/message.blade.php: -------------------------------------------------------------------------------- 1 | @component('mail::layout') 2 | {{-- Header --}} 3 | @slot('header') 4 | @component('mail::header', ['url' => config('app.url')]) 5 | {{ config('app.name') }} 6 | @endcomponent 7 | @endslot 8 | 9 | {{-- Body --}} 10 | {{ $slot }} 11 | 12 | {{-- Subcopy --}} 13 | @isset($subcopy) 14 | @slot('subcopy') 15 | @component('mail::subcopy') 16 | {{ $subcopy }} 17 | @endcomponent 18 | @endslot 19 | @endisset 20 | 21 | {{-- Footer --}} 22 | @slot('footer') 23 | @component('mail::footer') 24 | © {{ date('Y') }} {{ config('app.name') }}. All rights reserved. 25 | @endcomponent 26 | @endslot 27 | @endcomponent 28 | -------------------------------------------------------------------------------- /resources/assets/js/global.js: -------------------------------------------------------------------------------- 1 | // 全局消息 2 | window.events = new Vue(); 3 | 4 | window.flash = function(text,level='success'){ 5 | 6 | var message = {'text':text,'level':level}; 7 | window.events.$emit('flash',message); 8 | }; 9 | 10 | window.showLogin = function(){ 11 | 12 | window.events.$emit('login'); 13 | } 14 | 15 | window.showLoginConfirm = function () { 16 | 17 | this.$dialog.confirm({ 18 | message: '请登录后再执行操作', 19 | onConfirm: () => window.showLogin() 20 | }) 21 | 22 | } 23 | 24 | // axios 钩子 25 | axios.interceptors.response.use(function(response){ 26 | return response; 27 | },function(error){ 28 | 29 | if (error.response.status === 401){ 30 | 31 | window.showLogin() 32 | } 33 | return Promise.reject(error); 34 | }); 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/Base/Handler/NotificationHandler.php: -------------------------------------------------------------------------------- 1 | notification = $notification; 20 | 21 | return $this->mapObject(); 22 | 23 | } 24 | 25 | private function mapObject(){ 26 | 27 | $type = $this->notification->type; 28 | $class = new \ReflectionClass($type); 29 | if ($class->implementsInterface(NotificationMappable::class)){ 30 | return $type::map($this->notification->data); 31 | } 32 | 33 | return null; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /app/Http/Resources/CommentResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 20 | 'body' => $this->body, 21 | 'created_at' => $this->created_at->toDateTimeString(), 22 | 'is_favorite' => $this->isFavorited, 23 | 'favorite_count' => $this->favoritesCount, 24 | 'user' => new UserCollection($this->user) 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /resources/views/notifications/partials/article_was_subscribed.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Image 5 |
6 |
7 |
8 |
9 |

10 | {{ $message->user->name }} 订阅了你的文章 11 | {{ $message->article->title }} 12 | • 13 | {{ $notification->created_at->diffForHumans() }} 14 |

15 |
16 |
17 |
-------------------------------------------------------------------------------- /resources/views/notifications/partials/article_was_favorited.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Image 5 |
6 |
7 |
8 |
9 |

10 | {{ $message->user->name }} 喜欢了你的文章 11 | {{ $message->article->title }} 12 | • 13 | {{ $notification->created_at->diffForHumans() }} 14 |

15 |
16 |
17 |
-------------------------------------------------------------------------------- /resources/views/notifications/partials/comment_was_favorited.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Image 5 |
6 |
7 |
8 |
9 |

10 | {{ $message->user->name }} 11 | 喜欢了你的评论 12 | • 13 | {{ $notification->created_at->diffForHumans() }} 14 |
15 | 16 |

17 |
18 |
19 |
-------------------------------------------------------------------------------- /resources/views/notifications/partials/discussion_was_favorited.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Image 5 |
6 |
7 |
8 |
9 |

10 | {{ $message->user->name }} 喜欢了你的提问 11 | {{ $message->discussion->title }} 12 | • 13 | {{ $notification->created_at->diffForHumans() }} 14 |

15 |
16 |
17 |
-------------------------------------------------------------------------------- /resources/views/vendor/mail/html/button.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 |
4 | 5 | 6 | 15 | 16 |
7 | 8 | 9 | 12 | 13 |
10 | {{ $slot }} 11 |
14 |
17 |
20 | -------------------------------------------------------------------------------- /resources/views/notifications/partials/discussion_was_subscribed.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Image 5 |
6 |
7 |
8 |
9 |

10 | {{ $message->user->name }} 订阅了你的问题 11 | {{ $message->discussion->title }} 12 | • 13 | {{ $notification->created_at->diffForHumans() }} 14 |

15 |
16 |
17 |
-------------------------------------------------------------------------------- /app/Http/Controllers/Api/FilesController.php: -------------------------------------------------------------------------------- 1 | middleware('auth:api'); 15 | } 16 | 17 | public function ImageUpload(Request $request) 18 | { 19 | 20 | if (!$request->hasFile('file')){ 21 | return $this->failed('上传文件不能为空'); 22 | } 23 | 24 | 25 | $file = $request->file('file'); 26 | 27 | $imageHander = new ImageUploadHandler(); 28 | $result = $imageHander->uploadImage($file); 29 | 30 | return $this->success([ 31 | 'image' => '/'.$result['filename'] 32 | ]); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /resources/views/users/activities/created_comment.blade.php: -------------------------------------------------------------------------------- 1 | @component('users.activities.activity') 2 | @slot('heading') 3 | 4 | @if($activity->subject->commentable instanceof \App\Models\SpecialPage) 5 | {{ $user->name }} 评论页面 6 | 7 | "{{ $activity->subject->commentable['title'] }}" 8 | 9 | @else 10 | {{ $user->name }} 评论文章 11 | 12 | "{{ $activity->subject->commentable['title'] }}" 13 | 14 | @endif 15 | 16 | @endslot 17 | 18 | @slot('body') 19 | 20 | @endslot 21 | @endcomponent -------------------------------------------------------------------------------- /database/migrations/2017_05_28_025409_create_categories_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name',50); 19 | $table->string('slug'); 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('categories'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/fa-brands.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.6 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Brands'; 9 | font-style: normal; 10 | font-weight: normal; 11 | src: url('#{$fa-font-path}/fa-brands-400.eot'); 12 | src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), 13 | url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), 14 | url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), 15 | url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), 16 | url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .fab { 20 | font-family: 'Font Awesome 5 Brands'; 21 | } 22 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/fa-solid.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.6 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 900; 11 | src: url('#{$fa-font-path}/fa-solid-900.eot'); 12 | src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), 13 | url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), 14 | url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), 15 | url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), 16 | url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .fa, 20 | .fas { 21 | font-family: 'Font Awesome 5 Free'; 22 | font-weight: 900; 23 | } 24 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/fa-regular.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.6 by @fontawesome - http://fontawesome.com 3 | * License - http://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: url('#{$fa-font-path}/fa-regular-400.eot'); 12 | src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), 13 | url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), 14 | url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), 15 | url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), 16 | url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); 17 | } 18 | 19 | .far { 20 | font-family: 'Font Awesome 5 Free'; 21 | font-weight: 400; 22 | } 23 | -------------------------------------------------------------------------------- /resources/views/vendor/pagination/simple-bootstrap-4.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 17 | @endif 18 | -------------------------------------------------------------------------------- /app/Http/Flash.php: -------------------------------------------------------------------------------- 1 | flash($key,[ 11 | 'text'=>$message, 12 | 'level'=>$level 13 | ]); 14 | 15 | } 16 | 17 | public function message($message,$level='info') 18 | { 19 | 20 | $this->create($message,$level); 21 | 22 | } 23 | 24 | public function info($message){ 25 | $this->message($message); 26 | } 27 | 28 | public function success($message){ 29 | $this->message($message,'success'); 30 | } 31 | 32 | public function error($title,$message){ 33 | $this->message($message,'error'); 34 | } 35 | 36 | public function overlay($message,$level='info'){ 37 | $this->create($message,$level,'flash_message_overlay'); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /resources/views/notifications/partials/article_was_updated.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Image 5 |
6 |
7 |
8 |
9 |

10 | {{ $message->user->name }} 11 | 评论了你的文章 {{ $message->commentable->title }} 12 | • 13 | {{ $notification->created_at->diffForHumans() }} 14 |
15 | 16 |

17 |
18 |
19 |
-------------------------------------------------------------------------------- /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/assets/js/app.js', 'public/js') 15 | .sass('resources/assets/sass/app.scss', 'public/css') 16 | .js('resources/assets/js/home.js', 'public/js') 17 | .sass('resources/assets/sass/home.scss', 'public/css') 18 | .extract(['vue','buefy','vue-multiselect','moment']); 19 | 20 | if (mix.inProduction) { 21 | mix.version(); 22 | } 23 | 24 | // mix.browserSync('note.com'); 25 | 26 | -------------------------------------------------------------------------------- /resources/assets/sass/vender/fontawesome/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } 11 | 12 | // Hook for IE8-9 13 | // ------------------------- 14 | 15 | :root { 16 | .#{$fa-css-prefix}-rotate-90, 17 | .#{$fa-css-prefix}-rotate-180, 18 | .#{$fa-css-prefix}-rotate-270, 19 | .#{$fa-css-prefix}-flip-horizontal, 20 | .#{$fa-css-prefix}-flip-vertical { 21 | filter: none; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Resources/DiscussionResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 20 | 'title' => $this->title, 21 | 'page_image' => $this->page_image, 22 | 'body' => $this->body, 23 | 'created_at' => $this->created_at, 24 | 'user' => new UserResource($this->whenLoaded('user')), 25 | 'tags' => TagResource::collection($this->whenLoaded('tags')), 26 | 'best_answer' => new CommentResource($this->bestAnswer) 27 | 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2017_05_28_031123_create_tags_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name')->unique(); 19 | $table->string('slug')->unique(); 20 | $table->text('message')->nullable(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('tags'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2017_05_28_030133_create_replies_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('article_id'); 19 | $table->unsignedSmallInteger('user_id'); 20 | $table->text('body'); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('replies'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /resources/assets/js/components/Parse.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /resources/assets/sass/home.scss: -------------------------------------------------------------------------------- 1 | // 后台 管理 的css 2 | 3 | @import url("https://fonts.googleapis.com/icon?family=Material+Icons"); 4 | 5 | @import "variables"; 6 | 7 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fontawesome'; 8 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-brands'; 9 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-regular'; 10 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-solid'; 11 | 12 | @import "node_modules/bulma/bulma"; 13 | 14 | @import "node_modules/buefy/src/scss/buefy"; 15 | 16 | .body{ 17 | 18 | background-color: #eee; 19 | } 20 | 21 | 22 | .slide-menu{ 23 | 24 | padding-left: 2em; 25 | padding-top: 20px; 26 | 27 | } 28 | 29 | .main-content{ 30 | 31 | padding-top: 20px; 32 | padding-right: 25px; 33 | 34 | background-color: #ddd; 35 | 36 | } 37 | 38 | li{ 39 | 40 | list-style: none; 41 | 42 | } -------------------------------------------------------------------------------- /database/migrations/2017_05_28_031151_create_taggables_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('tag_id'); 19 | $table->unsignedInteger('taggable_id'); 20 | $table->string('taggable_type','50'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('taggables'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /resources/assets/js/components/Example.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 44 | -------------------------------------------------------------------------------- /app/Base/Filters/Filters.php: -------------------------------------------------------------------------------- 1 | request = $request; 18 | } 19 | 20 | public function apply(Builder $builder) 21 | { 22 | $this->builder = $builder; 23 | 24 | foreach ($this->getFitters() as $filter => $value){ 25 | if (method_exists($this,$filter)){ 26 | $this->$filter($value); 27 | } 28 | } 29 | } 30 | 31 | public function getFitters() 32 | { 33 | return $this->request->only($this->filters); 34 | } 35 | 36 | public function setFilters($fitter,$value){ 37 | $this->filters[$fitter] = $value; 38 | } 39 | 40 | 41 | } -------------------------------------------------------------------------------- /app/Providers/OAuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->make('Laravel\Socialite\Contracts\Factory')->extend('qq', function ($app) { 18 | $config = $app['config']['services.qq']; 19 | return new QQProvider( 20 | $app['request'], 21 | $config['client_id'], 22 | $config['client_secret'], 23 | $config['redirect'] 24 | ); 25 | }); 26 | } 27 | 28 | /** 29 | * Register the application services. 30 | * 31 | * @return void 32 | */ 33 | public function register() 34 | { 35 | // 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2017_06_22_100627_create_special_pages_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->boolean('show_nav')->default(true); 19 | $table->string('route'); 20 | $table->string('title'); 21 | $table->text('body'); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('special_pages'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_05_28_030521_create_activities_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('user_id'); 19 | $table->unsignedInteger('subject_id'); 20 | $table->string('subject_type',50); 21 | $table->string('type',50); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('activities'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_01_14_204314_create_notifications_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 18 | $table->string('type'); 19 | $table->morphs('notifiable'); 20 | $table->text('data'); 21 | $table->timestamp('read_at')->nullable(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('notifications'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /resources/views/notifications/partials/answer_was_update_best.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Image 5 |
6 |
7 |
8 |
9 |

10 | {{ $message->user->name }} 11 | 更新 12 | {{ $message->comment->commentable->title }} 13 | 的最佳答案 14 | • 15 | {{ $notification->created_at->diffForHumans() }} 16 |
17 | 18 |

19 |
20 |
21 |
-------------------------------------------------------------------------------- /app/Http/Controllers/Api/AuthenticateController.php: -------------------------------------------------------------------------------- 1 | validate($request, [ 15 | 'email' => 'required|email|max:255', 16 | 'password' => 'required|string' 17 | ]); 18 | 19 | $credentials = $request->only(['email','password']); 20 | 21 | if (Auth::attempt($credentials,true)) { 22 | 23 | if (Auth::user()->activated) { 24 | return $this->message('登录成功'); 25 | }else{ 26 | Auth::logout(); 27 | 28 | return $this->failed('账号未激活,请使用邮件链接激活邮箱'); 29 | } 30 | 31 | } else { 32 | 33 | return $this->failed('用户名或密码错误'); 34 | } 35 | 36 | 37 | 38 | 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /database/migrations/2018_02_27_171949_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->text('connection'); 19 | $table->text('queue'); 20 | $table->longText('payload'); 21 | $table->longText('exception'); 22 | $table->timestamp('failed_at')->useCurrent(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('failed_jobs'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /resources/assets/sass/overrite.scss: -------------------------------------------------------------------------------- 1 | 2 | .card{ 3 | box-shadow:none; 4 | box-shadow: 0 1px 2px 0 rgba(0,0,0,.05); 5 | 6 | 7 | 8 | .card-header{ 9 | box-shadow: none; 10 | border-bottom: 1px solid hsla(0,0%,59%,.1); 11 | 12 | 13 | .card-header-title{ 14 | 15 | font-weight:500; 16 | 17 | padding: 0.63em; 18 | padding-left: 1em; 19 | } 20 | 21 | .card-header-icon{ 22 | 23 | padding: 0.63em; 24 | } 25 | 26 | .card-header-icon{ 27 | 28 | font-size: 13px; 29 | } 30 | 31 | 32 | 33 | } 34 | } 35 | 36 | .nopadding{ 37 | padding:0; 38 | } 39 | 40 | .icon .fa, .icon .mdi { 41 | font-size: inherit; 42 | } 43 | 44 | .social-share .social-share-icon { 45 | position: relative; 46 | display: inline-block; 47 | width: 20px; 48 | height: 20px; 49 | font-size: 10px; 50 | border-radius: 50%; 51 | line-height: 20px; 52 | text-align: center; 53 | vertical-align: middle; 54 | transition: background 0.6s ease-out 0s; 55 | } -------------------------------------------------------------------------------- /app/Base/Traits/SlugTransable.php: -------------------------------------------------------------------------------- 1 | getAttributes(); 33 | $translate = 'name'; 34 | 35 | if (! array_key_exists('slug', $attributes)) { 36 | return; 37 | } 38 | 39 | if (array_key_exists('title', $attributes)) { 40 | $translate = 'title'; 41 | } 42 | 43 | dispatch(new TranslateSlug($model,$translate)); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the Closure based commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | require base_path('routes/console.php'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/SubscriptionsController.php: -------------------------------------------------------------------------------- 1 | middleware('auth:api'); 15 | } 16 | 17 | 18 | public function store(SubscribeRequest $request){ 19 | 20 | try{ 21 | $request->subscribe(); 22 | }catch(SubscribeException $e){ 23 | return $e->response(); 24 | } 25 | 26 | $request->getModel()->notify(); 27 | 28 | return $this->message('点赞成功'); 29 | } 30 | 31 | 32 | public function destroy(SubscribeRequest $request){ 33 | 34 | try{ 35 | $request->unsubscribe(); 36 | }catch(SubscribeException $e){ 37 | return $e->response(); 38 | } 39 | return $this->message('取消点赞成功'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /resources/views/layouts/partials/category.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

5 | 热门分类 6 |

7 | 8 | 查看全部 9 | 10 |
11 |
12 |
13 |
14 | 15 | @forelse($popular_categories as $item) 16 | 17 | 23 | @empty 24 |
  • 没有分类数据
  • 25 | @endforelse 26 | 27 |
    28 |
    29 |
    30 |
    31 | -------------------------------------------------------------------------------- /database/migrations/2017_05_28_030506_create_favorites_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('user_id'); 19 | $table->unsignedInteger('favorited_id'); 20 | $table->string('favorited_type',50); 21 | $table->timestamps(); 22 | $table->unique(['user_id','favorited_id','favorited_type']); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('favorites'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_06_01_095839_create_comments_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('user_id'); 19 | $table->text('body'); 20 | $table->unsignedInteger('commentable_id'); 21 | $table->string('commentable_type',50); 22 | $table->softDeletes(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('comments'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Http/Controllers/Web/CategoriesController.php: -------------------------------------------------------------------------------- 1 | orderBy('articles_count','desc') 16 | ->limit(10) 17 | ->get(); 18 | 19 | 20 | 21 | return $categories; 22 | } 23 | public function create() 24 | { 25 | return view('categories.create'); 26 | } 27 | 28 | public function store(Request $request) 29 | { 30 | $this->validate($request,[ 31 | 'name' => 'required|unique:categories', 32 | 'slug' => 'required|unique:categories', 33 | ]); 34 | 35 | Category::create($request->only('name','slug')); 36 | 37 | alert('分类添加成功','success'); 38 | return back(); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Http/Requests/UpdateUserRequest.php: -------------------------------------------------------------------------------- 1 | only($this->allowed_field)); 28 | $user->update($data); 29 | return $user; 30 | } 31 | 32 | /** 33 | * Get the validation rules that apply to the request. 34 | * 35 | * @return array 36 | */ 37 | public function rules() 38 | { 39 | return [ 40 | 'name' => 'string', 41 | 'signature' => 'max:26' 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Http/Controllers/Web/DraftsController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 16 | } 17 | 18 | public function index(){ 19 | 20 | $user = Auth::user(); 21 | 22 | $drafts = $user->drafts()->whereNull('parent_id')->latest()->paginate(10); 23 | 24 | return view('drafts.index',compact('user','drafts')); 25 | } 26 | 27 | public function show($draft){ 28 | 29 | return view('drafts.show'); 30 | } 31 | 32 | public function edit(Draft $draft){ 33 | return view('drafts.edit',compact('draft')); 34 | 35 | } 36 | 37 | public function destroy(Draft $draft){ 38 | $draft->delete(); 39 | flash('删除成功'); 40 | return back(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /resources/assets/js/components/Home/Menus.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/UsersController.php: -------------------------------------------------------------------------------- 1 | middleware('auth:api'); 14 | } 15 | 16 | public function uploadAvatar(Request $request){ 17 | 18 | $this->validate($request,[ 19 | 'img' => 'required|image' 20 | 21 | ]); 22 | 23 | $user = Auth::user(); 24 | 25 | $imageHander = new ImageUploadHandler(); 26 | 27 | 28 | $avatar = $request->file('img'); 29 | $result = $imageHander->uploadAvatar($avatar,$user); 30 | 31 | $avatarPath = '/'.$imageHander->avatarPath().'/'.$result['filename']; 32 | 33 | $user->avatar = $avatarPath; 34 | $user->save(); 35 | 36 | return $this->success([ 37 | 'avatar' => $avatarPath 38 | ]); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /database/migrations/2017_12_13_225211_create_subscriptions_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('user_id'); 19 | $table->unsignedInteger('subscribable_id'); 20 | $table->string('subscribable_type'); 21 | $table->unique(['user_id','subscribable_id','subscribable_type']); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('subscriptions'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Models/Tag.php: -------------------------------------------------------------------------------- 1 | morphedByMany(Article::class,'taggable'); 17 | } 18 | 19 | public function discussions(){ 20 | return $this->morphedByMany(Discussion::class,'taggable'); 21 | } 22 | 23 | public function path($name = null){ 24 | 25 | $path = '?tag='.$this->name; 26 | 27 | 28 | if ($name){ 29 | return url()->route($name).$path; 30 | } 31 | 32 | return $path; 33 | 34 | } 35 | 36 | protected static function boot() 37 | { 38 | parent::boot(); 39 | 40 | static::creating(function ($model){ 41 | $model->slug = app(SlugTranslateHandler::class)->translate($model->name); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Http/Controllers/Web/NotificationsController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 16 | } 17 | 18 | public function index(){ 19 | 20 | $limit = Input::get('limit') ?: 30; 21 | 22 | $type = Input::get('type'); 23 | $notifications = []; 24 | $user = Auth::user(); 25 | if ($type == 'unread'){ 26 | $notifications = $user->unreadNotifications()->paginate($limit); 27 | $notifications->markAsRead(); 28 | }else{ 29 | $notifications = $user->notifications()->paginate($limit); 30 | } 31 | 32 | $notifications->appends(Input::except('page')); 33 | 34 | return view('notifications.index',compact('notifications')); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 32 | } 33 | 34 | 35 | 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2017_12_10_223853_add_outh_field_to_users_table.php: -------------------------------------------------------------------------------- 1 | integer('github_id')->nullable()->after('is_admin'); 19 | $table->string('github_name')->nullable()->after('is_admin'); 20 | $table->string('github_url')->nullable()->after('is_admin'); 21 | 22 | $table->string('qq_openid')->nullable()->after('is_admin'); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::table('users', function (Blueprint $table) { 34 | // 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /resources/views/discussions/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('title','评论首页') 4 | 5 | 6 | @section('content') 7 | 8 |
    9 | 10 |
    11 |
    12 |
    13 |
    14 | @forelse($discussions as $discussion) 15 | @include('discussions.partials.discussion') 16 | @empty 17 |
    没有提问数据
    18 | @endforelse 19 | 20 |
    21 | {{ $discussions->links('vendor.pagination.default') }} 22 |
    23 |
    24 |
    25 |
    26 | 27 |
    28 | 29 | 30 |
    31 | @include('discussions.partials.filter') 32 |
    33 | 34 | 35 |
    36 | 37 | 38 | @endsection -------------------------------------------------------------------------------- /resources/views/articles/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | 4 | @section('content') 5 | 6 |
    7 |
    8 | 9 |
    10 |
    11 | 写文章 12 |
    13 | 14 |
    15 | 16 |
    17 | 18 | 19 |
    20 | 21 |
    22 | 23 |
    24 | 25 |
    26 |
    27 | 28 |
    29 |
    30 | 提示信息 31 |
    32 |
    33 | 34 |
    35 | 这是奥克兰发还发爱古法卡法咖啡馆花费 36 |
    37 | 38 |
    39 |
    40 | 41 | 42 | 43 | @endsection -------------------------------------------------------------------------------- /app/Base/Traits/ContentSetable.php: -------------------------------------------------------------------------------- 1 | convertMarkdownToHtml($value); 15 | $data = [ 16 | 'raw' => $value, 17 | 'html' => $html 18 | ]; 19 | 20 | if (array_key_exists('page_image', $this->getAttributes())) { 21 | $this->makeContentImage($html); 22 | } 23 | 24 | $this->body = json_encode($data); 25 | } 26 | 27 | 28 | public function makeContentImage($html){ 29 | 30 | $pattern = "/[img|IMG].*?src=['|\"](.*?(?:[.gif|.jpg]))['|\"].*?[\/]?>/"; 31 | preg_match($pattern,$html,$match); 32 | if (empty($match) || is_null($match[1])){ 33 | return; 34 | } 35 | $content_image = (new ImageUploadHandler()) 36 | ->makeArticleImage($match[1],''); 37 | $this->page_image = $content_image; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /resources/views/special_pages/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 |
    6 |
    7 |
    8 |
    9 |

    10 | 编辑页面 11 |

    12 |
    13 | 14 | 15 | 16 |
    17 | 18 | 19 |
    20 | 21 | 22 | 23 |
    24 | 25 |
    26 | 27 |
    28 | 29 |
    30 |
    31 | 提示信息 32 |
    33 | 34 |
    35 | 36 |
    37 | 这是奥克兰发还发爱古法卡法咖啡馆花费 38 |
    39 | 40 | 41 |
    42 | 43 |
    44 | 45 |
    46 | 47 | 48 | @endsection -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_LOG_LEVEL=debug 6 | APP_URL=http://localhost 7 | 8 | LOG_CHANNEL=stack 9 | 10 | DB_CONNECTION=mysql 11 | DB_HOST=127.0.0.1 12 | DB_PORT=3306 13 | DB_DATABASE=homestead 14 | DB_USERNAME=homestead 15 | DB_PASSWORD=secret 16 | 17 | BROADCAST_DRIVER=log 18 | CACHE_DRIVER=file 19 | SESSION_DRIVER=file 20 | QUEUE_DRIVER=sync 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 | 34 | # send cloud 配置 35 | # send cloud 配置,打开当前driver,关闭上面的 MAIL_DRIVER,并设置user和key 36 | # MAIL_DRIVER=sendcloud 37 | SEND_CLOUD_USER= 38 | SEND_CLOUD_KEY= 39 | 40 | 41 | PUSHER_APP_ID= 42 | PUSHER_APP_KEY= 43 | PUSHER_APP_SECRET= 44 | 45 | # 谷歌分析配置 46 | GOOGLE_ANALYTICS_ID= 47 | 48 | # github第三方登录配置 49 | GITHUB_CLIENT_ID= 50 | GITHUB_CLIENT_SECRET= 51 | 52 | # qq第三方登录配置 53 | QQ_CLIENT_ID= 54 | QQ_CLIENT_SECRET= 55 | 56 | # 百度翻译配置 57 | BAIDU_TRANSLATE_APPID= 58 | BAIDU_TRANSLATE_KEY= 59 | -------------------------------------------------------------------------------- /resources/views/notifications/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 |
    6 | 7 |
    8 | @include('notifications.partials.nav') 9 | 10 |
    11 |
    12 | 13 | 14 |

    15 | 我的提醒 16 |

    17 | 18 | @forelse ($notifications as $notification) 19 | 20 | @if (view()->exists("notifications.partials.".snake_case(class_basename($notification->type)))) 21 | @include ("notifications.partials.".snake_case(class_basename($notification->type)), [ 22 | 'message' => notification_parser($notification), 23 | 'notification' => $notification 24 | ]) 25 | @endif 26 | @empty 27 |

    暂时没有任何消息哦

    28 | @endforelse 29 | 30 | {{ $notifications->links() }} 31 | 32 |
    33 | 34 |
    35 | 36 | 37 | 38 | @endsection -------------------------------------------------------------------------------- /database/migrations/2017_11_19_115928_seed_special_pages_data.php: -------------------------------------------------------------------------------- 1 | 1, 19 | 'route' => 'about', 20 | 'title' => '关于', 21 | 'body' => '关于界面' 22 | ], 23 | [ 24 | 'show_nav' => 1, 25 | 'route' => 'message', 26 | 'title' => '留言板', 27 | 'body' => '留言板界面' 28 | ] 29 | 30 | 31 | ]; 32 | 33 | DB::table('special_pages')->insert($pages); 34 | 35 | 36 | } 37 | 38 | /** 39 | * Reverse the migrations. 40 | * 41 | * @return void 42 | */ 43 | public function down() 44 | { 45 | DB::table('special_pages')->truncate(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Http/Requests/SubscribeRequest.php: -------------------------------------------------------------------------------- 1 | Article::class, 19 | 'discussion' => Discussion::class 20 | ]; 21 | } 22 | 23 | /** 24 | * Determine if the user is authorized to make this request. 25 | * 26 | * @return bool 27 | */ 28 | public function authorize() 29 | { 30 | return true; 31 | } 32 | 33 | 34 | // 用户订阅 35 | public function subscribe() 36 | { 37 | $model = $this->getModel(); 38 | return $model->subscribe(); 39 | 40 | } 41 | 42 | // 用户取消订阅 43 | public function unsubscribe() 44 | { 45 | $model = $this->getModel(); 46 | if($model->isSubscribed){ 47 | $model->unsubscribe(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /database/migrations/2018_02_06_142849_create_drafts_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('user_id'); 19 | $table->unsignedInteger('parent_id')->nullable(); 20 | $table->unsignedInteger('relation_id')->nullable(); 21 | $table->string('relation_type')->nullable(); 22 | $table->string('title'); 23 | $table->string('slug')->nullable(); 24 | $table->text('body'); 25 | $table->timestamps(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('drafts'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Resources/ArticleResource.php: -------------------------------------------------------------------------------- 1 | $this->id, 24 | 'title' => $this->title, 25 | 'page_image' => $this->page_image, 26 | 'body' => $this->body, 27 | 'is_original' => $this->is_original, 28 | 'published_at' => $this->published_at, 29 | 'user' => new UserCollection($this->whenLoaded('user')), 30 | 'category' => new CategoryCollection($this->whenLoaded('category')), 31 | 'tags' => TagCollection::collection($this->whenLoaded('tags')) 32 | ]; 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/UsersController.php: -------------------------------------------------------------------------------- 1 | validate($request,[ 29 | 'name' => 'string', 30 | 'signature' => 'max:26', 31 | 'email' => 'email' 32 | ]); 33 | 34 | $user->update($request->only(['name','signature','email'])); 35 | 36 | flash('修改成功')->success(); 37 | 38 | return back(); 39 | } 40 | 41 | public function destroy(User $user){ 42 | 43 | $user->delete(); 44 | 45 | flash('删除成功')->success(); 46 | 47 | return back(); 48 | 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/Http/Requests/FavoriteRequest.php: -------------------------------------------------------------------------------- 1 | Comment::class, 20 | 'article' => Article::class, 21 | 'discussions' => Discussion::class 22 | ]; 23 | } 24 | 25 | /** 26 | * Determine if the user is authorized to make this request. 27 | * 28 | * @return bool 29 | */ 30 | public function authorize() 31 | { 32 | return true; 33 | } 34 | 35 | // 用户点赞 36 | public function store() 37 | { 38 | $model = $this->getModel(); 39 | return $model->favorite(); 40 | } 41 | 42 | // 用户取消点赞 43 | public function destroy() 44 | { 45 | $model = $this->getModel(); 46 | if($model->isFavorited){ 47 | $model->unfavorite(); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /resources/views/articles/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | 4 | @section('content') 5 | 6 |
    7 | 8 |
    9 |
    10 | 11 |
    12 |
    13 | 编辑文章 14 |
    15 | 16 |
    17 | 18 |
    19 | 22 | 23 |
    24 | 25 |
    26 | 27 |
    28 | 29 |
    30 |
    31 | 32 |
    33 |
    34 | 提示信息 35 |
    36 |
    37 | 38 |
    39 | 这是奥克兰发还发爱古法卡法咖啡馆花费 40 |
    41 | 42 |
    43 |
    44 | 45 |
    46 | 47 | 48 | @endsection -------------------------------------------------------------------------------- /app/Http/Controllers/Web/SpecialPagesController.php: -------------------------------------------------------------------------------- 1 | middleware(['auth','admin'])->except(['show']); 15 | } 16 | 17 | 18 | public function index(){ 19 | 20 | 21 | 22 | } 23 | 24 | public function edit(SpecialPage $page){ 25 | 26 | return view('special_pages.edit',compact('page')); 27 | } 28 | 29 | public function show($name){ 30 | 31 | $page = SpecialPage::where('route',$name)->firstOrFail(); 32 | 33 | return view('special_pages.show',compact('page')); 34 | } 35 | 36 | public function create(){ 37 | 38 | return view('special_pages.create'); 39 | } 40 | 41 | 42 | public function store(){ 43 | 44 | 45 | 46 | } 47 | 48 | public function destroy(SpecialPage $page){ 49 | 50 | 51 | $page->delete(); 52 | 53 | $page->comments->each->delete(); 54 | 55 | alert('页面删除成功','success'); 56 | 57 | return redirect('/'); 58 | } 59 | 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /resources/assets/js/components/BestAnswer.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/Base/Filters/ArticleFilters.php: -------------------------------------------------------------------------------- 1 | firstOrFail(); 21 | 22 | return $this->builder->where('user_id',$user->id); 23 | } 24 | 25 | protected function popular() 26 | { 27 | $this->builder->getQuery()->orders = []; 28 | 29 | return $this->builder 30 | ->withCount('comments') 31 | ->orderBy('comments_count','desc'); 32 | } 33 | 34 | protected function uncommented(){ 35 | $this->builder->getQuery()->orders = []; 36 | return $this->builder 37 | ->has('comments','=',0); 38 | } 39 | 40 | public function tag($name){ 41 | 42 | return $this->builder->whereHas('tags',function ($query) use ($name){ 43 | $query->where('slug',$name)->orWhere('name',$name); 44 | }); 45 | } 46 | 47 | public function archive($date){ 48 | 49 | dd($date); 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /database/migrations/2018_01_29_211051_create_discussions_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('user_id'); 19 | $table->string('page_image')->nullable(); 20 | $table->string('title'); 21 | $table->string('slug')->nullable(); 22 | $table->text('body'); 23 | $table->unsignedInteger('views_count')->default(0); 24 | $table->unsignedInteger('solved_id')->nullable(); 25 | $table->unsignedInteger('draft_id')->nullable(); 26 | $table->timestamps(); 27 | $table->softDeletes(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('discussions'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /resources/views/vendor/flash/message.blade.php: -------------------------------------------------------------------------------- 1 | @foreach (session('flash_notification', collect())->toArray() as $message) 2 | @if ($message['overlay']) 3 | @include('flash::modal', [ 4 | 'modalClass' => 'flash-modal', 5 | 'title' => $message['title'], 6 | 'body' => $message['message'] 7 | ]) 8 | @else 9 | 10 | 11 | {!! $message['message'] !!} 12 | 13 | 14 | {{--
    --}} 19 | {{--@if ($message['important'])--}} 20 | {{----}} 25 | {{--@endif--}} 26 | 27 | {{--{!! $message['message'] !!}--}} 28 | {{--
    --}} 29 | @endif 30 | @endforeach 31 | 32 | {{ session()->forget('flash_notification') }} 33 | -------------------------------------------------------------------------------- /app/Jobs/TranslateSlug.php: -------------------------------------------------------------------------------- 1 | translate = $translate; 30 | $this->field = $field; 31 | } 32 | 33 | /** 34 | * Execute the job. 35 | * 36 | * @return void 37 | */ 38 | public function handle() 39 | { 40 | 41 | $field = $this->field; 42 | $slug = app(SlugTranslateHandler::class)->translate($this->translate->$field); 43 | 44 | $this->translate->slug = $slug; 45 | DB::table($this->translate->getTable())->where('id', $this->translate->id)->update(['slug' => $slug]); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Feature 14 | 15 | 16 | 17 | ./tests/Unit 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /resources/assets/sass/app.scss: -------------------------------------------------------------------------------- 1 | 2 | 3 | //@import url("https://fonts.googleapis.com/icon?family=Material+Icons"); 4 | 5 | @import "variables"; 6 | 7 | $modal-content-width:400px; 8 | 9 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fontawesome'; 10 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-brands'; 11 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-regular'; 12 | @import 'node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-solid'; 13 | 14 | 15 | @import "node_modules/bulma/bulma"; 16 | 17 | @import "node_modules/buefy/src/scss/buefy"; 18 | 19 | @import "node_modules/social-share.js/dist/css/share.min"; 20 | 21 | @import "node_modules/vue-multiselect/dist/vue-multiselect.min"; 22 | 23 | 24 | 25 | 26 | // Fonts 27 | //@import url(https://fonts.googleapis.com/css?family=Raleway:300,400,600); 28 | // 29 | // @import url("https://fonts.googleapis.com/icon?family=Material+Icons"); 30 | // 31 | 32 | @import "navbar"; 33 | 34 | @import "helpers"; 35 | // 36 | @import "styles"; 37 | // 38 | @import "vender/prism.css"; 39 | // 40 | @import "markdown"; 41 | // 42 | @import "article"; 43 | 44 | @import "discussion"; 45 | 46 | // 47 | @import "vender/simplemde.min.css"; 48 | 49 | @import "overrite"; 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /resources/views/vendor/notifications/email.blade.php: -------------------------------------------------------------------------------- 1 | @component('mail::message') 2 | {{-- Greeting --}} 3 | @if (! empty($greeting)) 4 | # {{ $greeting }} 5 | @else 6 | @if ($level == 'error') 7 | # Whoops! 8 | @else 9 | # Hello! 10 | @endif 11 | @endif 12 | 13 | {{-- Intro Lines --}} 14 | @foreach ($introLines as $line) 15 | {{ $line }} 16 | 17 | @endforeach 18 | 19 | {{-- Action Button --}} 20 | @isset($actionText) 21 | 33 | @component('mail::button', ['url' => $actionUrl, 'color' => $color]) 34 | {{ $actionText }} 35 | @endcomponent 36 | @endisset 37 | 38 | {{-- Outro Lines --}} 39 | @foreach ($outroLines as $line) 40 | {{ $line }} 41 | 42 | @endforeach 43 | 44 | 45 | @if (! empty($salutation)) 46 | {{ $salutation }} 47 | @else 48 | 荣幸之至,
    {{ config('app.name') }} 49 | @endif 50 | 51 | 52 | @isset($actionText) 53 | @component('mail::subcopy') 54 | 如果点击 "{{ $actionText }}" 按钮无效, 请拷贝改链接到您的浏览器进行访问: [{{ $actionUrl }}]({{ $actionUrl }}) 55 | @endcomponent 56 | @endisset 57 | @endcomponent 58 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name')->unique(); 19 | $table->string('signature')->nullable(); 20 | $table->string('email')->nullable()->unique(); 21 | $table->string('activation_token')->nullable(); 22 | $table->boolean('activated')->default(false); 23 | $table->string('password'); 24 | $table->string('avatar')->nullable(); 25 | $table->json('settings')->nullable(); 26 | $table->boolean('is_admin')->default(false); 27 | $table->rememberToken(); 28 | $table->timestamps(); 29 | }); 30 | } 31 | 32 | /** 33 | * Reverse the migrations. 34 | * 35 | * @return void 36 | */ 37 | public function down() 38 | { 39 | Schema::dropIfExists('users'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /resources/assets/js/components/Paginator.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 44 | 45 | -------------------------------------------------------------------------------- /resources/assets/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | // Body 3 | //$body-bg: #f5f8fa; 4 | $body-bg: #f5f8f9; 5 | 6 | $family-serif: "lato-regular", "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Microsoft YaHei", sans-serif; 7 | 8 | // Borders 9 | $laravel-border-color: darken($body-bg, 10%); 10 | $list-group-border: #e7eaf1; 11 | $navbar-default-border: #e7eaf1; 12 | //$panel-default-border: $laravel-border-color; 13 | $panel-default-border: #e7eaf1; 14 | 15 | $panel-inner-border: $laravel-border-color; 16 | 17 | // Brands 18 | //$brand-primary: #3097D1; 19 | $brand-primary: #00b5ad; 20 | 21 | 22 | $brand-info: #8eb4cb; 23 | $brand-success: #2ab27b; 24 | $brand-warning: #cbb956; 25 | $brand-danger: #bf5329; 26 | 27 | // Typography 28 | $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/"; 29 | $font-family-sans-serif: "Raleway", sans-serif; 30 | $font-size-base: 14px; 31 | $line-height-base: 1.6; 32 | $text-color: #636b6f; 33 | 34 | // Navbar 35 | //$navbar-default-bg: #fff; 36 | $navbar-default-bg: rgba(255,255,255,0.9); 37 | 38 | // Buttons 39 | $btn-default-color: $text-color; 40 | 41 | // Inputs 42 | $input-border: lighten($text-color, 40%); 43 | $input-border-focus: lighten($brand-primary, 25%); 44 | $input-color-placeholder: lighten($text-color, 30%); 45 | 46 | // Panels 47 | $panel-default-heading-bg: #fff; 48 | -------------------------------------------------------------------------------- /app/Base/Helpers.php: -------------------------------------------------------------------------------- 1 | message($message, $level); 15 | } 16 | } 17 | 18 | 19 | if (! function_exists('nav_is_active')) { 20 | 21 | function nav_is_active($name, $route = null) 22 | { 23 | if ($route == null) { 24 | return Route::currentRouteName() == $name ? 'is-active' : ''; 25 | } 26 | return request()->url() == route($name, $route) ? 'is-active' : ''; 27 | 28 | } 29 | } 30 | 31 | if (! function_exists('menu_is_active')) { 32 | 33 | function menu_is_active($name, $route = null) 34 | { 35 | if ($route == null) { 36 | return Route::currentRouteName() == $name ? 'is-active' : ''; 37 | } 38 | return request()->url() == route($name, $route) ? 'is-active' : ''; 39 | 40 | } 41 | } 42 | 43 | 44 | if (! function_exists('notification_parser')) { 45 | 46 | function notification_parser($data) 47 | { 48 | $handler = app(NotificationHandler::class); 49 | return $handler->make($data); 50 | } 51 | } -------------------------------------------------------------------------------- /app/Http/Controllers/Web/SessionsController.php: -------------------------------------------------------------------------------- 1 | validate($request, [ 16 | 'email' => 'required|email|max:255', 17 | 'password' => 'required|string' 18 | ]); 19 | 20 | $credentials = [ 21 | 'email' => $request->email, 22 | 'password' => $request->password, 23 | ]; 24 | 25 | if (Auth::attempt($credentials,true)) { 26 | 27 | 28 | 29 | if (Auth::user()->activated) { 30 | 31 | // return back(); 32 | 33 | // flash('尊敬的'.Auth::user()->name.',欢迎回来')->success(); 34 | return redirect()->intended(route("users.show", [Auth::user()])); 35 | }else{ 36 | Auth::logout(); 37 | flash('你的账号未激活,请检查邮箱中的注册邮件进行激活。')->important(); 38 | 39 | return back(); 40 | } 41 | 42 | } else { 43 | 44 | flash('很抱歉,您的邮箱和密码不匹配')->error()->important(); 45 | return redirect()->back(); 46 | } 47 | 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /resources/views/users/show.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 | 5 | @component('users.components.user',['user'=>$user]) 6 | @forelse ($activities as $date => $activity) 7 | 8 |
    9 | @foreach ($activity as $record) 10 | @if (view()->exists("users.activities.{$record->type}")) 11 | @include ("users.activities.{$record->type}", ['activity' => $record]) 12 | @endif 13 | @endforeach 14 |
    15 | 16 | @empty 17 |

    暂时没有任何动态哦

    18 | @endforelse 19 | @endcomponent 20 | 21 | 22 | @endsection 23 | 24 | @section('scripts') 25 | 26 | 47 | 48 | @endsection -------------------------------------------------------------------------------- /app/Base/Service/Markdowner.php: -------------------------------------------------------------------------------- 1 | htmlConverter = new HtmlConverter(); 25 | 26 | $this->markdownConverter = new Parsedown(); 27 | } 28 | 29 | /** 30 | * Convert Markdown To Html. 31 | * 32 | * @param $markdown 33 | * @return string 34 | */ 35 | public function convertMarkdownToHtml($markdown) 36 | { 37 | $convertedHmtl = $this->markdownConverter 38 | ->setBreaksEnabled(true) 39 | ->text($markdown); 40 | //$convertedHmtl = str_replace("
    ", '
    ', $convertedHmtl);
    41 |         return $convertedHmtl;
    42 | 
    43 |     }
    44 | 
    45 |     /**
    46 |      * Convert Html To Markdown.
    47 |      *
    48 |      * @param $html
    49 |      * @return string
    50 |      */
    51 |     public function convertHtmlToMarkdown($html)
    52 |     {
    53 |         return $this->htmlConverter->convert($html);
    54 |     }
    55 | 
    56 | }
    
    
    --------------------------------------------------------------------------------
    /app/Base/Traits/GetModelByMorpType.php:
    --------------------------------------------------------------------------------
     1 | method()){
    15 |             case 'GET':
    16 |                 return [];
    17 |             default:
    18 |                 return [
    19 |                     'type' => 'required',
    20 |                     'type_id' => 'required'
    21 |                 ];
    22 |         }
    23 |     }
    24 | 
    25 |     protected function map(){
    26 | 
    27 |         return [];
    28 |     }
    29 | 
    30 |     protected function getModelClass($type = null)
    31 |     {
    32 |         if ($type == null){
    33 |             $type = $this->get('type');
    34 |         }
    35 |         return $this->map()[$type];
    36 |     }
    37 | 
    38 |     public function getModel($type = null,$type_id = null)
    39 |     {
    40 | 
    41 | 
    42 |         $modelClass =  $this->getModelClass($type);
    43 |         if(! $modelClass){
    44 |             throw new FavoriteException('type参数有误',400);
    45 |         }
    46 |         $model = $modelClass::find($type_id ?? $this->type_id);
    47 | 
    48 |         if(! $model){
    49 |             throw new FavoriteException('模型未找到',404);
    50 |         }
    51 |         return $model;
    52 | 
    53 |     }
    54 | 
    55 | }
    
    
    --------------------------------------------------------------------------------
    /app/Http/Controllers/Api/DraftsController.php:
    --------------------------------------------------------------------------------
     1 | middleware('auth:api');
    17 |     }
    18 | 
    19 |     public function show(Draft $draft){
    20 |         $lastUpdate = $draft;
    21 |         if ($draft->children()->count() > 0){
    22 |             $lastUpdate = $draft->children()->latest()->first();
    23 |         }
    24 |         return new DraftResource($lastUpdate->load(['user','relation']));
    25 |     }
    26 | 
    27 |     public function update(Request $request,Draft $draft){
    28 | 
    29 |         $this->validate($request,[
    30 |             'title' => 'required',
    31 |             'body' => ''
    32 |         ]);
    33 |         $fields = $request->except('_method');
    34 | 
    35 |         if (!$request->get('body')){
    36 |            $fields['body'] = '';
    37 |         }
    38 | 
    39 |         $newDraft = $draft->children()->create($fields + [
    40 |             'user_id' => Auth::id()
    41 |         ]);
    42 |         $newDraft->relation_id = $draft->relation_id;
    43 |         $newDraft->relation_type = $draft->relation_type;
    44 |         $newDraft->save();
    45 |         return $this->message('保存成功');
    46 | 
    47 |     }
    48 | }
    49 | 
    
    
    --------------------------------------------------------------------------------
    /config/trustedproxy.php:
    --------------------------------------------------------------------------------
     1 |  null, // [,], '*'
    19 | 
    20 |     /*
    21 |      * To trust one or more specific proxies that connect
    22 |      * directly to your server, use an array of IP addresses:
    23 |      */
    24 |      # 'proxies' => ['192.168.1.1'],
    25 | 
    26 |     /*
    27 |      * Or, to trust all proxies that connect
    28 |      * directly to your server, use a "*"
    29 |      */
    30 |      # 'proxies' => '*',
    31 | 
    32 |     /*
    33 |      * Which headers to use to detect proxy related data (For, Host, Proto, Port)
    34 |      * 
    35 |      * Options include:
    36 |      * 
    37 |      * - Illuminate\Http\Request::HEADER_X_FORWARDED_ALL (use all x-forwarded-* headers to establish trust)
    38 |      * - Illuminate\Http\Request::HEADER_FORWARDED (use the FORWARDED header to establish trust)
    39 |      * 
    40 |      * @link https://symfony.com/doc/current/deployment/proxies.html
    41 |      */
    42 |     'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL,
    43 | 
    44 |     
    45 | ];
    46 | 
    
    
    --------------------------------------------------------------------------------
    /resources/assets/js/pages/Article.vue:
    --------------------------------------------------------------------------------
     1 | 
    
    
    --------------------------------------------------------------------------------
    /app/Base/Traits/Subscribable.php:
    --------------------------------------------------------------------------------
     1 | subscriptions()->firstOrCreate([
    11 |             'user_id' => $userId ?: auth()->id()
    12 |         ]);
    13 |     }
    14 | 
    15 |     public function unsubscribe($userId = null){
    16 | 
    17 |         $this->subscriptions()
    18 |             ->where('user_id',$userId ?: auth()->id())
    19 |             ->delete();
    20 | 
    21 |     }
    22 | 
    23 |     /**
    24 |      * Determine if the current type has been subscribed.
    25 |      *
    26 |      * @return boolean
    27 |      */
    28 |     public function isSubscribed()
    29 |     {
    30 |         return !! $this->subscriptions()->where('user_id', auth()->id())->count();
    31 |     }
    32 | 
    33 |     /**
    34 |      * Fetch the subscribe status as a property.
    35 |      *
    36 |      * @return bool
    37 |      */
    38 |     public function getIsSubscribedAttribute()
    39 |     {
    40 |         return $this->subscriptions()->where('user_id', auth()->id())->exists();
    41 |     }
    42 | 
    43 |     /**
    44 |      * Get the number of subscriptions for the reply.
    45 |      *
    46 |      * @return integer
    47 |      */
    48 |     public function getSubscriptionsCountAttribute()
    49 |     {
    50 |         return $this->subscriptions()->count();
    51 |     }
    52 | 
    53 | 
    54 |     public function subscriptions(){
    55 | 
    56 |         return $this->morphMany(Subscription::class,'subscribable');
    57 |     }
    58 | 
    59 | }
    
    
    --------------------------------------------------------------------------------
    /database/migrations/2017_05_28_025758_create_articles_table.php:
    --------------------------------------------------------------------------------
     1 | increments('id');
    18 |             $table->unsignedInteger('user_id');
    19 |             $table->unsignedInteger('category_id');
    20 |             $table->unsignedInteger('replies_count')->default(0);
    21 |             $table->unsignedInteger('views_count')->default(0);
    22 |             $table->string('title');
    23 |             $table->string('page_image')->nullable();
    24 |             $table->string('slug')->nullable();
    25 |             $table->text('body');
    26 |             $table->boolean('is_original')->default(false)->comment('是否为原创');
    27 |             $table->boolean('is_secret')->default(false)->comment('是否为私密文章');
    28 | 
    29 |             $table->unsignedInteger('draft_id')->nullable();
    30 |             $table->softDeletes();
    31 |             $table->timestamps();
    32 |         });
    33 |     }
    34 | 
    35 |     /**
    36 |      * Reverse the migrations.
    37 |      *
    38 |      * @return void
    39 |      */
    40 |     public function down()
    41 |     {
    42 |         Schema::dropIfExists('articles');
    43 |     }
    44 | }
    45 | 
    
    
    --------------------------------------------------------------------------------
    /app/Providers/AuthServiceProvider.php:
    --------------------------------------------------------------------------------
     1 |  'App\Policies\ModelPolicy',
    30 |         Article::class => ArticlePolicy::class,
    31 |         User::class => UserPolicy::class,
    32 |         Comment::class => CommentPolicy::class,
    33 |         SpecialPage::class => SpecialPagePolicy::class,
    34 |         Draft::class => DraftPolicy::class,
    35 |         Discussion::class => DiscussionPolicy::class
    36 |     ];
    37 | 
    38 |     /**
    39 |      * Register any authentication / authorization services.
    40 |      *
    41 |      * @return void
    42 |      */
    43 |     public function boot()
    44 |     {
    45 |         Passport::routes();
    46 | 
    47 |         $this->registerPolicies();
    48 | 
    49 |         //
    50 |     }
    51 | }
    52 | 
    
    
    --------------------------------------------------------------------------------
    /app/Http/Controllers/Api/FavoriteController.php:
    --------------------------------------------------------------------------------
     1 | middleware('auth:api')->except('index');
    16 | 
    17 |     }
    18 | 
    19 |     public function index($type,$type_id,FavoriteRequest $request){
    20 | 
    21 |         $limit = Input::get('limit') ?: 20;
    22 |         $model = $request->getModel($type,$type_id);
    23 | 
    24 |         $favorites = $model->favorites()->with('user')->paginate($limit);
    25 |         return FavoriteResource::collection($favorites);
    26 |     }
    27 |     
    28 |     // 用户点赞
    29 |     public function store(FavoriteRequest $request)
    30 |     {
    31 | 
    32 |         try{
    33 |             $favorite = $request->store();
    34 |         }catch(FavoriteException $e){
    35 |             return $e->response();
    36 |         }
    37 | 
    38 |         $request->getModel()->notifyFavorited();
    39 | 
    40 |         return new FavoriteResource($favorite->load('user'));
    41 |         
    42 |     }
    43 | 
    44 |     // 用户取消点赞
    45 |     public function destroy(FavoriteRequest $request){
    46 | 
    47 |         try{
    48 |             $request->destroy();
    49 |         }catch(FavoriteException $e){
    50 |             return $e->response();
    51 |         }
    52 | 
    53 |         return $this->message('取消点赞成功');
    54 | 
    55 |     }
    56 | 
    57 | 
    58 | }
    59 | 
    
    
    --------------------------------------------------------------------------------
    /resources/assets/sass/vender/fontawesome/_mixins.scss:
    --------------------------------------------------------------------------------
     1 | // Mixins
     2 | // --------------------------
     3 | 
     4 | @mixin fa-icon {
     5 |   -webkit-font-smoothing: antialiased;
     6 |   -moz-osx-font-smoothing: grayscale;
     7 |   display: inline-block;
     8 |   font-style: normal;
     9 |   font-variant: normal;
    10 |   font-weight: normal;
    11 |   line-height: 1;
    12 |   vertical-align: -.125em;
    13 | }
    14 | 
    15 | @mixin fa-icon-rotate($degrees, $rotation) {
    16 |   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
    17 |   transform: rotate($degrees);
    18 | }
    19 | 
    20 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
    21 |   -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
    22 |   transform: scale($horiz, $vert);
    23 | }
    24 | 
    25 | 
    26 | // Only display content to screen readers. A la Bootstrap 4.
    27 | //
    28 | // See: http://a11yproject.com/posts/how-to-hide-content/
    29 | 
    30 | @mixin sr-only {
    31 |   border: 0;
    32 |   clip: rect(0, 0, 0, 0);
    33 |   height: 1px;
    34 |   margin: -1px;
    35 |   overflow: hidden;
    36 |   padding: 0;
    37 |   position: absolute;
    38 |   width: 1px;
    39 | }
    40 | 
    41 | // Use in conjunction with .sr-only to only display content when it's focused.
    42 | //
    43 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
    44 | //
    45 | // Credit: HTML5 Boilerplate
    46 | 
    47 | @mixin sr-only-focusable {
    48 |   &:active,
    49 |   &:focus {
    50 |     clip: auto;
    51 |     height: auto;
    52 |     margin: 0;
    53 |     overflow: visible;
    54 |     position: static;
    55 |     width: auto;
    56 |   }
    57 | }
    58 | 
    
    
    --------------------------------------------------------------------------------
    /config/hashids.php:
    --------------------------------------------------------------------------------
     1 | 
     7 |  *
     8 |  * For the full copyright and license information, please view the LICENSE
     9 |  * file that was distributed with this source code.
    10 |  */
    11 | 
    12 | declare(strict_types=1);
    13 | 
    14 | return [
    15 | 
    16 |     /*
    17 |     |--------------------------------------------------------------------------
    18 |     | Default Connection Name
    19 |     |--------------------------------------------------------------------------
    20 |     |
    21 |     | Here you may specify which of the connections below you wish to use as
    22 |     | your default connection for all work. Of course, you may use many
    23 |     | connections at once using the manager class.
    24 |     |
    25 |     */
    26 | 
    27 |     'default' => 'main',
    28 | 
    29 |     /*
    30 |     |--------------------------------------------------------------------------
    31 |     | Hashids Connections
    32 |     |--------------------------------------------------------------------------
    33 |     |
    34 |     | Here are each of the connections setup for your application. Example
    35 |     | configuration has been included, but you may add as many connections as
    36 |     | you would like.
    37 |     |
    38 |     */
    39 | 
    40 |     'connections' => [
    41 | 
    42 |         'main' => [
    43 |             'salt' => '',
    44 |             'length' => 30,
    45 |         ],
    46 | 
    47 |         'alternative' => [
    48 |             'salt' => 'your-salt-string',
    49 |             'length' => 'your-length-integer',
    50 |         ],
    51 | 
    52 |     ],
    53 | 
    54 | ];
    55 | 
    
    
    --------------------------------------------------------------------------------
    /resources/views/admin/partials/slide_menu.blade.php:
    --------------------------------------------------------------------------------
     1 | 
    47 | 
    48 | 
    
    
    --------------------------------------------------------------------------------
    /resources/views/vendor/pagination/admin.blade.php:
    --------------------------------------------------------------------------------
     1 | @if ($paginator->hasPages())
     2 | 
     3 | 
     4 |     
    41 | 
    42 | @endif
    
    
    --------------------------------------------------------------------------------
    /resources/views/vendor/pagination/bootstrap-4.blade.php:
    --------------------------------------------------------------------------------
     1 | @if ($paginator->hasPages())
     2 |     
      3 | {{-- Previous Page Link --}} 4 | @if ($paginator->onFirstPage()) 5 |
    • «
    • 6 | @else 7 |
    • 8 | @endif 9 | 10 | {{-- Pagination Elements --}} 11 | @foreach ($elements as $element) 12 | {{-- "Three Dots" Separator --}} 13 | @if (is_string($element)) 14 |
    • {{ $element }}
    • 15 | @endif 16 | 17 | {{-- Array Of Links --}} 18 | @if (is_array($element)) 19 | @foreach ($element as $page => $url) 20 | @if ($page == $paginator->currentPage()) 21 |
    • {{ $page }}
    • 22 | @else 23 |
    • {{ $page }}
    • 24 | @endif 25 | @endforeach 26 | @endif 27 | @endforeach 28 | 29 | {{-- Next Page Link --}} 30 | @if ($paginator->hasMorePages()) 31 |
    • 32 | @else 33 |
    • »
    • 34 | @endif 35 |
    36 | @endif 37 | -------------------------------------------------------------------------------- /resources/views/vendor/pagination/default.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 3 | 4 | 41 | 42 | @endif -------------------------------------------------------------------------------- /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": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 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 --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.17", 14 | "popper.js": "^1.12", 15 | "babel-polyfill": "^6.23.0", 16 | "bootstrap-sass": "^3.3.7", 17 | "buefy": "^0.6.2", 18 | "bulma": "^0.6.2", 19 | "cross-env": "^5.1", 20 | "fine-uploader": "^5.14.4", 21 | "ionicons": "^2.0.1", 22 | "jquery": "^3.2", 23 | "laravel-mix": "^2.0", 24 | "lodash": "^4.17.4", 25 | "vue": "^2.5.7", 26 | "vue-image-crop-upload": "^1.3.11", 27 | "vue-router": "^2.5.3" 28 | }, 29 | "dependencies": { 30 | "@fortawesome/fontawesome-free-webfonts": "^1.0.3", 31 | "marked": "^0.3.6", 32 | "moment": "^2.18.1", 33 | "particles.js": "^2.0.0", 34 | "simplemde": "^1.11.2", 35 | "social-share.js": "^1.0.16", 36 | "vue-multiselect": "^2.0.0-beta.15" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /resources/views/articles/partials/user.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
    3 |
    4 |

    5 | 关于作者 6 |

    7 | 8 | 查看全部 9 | 10 |
    11 |
    12 |
    13 |
    14 |
    15 | 16 | {{ $article->user->name }} 17 | 18 |
    19 |
    20 |
    21 |

    22 | {{ $article->user->name }} 23 |
    24 | @if($article->user->signature) 25 | {{ $article->user->signature }} 26 | @else 27 | 该用户很懒,什么都没有留下 28 | @endif 29 | 30 |

    31 |
    32 |
    33 | 34 |
    35 | @can('update',$article->user) 36 | 编辑个人资料 37 | @endcan 38 |
    39 |
    40 |
    -------------------------------------------------------------------------------- /app/Notifications/ArticleWasFavorited.php: -------------------------------------------------------------------------------- 1 | article = $article; 26 | } 27 | 28 | /** 29 | * Get the notification's delivery channels. 30 | * 31 | * @param mixed $notifiable 32 | * @return array 33 | */ 34 | public function via($notifiable) 35 | { 36 | return ['database']; 37 | } 38 | 39 | 40 | 41 | /** 42 | * Get the array representation of the notification. 43 | * 44 | * @param mixed $notifiable 45 | * @return array 46 | */ 47 | public function toArray($notifiable) 48 | { 49 | $user = Auth::user(); 50 | return [ 51 | 'article_id' => $this->article->id, 52 | 'user_id' => $user->id 53 | ]; 54 | } 55 | 56 | public static function map($data) 57 | { 58 | $article = Article::query()->find($data['article_id']); 59 | $user = User::query()->find($data['user_id']); 60 | 61 | return (object)[ 62 | 'article' => $article, 63 | 'user' => $user 64 | ]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/Notifications/AnswerWasUpdateBest.php: -------------------------------------------------------------------------------- 1 | comment = $comment; 28 | $this->user = $user; 29 | } 30 | 31 | /** 32 | * Get the notification's delivery channels. 33 | * 34 | * @param mixed $notifiable 35 | * @return array 36 | */ 37 | public function via($notifiable) 38 | { 39 | return ['database']; 40 | } 41 | 42 | 43 | /** 44 | * Get the array representation of the notification. 45 | * 46 | * @param mixed $notifiable 47 | * @return array 48 | */ 49 | public function toArray($notifiable) 50 | { 51 | return [ 52 | 'comment_id' => $this->comment->id, 53 | 'user_id' => $this->user->id 54 | ]; 55 | } 56 | 57 | public static function map($data) 58 | { 59 | $discussion = Comment::query()->find($data['comment_id']); 60 | $user = User::query()->find($data['user_id']); 61 | 62 | return (object)[ 63 | 'comment' => $discussion, 64 | 'user' => $user 65 | ]; 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/Notifications/CommentWasFavorited.php: -------------------------------------------------------------------------------- 1 | comment = $comment; 27 | } 28 | 29 | /** 30 | * Get the notification's delivery channels. 31 | * 32 | * @param mixed $notifiable 33 | * @return array 34 | */ 35 | public function via($notifiable) 36 | { 37 | return ['database']; 38 | } 39 | 40 | 41 | /** 42 | * Get the array representation of the notification. 43 | * 44 | * @param mixed $notifiable 45 | * @return array 46 | */ 47 | public function toArray($notifiable) 48 | { 49 | $user = Auth::user(); 50 | return [ 51 | 'comment_id' => $this->comment->id, 52 | 'user_id' => $user->id 53 | ]; 54 | } 55 | 56 | public static function map($data) 57 | { 58 | 59 | $comment = Comment::query()->find($data['comment_id']); 60 | $user = User::query()->find($data['user_id']); 61 | 62 | return (object)[ 63 | 'comment' => $comment, 64 | 'user' => $user 65 | ]; 66 | 67 | } 68 | } 69 | --------------------------------------------------------------------------------