├── public ├── favicon.ico ├── .gitignore ├── robots.txt ├── .htaccess ├── web.config └── index.php ├── frontend ├── src │ ├── assets │ │ ├── .keep │ │ └── img │ │ │ └── info.png │ ├── theme │ │ └── default.less │ ├── utils │ │ ├── Wx.js │ │ ├── Storage.js │ │ ├── Helper.js │ │ ├── Url.js │ │ └── Http.js │ ├── mobile │ │ ├── Error.vue │ │ ├── Login.vue │ │ └── Qrlogin.vue │ ├── CDesktop.vue │ ├── mobile.js │ ├── desktop.js │ ├── components │ │ ├── SpinWrapper.vue │ │ └── DataTable.vue │ ├── router │ │ ├── mobile.js │ │ └── desktop.js │ ├── desktop │ │ ├── Error.vue │ │ └── Departments.vue │ ├── CMobile.vue │ └── auth │ │ └── Auth.js ├── static │ └── .gitkeep ├── config │ ├── .gitignore │ ├── prod.env.js │ ├── test.env.js │ ├── dev.env.js │ └── index.js.example ├── .eslintignore ├── .gitignore ├── test │ └── unit │ │ ├── .eslintrc │ │ ├── specs │ │ └── Hello.spec.js │ │ ├── index.js │ │ └── karma.conf.js ├── .editorconfig ├── .postcssrc.js ├── .babelrc ├── build │ ├── dev-client.js │ ├── vue-loader.conf.js │ ├── webpack.test.conf.js │ ├── build.js │ ├── check-versions.js │ ├── webpack.dev.conf.js │ ├── webpack.base.conf.js │ ├── utils.js │ └── dev-server.js ├── index.html ├── mobile.html ├── README.md ├── .eslintrc.js └── package.json ├── database ├── .gitignore ├── seeds │ ├── DatabaseSeeder.php │ └── UsersTableSeeder.php ├── factories │ └── ModelFactory.php └── migrations │ ├── 2017_04_27_101040_create_request_logs_collection.php │ ├── 2017_03_14_204633_create_failed_jobs_table.php │ ├── 2017_03_13_152355_create_departments_table.php │ ├── 2017_04_07_145100_add_rbac_auth.php │ ├── 2017_03_12_193242_add_user_auth.php │ ├── 2017_03_13_164637_add_departments_auth.php │ ├── 2017_07_09_172152_create_department_user_table.php │ ├── 2017_03_14_203920_add_qrlogin_auth.php │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2017_03_10_182637_seed_users.php │ └── 2017_03_10_155503_entrust_setup_tables.php ├── bootstrap ├── cache │ └── .gitignore ├── autoload.php └── app.php ├── storage ├── logs │ └── .gitignore ├── app │ ├── public │ │ └── .gitignore │ ├── qywx │ │ └── .gitignore │ ├── upload │ │ └── .gitignore │ └── .gitignore └── framework │ ├── cache │ └── .gitignore │ ├── testing │ └── .gitignore │ ├── views │ └── .gitignore │ ├── sessions │ └── .gitignore │ └── .gitignore ├── resources ├── 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 │ │ │ │ └── layout.blade.php │ │ ├── pagination │ │ │ ├── simple-default.blade.php │ │ │ ├── simple-bootstrap-4.blade.php │ │ │ ├── default.blade.php │ │ │ └── bootstrap-4.blade.php │ │ └── notifications │ │ │ └── email.blade.php │ └── welcome.blade.php ├── assets │ ├── sass │ │ ├── app.scss │ │ └── _variables.scss │ └── js │ │ ├── app.js │ │ ├── components │ │ └── Example.vue │ │ └── bootstrap.js └── lang │ └── en │ ├── pagination.php │ ├── auth.php │ └── passwords.php ├── .gitattributes ├── screenshots ├── user.png ├── login_1.png └── login_2.png ├── app ├── Role.php ├── Permission.php ├── RequestLog.php ├── Department.php ├── Http │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── VerifyCsrfToken.php │ │ ├── TrimStrings.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── CanPath.php │ │ ├── RecordRequest.php │ │ └── PreventMongodbJnjection.php │ ├── Controllers │ │ ├── Controller.php │ │ ├── Auth │ │ │ └── LoginController.php │ │ └── Api │ │ │ └── V1 │ │ │ ├── DepartmentController.php │ │ │ ├── WechatController.php │ │ │ ├── UserController.php │ │ │ └── FileController.php │ └── Kernel.php ├── File.php ├── Providers │ ├── BroadcastServiceProvider.php │ ├── AuthServiceProvider.php │ ├── EventServiceProvider.php │ ├── AppServiceProvider.php │ └── RouteServiceProvider.php ├── Exceptions │ ├── NormalException.php │ └── Handler.php ├── Repositories │ ├── DepartmentRepository.php │ ├── AbstractRepository.php │ └── UserRepository.php ├── Jobs │ └── SyncFromQywx.php ├── Console │ ├── Commands │ │ └── Rbac │ │ │ ├── RemovePerm.php │ │ │ ├── RemoveRole.php │ │ │ ├── ResetPassword.php │ │ │ ├── AttachRole.php │ │ │ ├── DetachRole.php │ │ │ ├── AttachPerm.php │ │ │ ├── DetachPerm.php │ │ │ ├── AddRole.php │ │ │ ├── AddPerm.php │ │ │ ├── Perms.php │ │ │ ├── Roles.php │ │ │ └── AddUser.php │ └── Kernel.php ├── Biz │ └── UserBiz.php └── User.php ├── .editorconfig ├── artisan.bat ├── deploy.sh ├── tests ├── UnitTestCase.php ├── Unit │ └── ExampleTest.php ├── CreatesApplication.php ├── Feature │ ├── DepartmentTest.php │ ├── RbacTest.php │ ├── UserTest.php │ └── AuthTest.php └── TestCase.php ├── routes ├── web.php ├── channels.php ├── console.php └── api.php ├── config ├── qywx.php ├── view.php ├── services.php ├── broadcasting.php ├── filesystems.php ├── queue.php ├── cache.php ├── entrust.php └── auth.php ├── .gitignore ├── webpack.mix.js ├── server.php ├── LICENSE ├── .env.example ├── package.json ├── phpunit.xml.example ├── artisan ├── composer.json ├── readme.md └── install.sh /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /frontend/config/.gitignore: -------------------------------------------------------------------------------- 1 | index.js 2 | -------------------------------------------------------------------------------- /public/.gitignore: -------------------------------------------------------------------------------- 1 | static 2 | *.html 3 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/qywx/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/upload/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.css linguist-vendored 2 | *.scss linguist-vendored 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !upload/ 3 | !public/ 4 | !qywx/ 5 | !.gitignore 6 | -------------------------------------------------------------------------------- /frontend/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /resources/views/vendor/mail/markdown/promotion/button.blade.php: -------------------------------------------------------------------------------- 1 | [{{ $slot }}]({{ $url }}) 2 | -------------------------------------------------------------------------------- /screenshots/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purocean/laravel-template/HEAD/screenshots/user.png -------------------------------------------------------------------------------- /screenshots/login_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purocean/laravel-template/HEAD/screenshots/login_1.png -------------------------------------------------------------------------------- /screenshots/login_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purocean/laravel-template/HEAD/screenshots/login_2.png -------------------------------------------------------------------------------- /frontend/src/theme/default.less: -------------------------------------------------------------------------------- 1 | @import '~iview/src/styles/index.less'; 2 | 3 | // @primary-color: #3399ff; 4 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | yarn-error.log 6 | test/unit/coverage 7 | -------------------------------------------------------------------------------- /frontend/src/assets/img/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purocean/laravel-template/HEAD/frontend/src/assets/img/info.png -------------------------------------------------------------------------------- /resources/views/vendor/mail/html/table.blade.php: -------------------------------------------------------------------------------- 1 |
| 4 | {{ Illuminate\Mail\Markdown::parse($slot) }} 5 | | 6 |
| 6 | {{ Illuminate\Mail\Markdown::parse($slot) }} 7 | | 8 |
{{ $route.query.message }}
5 || 7 | {{ Illuminate\Mail\Markdown::parse($slot) }} 8 | | 9 |
4 |
|
12 |
4 |
|
18 |
{{ message }}
3 | 4 | 5 | 55 | -------------------------------------------------------------------------------- /app/Console/Commands/Rbac/DetachPerm.php: -------------------------------------------------------------------------------- 1 | argument('rolename'); 43 | $permname = $this->argument('permname'); 44 | 45 | $role = Role::where(['name' => $rolename])->firstOrFail(); 46 | $perm = Permission::where(['name' => $permname])->firstOrFail(); 47 | 48 | $role->detachPermission($perm); 49 | 50 | $this->info("detach permission $permname from $rolename"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Http/Middleware/PreventMongodbJnjection.php: -------------------------------------------------------------------------------- 1 | except as $path) { 28 | if ($request->is($path)) { 29 | return $next($request); 30 | } 31 | } 32 | 33 | $transform = function ($value) use (&$transform) { 34 | if (is_array($value)) { 35 | foreach ($value as $k => $v) { 36 | if (is_string($k)) { 37 | unset($value[$k]); 38 | $value[str_replace(['$', chr(0)], '', $k)] = $transform($v); 39 | } 40 | } 41 | } 42 | 43 | return $value; 44 | }; 45 | 46 | $request->replace($transform($request->all())); 47 | 48 | return $next($request); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /database/migrations/2017_03_14_203920_add_qrlogin_auth.php: -------------------------------------------------------------------------------- 1 | '/qrlogin/*']); 18 | 19 | Artisan::call('rbac:attachperm', ['rolename' => 'suadmin', 'permname' => '/qrlogin/*']); 20 | Artisan::call('rbac:attachperm', ['rolename' => 'admin', 'permname' => '/qrlogin/*']); 21 | Artisan::call('rbac:attachperm', ['rolename' => 'user', 'permname' => '/qrlogin/*']); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Artisan::call('rbac:detachperm', ['rolename' => 'user', 'permname' => '/qrlogin/*']); 32 | Artisan::call('rbac:detachperm', ['rolename' => 'admin', 'permname' => '/qrlogin/*']); 33 | Artisan::call('rbac:detachperm', ['rolename' => 'suadmin', 'permname' => '/qrlogin/*']); 34 | 35 | Artisan::call('rbac:removeperm', ['name' => '/qrlogin/*']); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Feature/DepartmentTest.php: -------------------------------------------------------------------------------- 1 | getJson('/api/departments')->assertStatus(401); 17 | 18 | $this->iam('usertest')->getJson('/api/departments')->assertStatus(403); 19 | 20 | $this->iam('useradmin')->getJson('/api/departments') 21 | ->assertStatus(200) 22 | ->assertJson(['status' => 'ok']); 23 | } 24 | 25 | public function testSync() 26 | { 27 | $this->postJson('/api/departments/sync')->assertStatus(401); 28 | 29 | $this->iam('usertest')->postJson('/api/departments/sync')->assertStatus(403); 30 | 31 | $this->iam('suadmin')->getJson('/api/departments/sync')->assertStatus(405); 32 | 33 | $this->iam('suadmin', function () { 34 | Queue::fake(); 35 | })->postJson('/api/departments/sync') 36 | ->assertStatus(200) 37 | ->assertJson(['status' => 'ok']); 38 | 39 | Queue::assertPushed(SyncFromQywx::class); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('username')->unique()->comment('用户名'); 19 | $table->string('name')->default('')->comment('名字'); 20 | $table->string('email')->unique()->nullable()->comment('邮箱'); 21 | $table->string('mobile')->default('')->comment('电话号码'); 22 | $table->string('avatar')->default('')->comment('头像'); 23 | $table->string('password')->comment('密码'); 24 | $table->json('info')->comment('个人信息'); 25 | $table->smallInteger('status')->default(0)->comment('状态'); 26 | $table->rememberToken(); 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('users'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Console/Commands/Rbac/AddRole.php: -------------------------------------------------------------------------------- 1 | argument('name'); 44 | $displayName = $this->argument('displayName') ?: $name; 45 | $description = $this->argument('description') ?: $name; 46 | 47 | $role->name = $name; 48 | $role->display_name = $displayName; 49 | $role->description = $description; 50 | 51 | $role->saveOrFail(); 52 | 53 | $this->info("new role {$name}"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /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 | @if (isset($actionText)) 21 | 33 | @component('mail::button', ['url' => $actionUrl, 'color' => $color]) 34 | {{ $actionText }} 35 | @endcomponent 36 | @endif 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 | Regards,
29 |
|
51 |
4 | {{ name }}
6 | 7 |