├── .DS_Store ├── .env.example ├── .gitattributes ├── .gitignore ├── LICENSE ├── app ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Helpers.php ├── Http │ ├── Controllers │ │ ├── Admin │ │ │ ├── AdminController.php │ │ │ ├── LoginController.php │ │ │ ├── MenuController.php │ │ │ ├── PermissionController.php │ │ │ ├── RolesController.php │ │ │ ├── TestController.php │ │ │ └── UserController.php │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ └── ResetPasswordController.php │ │ └── Controller.php │ ├── Kernel.php │ ├── Middleware │ │ ├── CanMiddleware.php │ │ ├── EncryptCookies.php │ │ ├── LoginAuthenticated.php │ │ ├── MenuMiddleware.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustProxies.php │ │ └── VerifyCsrfToken.php │ └── Models │ │ ├── Menu.php │ │ ├── MenuRoles.php │ │ ├── Permission.php │ │ ├── RolePermission.php │ │ ├── Roles.php │ │ ├── Users.php │ │ └── UsersRoles.php ├── Library │ └── Response.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── Service │ └── RouteService.php ├── User.php └── Validate │ ├── BaseValidate.php │ ├── MenuStoreValidate.php │ ├── MenuUpdateValidate.php │ ├── ModifyPwdValidate.php │ ├── PermissionStoreValidate.php │ ├── PermissionUpdateValidate.php │ ├── RolesStoreValidate.php │ ├── RolesUpdateValidate.php │ ├── UserStoreValidate.php │ └── UserUpdateValidate.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── captcha.php ├── database.php ├── filesystems.php ├── mail.php ├── queue.php ├── services.php ├── session.php ├── view.php └── web.php ├── database ├── .gitignore ├── factories │ └── UserFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ └── 2014_10_12_100000_create_password_resets_table.php └── seeds │ └── DatabaseSeeder.php ├── package.json ├── phpunit.xml ├── public ├── .DS_Store ├── .htaccess ├── css │ ├── app.css │ └── login.css ├── favicon.ico ├── index.php ├── js │ ├── app.js │ ├── ext │ │ └── treeTable.js │ ├── jquery1.12.1.js │ └── layui │ │ ├── css │ │ ├── layui.css │ │ ├── layui.mobile.css │ │ └── modules │ │ │ ├── code.css │ │ │ ├── laydate │ │ │ └── default │ │ │ │ └── laydate.css │ │ │ └── layer │ │ │ └── default │ │ │ ├── icon-ext.png │ │ │ ├── icon.png │ │ │ ├── layer.css │ │ │ ├── loading-0.gif │ │ │ ├── loading-1.gif │ │ │ └── loading-2.gif │ │ ├── font │ │ ├── iconfont.eot │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ │ ├── images │ │ └── face │ │ │ ├── 0.gif │ │ │ ├── 1.gif │ │ │ ├── 10.gif │ │ │ ├── 11.gif │ │ │ ├── 12.gif │ │ │ ├── 13.gif │ │ │ ├── 14.gif │ │ │ ├── 15.gif │ │ │ ├── 16.gif │ │ │ ├── 17.gif │ │ │ ├── 18.gif │ │ │ ├── 19.gif │ │ │ ├── 2.gif │ │ │ ├── 20.gif │ │ │ ├── 21.gif │ │ │ ├── 22.gif │ │ │ ├── 23.gif │ │ │ ├── 24.gif │ │ │ ├── 25.gif │ │ │ ├── 26.gif │ │ │ ├── 27.gif │ │ │ ├── 28.gif │ │ │ ├── 29.gif │ │ │ ├── 3.gif │ │ │ ├── 30.gif │ │ │ ├── 31.gif │ │ │ ├── 32.gif │ │ │ ├── 33.gif │ │ │ ├── 34.gif │ │ │ ├── 35.gif │ │ │ ├── 36.gif │ │ │ ├── 37.gif │ │ │ ├── 38.gif │ │ │ ├── 39.gif │ │ │ ├── 4.gif │ │ │ ├── 40.gif │ │ │ ├── 41.gif │ │ │ ├── 42.gif │ │ │ ├── 43.gif │ │ │ ├── 44.gif │ │ │ ├── 45.gif │ │ │ ├── 46.gif │ │ │ ├── 47.gif │ │ │ ├── 48.gif │ │ │ ├── 49.gif │ │ │ ├── 5.gif │ │ │ ├── 50.gif │ │ │ ├── 51.gif │ │ │ ├── 52.gif │ │ │ ├── 53.gif │ │ │ ├── 54.gif │ │ │ ├── 55.gif │ │ │ ├── 56.gif │ │ │ ├── 57.gif │ │ │ ├── 58.gif │ │ │ ├── 59.gif │ │ │ ├── 6.gif │ │ │ ├── 60.gif │ │ │ ├── 61.gif │ │ │ ├── 62.gif │ │ │ ├── 63.gif │ │ │ ├── 64.gif │ │ │ ├── 65.gif │ │ │ ├── 66.gif │ │ │ ├── 67.gif │ │ │ ├── 68.gif │ │ │ ├── 69.gif │ │ │ ├── 7.gif │ │ │ ├── 70.gif │ │ │ ├── 71.gif │ │ │ ├── 8.gif │ │ │ └── 9.gif │ │ ├── lay │ │ └── modules │ │ │ ├── carousel.js │ │ │ ├── code.js │ │ │ ├── colorpicker.js │ │ │ ├── element.js │ │ │ ├── flow.js │ │ │ ├── form.js │ │ │ ├── jquery.js │ │ │ ├── laydate.js │ │ │ ├── layedit.js │ │ │ ├── layer.js │ │ │ ├── laypage.js │ │ │ ├── laytpl.js │ │ │ ├── mobile.js │ │ │ ├── rate.js │ │ │ ├── slider.js │ │ │ ├── table.js │ │ │ ├── transfer.js │ │ │ ├── tree.js │ │ │ ├── upload.js │ │ │ └── util.js │ │ ├── layui.all.js │ │ └── layui.js ├── robots.txt └── web.config ├── rbac.sql ├── readme.md ├── resources ├── assets │ ├── js │ │ ├── app.js │ │ ├── bootstrap.js │ │ └── components │ │ │ └── ExampleComponent.vue │ └── sass │ │ ├── _variables.scss │ │ └── app.scss ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php └── views │ ├── admin │ ├── 403.blade.php │ ├── index.blade.php │ ├── login.blade.php │ ├── menu │ │ ├── create.blade.php │ │ ├── edit.blade.php │ │ └── index.blade.php │ ├── modifyPwd.blade.php │ ├── permission │ │ ├── create.blade.php │ │ ├── edit.blade.php │ │ └── index.blade.php │ ├── roles │ │ ├── create.blade.php │ │ ├── edit.blade.php │ │ └── index.blade.php │ ├── test.blade.php │ └── user │ │ ├── create.blade.php │ │ ├── edit.blade.php │ │ └── index.blade.php │ ├── layouts │ └── admin.blade.php │ ├── vendor │ └── pagination │ │ ├── bootstrap-4.blade.php │ │ ├── default.blade.php │ │ ├── semantic-ui.blade.php │ │ ├── simple-bootstrap-4.blade.php │ │ └── simple-default.blade.php │ └── welcome.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── server.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php └── webpack.mix.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/.DS_Store -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY=base64:sAvu5IAQU9uagKukZanzzJQ7w09UBaXOy2nqxlaLaas= 4 | APP_DEBUG=true 5 | APP_LOG_LEVEL=debug 6 | APP_URL=http://localhost 7 | 8 | DB_CONNECTION=mysql 9 | DB_HOST=127.0.0.1 10 | DB_PORT=3306 11 | DB_DATABASE=homestead 12 | DB_USERNAME=homestead 13 | DB_PASSWORD=secret 14 | 15 | BROADCAST_DRIVER=log 16 | CACHE_DRIVER=file 17 | SESSION_DRIVER=file 18 | SESSION_LIFETIME=120 19 | QUEUE_DRIVER=sync 20 | 21 | REDIS_HOST=127.0.0.1 22 | REDIS_PASSWORD=null 23 | REDIS_PORT=6379 24 | 25 | MAIL_DRIVER=smtp 26 | MAIL_HOST=smtp.mailtrap.io 27 | MAIL_PORT=2525 28 | MAIL_USERNAME=null 29 | MAIL_PASSWORD=null 30 | MAIL_ENCRYPTION=null 31 | 32 | PUSHER_APP_ID= 33 | PUSHER_APP_KEY= 34 | PUSHER_APP_SECRET= 35 | PUSHER_APP_CLUSTER=mt1 36 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | /.idea 7 | /.vagrant 8 | Homestead.json 9 | Homestead.yaml 10 | npm-debug.log 11 | yarn-error.log 12 | .env 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 laravel_rbac_permission 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Console; 13 | 14 | use Illuminate\Console\Scheduling\Schedule; 15 | use Illuminate\Foundation\Console\Kernel as ConsoleKernel; 16 | 17 | class Kernel extends ConsoleKernel 18 | { 19 | /** 20 | * The Artisan commands provided by your application. 21 | * 22 | * @var array 23 | */ 24 | protected $commands = [ 25 | ]; 26 | 27 | /** 28 | * Define the application's command schedule. 29 | */ 30 | protected function schedule(Schedule $schedule) 31 | { 32 | // $schedule->command('inspire') 33 | // ->hourly(); 34 | } 35 | 36 | /** 37 | * Register the commands for the application. 38 | */ 39 | protected function commands() 40 | { 41 | $this->load(__DIR__.'/Commands'); 42 | 43 | require base_path('routes/console.php'); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Exceptions; 13 | 14 | use Exception; 15 | use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; 16 | 17 | class Handler extends ExceptionHandler 18 | { 19 | /** 20 | * A list of the exception types that are not reported. 21 | * 22 | * @var array 23 | */ 24 | protected $dontReport = [ 25 | ]; 26 | 27 | /** 28 | * A list of the inputs that are never flashed for validation exceptions. 29 | * 30 | * @var array 31 | */ 32 | protected $dontFlash = [ 33 | 'password', 34 | 'password_confirmation', 35 | ]; 36 | 37 | /** 38 | * Report or log an exception. 39 | * 40 | * This is a great spot to send exceptions to Sentry, Bugsnag, etc. 41 | */ 42 | public function report(Exception $exception) 43 | { 44 | parent::report($exception); 45 | } 46 | 47 | /** 48 | * Render an exception into an HTTP response. 49 | * 50 | * @param \Illuminate\Http\Request $request 51 | * 52 | * @return \Illuminate\Http\Response 53 | */ 54 | public function render($request, Exception $exception) 55 | { 56 | return parent::render($request, $exception); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/Helpers.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | function can() 13 | { 14 | $currRouteName = \Illuminate\Support\Facades\Route::currentRouteName(); 15 | 16 | if (ends_with($currRouteName, '.white')) { 17 | return true; 18 | } 19 | 20 | $user = session()->get('user'); 21 | if (\App\Http\Models\Users::ADMIN_YES == $user['administrator']) { 22 | return true; 23 | } 24 | 25 | $role_ids = \App\Http\Models\UsersRoles::where('users_id', $user['id'])->pluck('roles_id')->toArray(); 26 | 27 | $permission_ids = \App\Http\Models\RolePermission::whereIn('roles_id', $role_ids)->pluck('permission_id')->toArray(); 28 | 29 | $check = \App\Http\Models\Permission::whereIn('id', $permission_ids)->where('routes', 'like', "%{$currRouteName}%")->count(); 30 | if ($check > 0) { 31 | return true; 32 | } 33 | 34 | return false; 35 | } 36 | 37 | if (!function_exists('ends_with')) { 38 | /** 39 | * Determine if a given string ends with a given substring. 40 | * 41 | * @param string $haystack 42 | * @param string|array $needles 43 | * 44 | * @return bool 45 | */ 46 | function ends_with($haystack, $needles) 47 | { 48 | return \Illuminate\Support\Str::endsWith($haystack, $needles); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/AdminController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Admin; 13 | 14 | use App\Http\Controllers\Controller; 15 | use App\Http\Models\Users; 16 | use App\Library\Response; 17 | use App\Validate\ModifyPwdValidate; 18 | use Illuminate\Database\QueryException; 19 | use Illuminate\Http\Request; 20 | use Illuminate\Support\Facades\Hash; 21 | 22 | class AdminController extends Controller 23 | { 24 | public function index() 25 | { 26 | return view('admin.index'); 27 | } 28 | 29 | public function modifyPwd() 30 | { 31 | return view('admin.modifyPwd'); 32 | } 33 | 34 | public function newPwd(Request $request) 35 | { 36 | $validate = new ModifyPwdValidate($request); 37 | if (!$validate->goCheck()) { 38 | return Response::response(['code' => Response::PARAM_ERROR, 'msg' => $validate->errors->first()]); 39 | } 40 | 41 | $params = $validate->requestData; 42 | 43 | $user = Users::find(session('user')['id']); 44 | if (!$user) { 45 | return Response::response(['code' => Response::BAD_REQUEST]); 46 | } 47 | 48 | if (1 == $user->id) { 49 | //公共测试环境暂不允许修改超管密码~ 50 | return Response::response(['code' => Response::BAD_REQUEST, 'msg' => '公共测试环境暂不允许修改超管密码~']); 51 | } 52 | 53 | if (!Hash::check($params['oldPassword'], $user->password)) { 54 | return Response::response(['code' => Response::BAD_REQUEST, 'msg' => '请输入正确的当前密码']); 55 | } 56 | 57 | try { 58 | $user->password = Hash::make($params['password']); 59 | 60 | if ($user->save()) { 61 | //退出登录 62 | $request->session()->forget('user'); 63 | 64 | return Response::response(); 65 | } 66 | } catch (QueryException $e) { 67 | return Response::response(['e' => $e, 'code' => Response::SQL_ERROR]); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/LoginController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Admin; 13 | 14 | use App\Http\Controllers\Controller; 15 | use App\Http\Models\Users; 16 | use App\Library\Response; 17 | use Illuminate\Http\Request; 18 | use Illuminate\Support\Facades\Hash; 19 | use Illuminate\Support\Facades\Validator; 20 | 21 | class LoginController extends Controller 22 | { 23 | public function index() 24 | { 25 | if (session('user')) { 26 | return redirect(route('admin.index.white')); 27 | } 28 | 29 | return view('admin.login'); 30 | } 31 | 32 | public function login(Request $request) 33 | { 34 | $validator = Validator::make($request->all(), [ 35 | 'email' => 'required|email', 36 | 'password' => 'required', 37 | 'captcha' => 'required|captcha', 38 | ], [ 39 | 'email.required' => '请输入登录名', 40 | 'email.email' => '邮箱格式有误', 41 | 'password.required' => '请输入密码', 42 | 'captcha.required' => '请输入验证码', 43 | 'captcha.captcha' => '验证码有误', 44 | ]); 45 | 46 | if ($validator->fails()) { 47 | return Response::response(['code' => Response::PARAM_ERROR, 'msg' => $validator->errors()->first()]); 48 | } 49 | 50 | $data = $validator->getData(); 51 | 52 | $user = Users::where('email', '=', $data['email'])->first(); 53 | if (!$user || !Hash::check($data['password'], $user->password)) { 54 | return Response::response(['code' => Response::BAD_REQUEST, 'msg' => '登录名或密码有误']); 55 | } 56 | 57 | if (Users::STATUS_DISABLE == $user->status) { 58 | return Response::response(['code' => Response::BAD_REQUEST, 'msg' => '您的账户被禁用,请联系管理员']); 59 | } 60 | 61 | session(['user' => $user]); 62 | 63 | return Response::response(); 64 | } 65 | 66 | public function logout(Request $request) 67 | { 68 | $request->session()->forget('user'); 69 | 70 | return redirect(route('admin.login.white')); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/PermissionController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Admin; 13 | 14 | use App\Http\Controllers\Controller; 15 | use App\Http\Models\Permission; 16 | use App\Http\Models\RolePermission; 17 | use App\Library\Response; 18 | use App\Service\RouteService; 19 | use App\Validate\PermissionStoreValidate; 20 | use App\Validate\PermissionUpdateValidate; 21 | use Illuminate\Database\QueryException; 22 | use Illuminate\Http\Request; 23 | use Illuminate\Support\Facades\DB; 24 | use Illuminate\Support\Facades\Log; 25 | 26 | class PermissionController extends Controller 27 | { 28 | public function index() 29 | { 30 | $permissions = Permission::paginate(config('page_size')); 31 | 32 | return view('admin.permission.index', ['permissions' => $permissions]); 33 | } 34 | 35 | public function create() 36 | { 37 | $routes = RouteService::getRoutes(); 38 | 39 | return view('admin.permission.create', ['routes' => $routes]); 40 | } 41 | 42 | public function store(Request $request) 43 | { 44 | $validate = new PermissionStoreValidate($request); 45 | 46 | if (!$validate->goCheck()) { 47 | return Response::response(['code' => Response::PARAM_ERROR, 'msg' => $validate->errors->first()]); 48 | } 49 | 50 | $params = $validate->requestData; 51 | 52 | $permission = new Permission(); 53 | 54 | $permission->name = $params['name']; 55 | $permission->routes = implode(',', $params['route']); 56 | 57 | if (!$permission->save()) { 58 | return Response::response(['code' => Response::SQL_ERROR]); 59 | } 60 | 61 | return Response::response(); 62 | } 63 | 64 | public function edit(Request $request) 65 | { 66 | $permission_id = $request->get('permission_id'); 67 | 68 | $error = ''; 69 | $permission = null; 70 | 71 | if (!$permission_id) { 72 | $error = '参数有误'; 73 | } else { 74 | $permission = Permission::find($permission_id); 75 | if (!$permission) { 76 | $error = '获取权限信息错误'; 77 | } else { 78 | $permission->routes = explode(',', $permission->routes); 79 | } 80 | } 81 | 82 | $routes = RouteService::getRoutes(); 83 | 84 | return view('admin.permission.edit', ['permission' => $permission, 'error' => $error, 'routes' => $routes]); 85 | } 86 | 87 | public function update(Request $request) 88 | { 89 | $validate = new PermissionUpdateValidate($request); 90 | 91 | if (!$validate->goCheck()) { 92 | return Response::response(['code' => Response::PARAM_ERROR, 'msg' => $validate->errors->first()]); 93 | } 94 | 95 | $params = $validate->requestData; 96 | 97 | $permission = Permission::find($params['id']); 98 | 99 | $permission->name = $params['name']; 100 | $permission->routes = implode(',', $params['route']); 101 | 102 | if (!$permission->save()) { 103 | return Response::response(['code' => Response::SQL_ERROR]); 104 | } 105 | 106 | return Response::response(); 107 | } 108 | 109 | public function delete(Request $request) 110 | { 111 | $id = $request->get('id'); 112 | if (!$id) { 113 | return Response::response(['code' => Response::PARAM_ERROR]); 114 | } 115 | 116 | DB::beginTransaction(); 117 | 118 | try { 119 | Permission::where('id', $id)->delete(); 120 | RolePermission::where('roles_id', $id)->delete(); 121 | DB::commit(); 122 | 123 | return Response::response(); 124 | } catch (QueryException $e) { 125 | DB::rollBack(); 126 | Log::error('删除权限组数据库异常', [$e->getMessage()]); 127 | 128 | return Response::response(['code' => Response::SQL_ERROR, 'e' => $e]); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/TestController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Admin; 13 | 14 | use App\Http\Controllers\Controller; 15 | 16 | class TestController extends Controller 17 | { 18 | public function test1() 19 | { 20 | return view('admin.test', ['content' => '这是test1的测试']); 21 | } 22 | 23 | public function test2() 24 | { 25 | return view('admin.test', ['content' => '这是test2的测试']); 26 | } 27 | 28 | public function test3() 29 | { 30 | return view('admin.test', ['content' => '这是test3的测试']); 31 | } 32 | 33 | public function test4() 34 | { 35 | return view('admin.test', ['content' => '这是test4的测试']); 36 | } 37 | 38 | public function test5() 39 | { 40 | return view('admin.test', ['content' => '这是test5的测试']); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Auth; 13 | 14 | use App\Http\Controllers\Controller; 15 | use Illuminate\Foundation\Auth\SendsPasswordResetEmails; 16 | 17 | class ForgotPasswordController extends Controller 18 | { 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | Password Reset Controller 22 | |-------------------------------------------------------------------------- 23 | | 24 | | This controller is responsible for handling password reset emails and 25 | | includes a trait which assists in sending these notifications from 26 | | your application to your users. Feel free to explore this trait. 27 | | 28 | */ 29 | 30 | use SendsPasswordResetEmails; 31 | 32 | /** 33 | * Create a new controller instance. 34 | */ 35 | public function __construct() 36 | { 37 | $this->middleware('guest'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/LoginController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Auth; 13 | 14 | use App\Http\Controllers\Controller; 15 | use Illuminate\Foundation\Auth\AuthenticatesUsers; 16 | 17 | class LoginController extends Controller 18 | { 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | Login Controller 22 | |-------------------------------------------------------------------------- 23 | | 24 | | This controller handles authenticating users for the application and 25 | | redirecting them to your home screen. The controller uses a trait 26 | | to conveniently provide its functionality to your applications. 27 | | 28 | */ 29 | 30 | use AuthenticatesUsers; 31 | 32 | /** 33 | * Where to redirect users after login. 34 | * 35 | * @var string 36 | */ 37 | protected $redirectTo = '/home'; 38 | 39 | /** 40 | * Create a new controller instance. 41 | */ 42 | public function __construct() 43 | { 44 | $this->middleware('guest')->except('logout'); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/RegisterController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Auth; 13 | 14 | use App\User; 15 | use App\Http\Controllers\Controller; 16 | use Illuminate\Support\Facades\Validator; 17 | use Illuminate\Foundation\Auth\RegistersUsers; 18 | 19 | class RegisterController extends Controller 20 | { 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Register Controller 24 | |-------------------------------------------------------------------------- 25 | | 26 | | This controller handles the registration of new users as well as their 27 | | validation and creation. By default this controller uses a trait to 28 | | provide this functionality without requiring any additional code. 29 | | 30 | */ 31 | 32 | use RegistersUsers; 33 | 34 | /** 35 | * Where to redirect users after registration. 36 | * 37 | * @var string 38 | */ 39 | protected $redirectTo = '/home'; 40 | 41 | /** 42 | * Create a new controller instance. 43 | */ 44 | public function __construct() 45 | { 46 | $this->middleware('guest'); 47 | } 48 | 49 | /** 50 | * Get a validator for an incoming registration request. 51 | * 52 | * @return \Illuminate\Contracts\Validation\Validator 53 | */ 54 | protected function validator(array $data) 55 | { 56 | return Validator::make($data, [ 57 | 'name' => 'required|string|max:255', 58 | 'email' => 'required|string|email|max:255|unique:users', 59 | 'password' => 'required|string|min:6|confirmed', 60 | ]); 61 | } 62 | 63 | /** 64 | * Create a new user instance after a valid registration. 65 | * 66 | * @return \App\User 67 | */ 68 | protected function create(array $data) 69 | { 70 | return User::create([ 71 | 'name' => $data['name'], 72 | 'email' => $data['email'], 73 | 'password' => bcrypt($data['password']), 74 | ]); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers\Auth; 13 | 14 | use App\Http\Controllers\Controller; 15 | use Illuminate\Foundation\Auth\ResetsPasswords; 16 | 17 | class ResetPasswordController extends Controller 18 | { 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | Password Reset Controller 22 | |-------------------------------------------------------------------------- 23 | | 24 | | This controller is responsible for handling password reset requests 25 | | and uses a simple trait to include this behavior. You're free to 26 | | explore this trait and override any methods you wish to tweak. 27 | | 28 | */ 29 | 30 | use ResetsPasswords; 31 | 32 | /** 33 | * Where to redirect users after resetting their password. 34 | * 35 | * @var string 36 | */ 37 | protected $redirectTo = '/home'; 38 | 39 | /** 40 | * Create a new controller instance. 41 | */ 42 | public function __construct() 43 | { 44 | $this->middleware('guest'); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Controllers; 13 | 14 | use Illuminate\Foundation\Bus\DispatchesJobs; 15 | use Illuminate\Routing\Controller as BaseController; 16 | use Illuminate\Foundation\Validation\ValidatesRequests; 17 | use Illuminate\Foundation\Auth\Access\AuthorizesRequests; 18 | 19 | class Controller extends BaseController 20 | { 21 | use AuthorizesRequests; 22 | use DispatchesJobs; 23 | use ValidatesRequests; 24 | } 25 | -------------------------------------------------------------------------------- /app/Http/Kernel.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http; 13 | 14 | use Illuminate\Foundation\Http\Kernel as HttpKernel; 15 | 16 | class Kernel extends HttpKernel 17 | { 18 | /** 19 | * The application's global HTTP middleware stack. 20 | * 21 | * These middleware are run during every request to your application. 22 | * 23 | * @var array 24 | */ 25 | protected $middleware = [ 26 | \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, 27 | \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, 28 | \App\Http\Middleware\TrimStrings::class, 29 | \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, 30 | \App\Http\Middleware\TrustProxies::class, 31 | ]; 32 | 33 | /** 34 | * The application's route middleware groups. 35 | * 36 | * @var array 37 | */ 38 | protected $middlewareGroups = [ 39 | 'web' => [ 40 | \App\Http\Middleware\EncryptCookies::class, 41 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 42 | \Illuminate\Session\Middleware\StartSession::class, 43 | // \Illuminate\Session\Middleware\AuthenticateSession::class, 44 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 45 | \App\Http\Middleware\VerifyCsrfToken::class, 46 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 47 | ], 48 | 49 | 'api' => [ 50 | 'throttle:60,1', 51 | 'bindings', 52 | ], 53 | ]; 54 | 55 | /** 56 | * The application's route middleware. 57 | * 58 | * These middleware may be assigned to groups or used individually. 59 | * 60 | * @var array 61 | */ 62 | protected $routeMiddleware = [ 63 | 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 64 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 65 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 66 | 'can' => \Illuminate\Auth\Middleware\Authorize::class, 67 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 68 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 69 | 'login' => \App\Http\Middleware\LoginAuthenticated::class, 70 | 'menu' => \App\Http\Middleware\MenuMiddleware::class, 71 | 'auth.can' => \App\Http\Middleware\CanMiddleware::class, 72 | ]; 73 | } 74 | -------------------------------------------------------------------------------- /app/Http/Middleware/CanMiddleware.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use App\Library\Response; 15 | use Closure; 16 | 17 | class CanMiddleware 18 | { 19 | /** 20 | * Handle an incoming request. 21 | * 22 | * @param \Illuminate\Http\Request $request 23 | * @param string|null $guard 24 | * 25 | * @return mixed 26 | */ 27 | public function handle($request, Closure $next, $guard = null) 28 | { 29 | if (!can()) { 30 | if ($request->ajax()) { 31 | return response(['code' => Response::FORBIDDEN, 'msg' => '您没有被授权访问', 'data' => []]); 32 | } 33 | 34 | return redirect(route('admin.forbidden.white')); 35 | } 36 | 37 | return $next($request); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use Illuminate\Cookie\Middleware\EncryptCookies as Middleware; 15 | 16 | class EncryptCookies extends Middleware 17 | { 18 | /** 19 | * The names of the cookies that should not be encrypted. 20 | * 21 | * @var array 22 | */ 23 | protected $except = [ 24 | ]; 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Middleware/LoginAuthenticated.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use Closure; 15 | 16 | class LoginAuthenticated 17 | { 18 | /** 19 | * Handle an incoming request. 20 | * 21 | * @param \Illuminate\Http\Request $request 22 | * @param string|null $guard 23 | * 24 | * @return mixed 25 | */ 26 | public function handle($request, Closure $next, $guard = null) 27 | { 28 | $user = $request->session()->get('user'); 29 | 30 | if (!$user) { 31 | return redirect(route('admin.login.white')); 32 | } 33 | 34 | return $next($request); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Http/Middleware/MenuMiddleware.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use App\Http\Models\Menu; 15 | use App\Http\Models\MenuRoles; 16 | use App\Http\Models\Users; 17 | use App\Http\Models\UsersRoles; 18 | use Closure; 19 | use App\Http\Models\Menu as MenuModel; 20 | use Illuminate\Support\Facades\Cache; 21 | use Illuminate\Support\Facades\Route; 22 | use Illuminate\Support\Facades\View; 23 | 24 | class MenuMiddleware 25 | { 26 | /** 27 | * Handle an incoming request. 28 | * 29 | * @param \Illuminate\Http\Request $request 30 | * @param string|null $guard 31 | * 32 | * @return mixed 33 | */ 34 | public function handle($request, Closure $next, $guard = null) 35 | { 36 | $user = $request->session()->get('user'); 37 | 38 | $menu_tree = []; 39 | $menu_arr = []; 40 | $menus = MenuModel::all()->toArray(); 41 | foreach ($menus as $m) { 42 | $menu_arr[$m['id']] = $m; 43 | } 44 | 45 | if (Users::ADMIN_YES == $user['administrator']) { 46 | //超管获取所有菜单 47 | MenuModel::menuTree($menu_arr, $menu_tree); 48 | } else { 49 | $role_ids = UsersRoles::where('users_id', '=', $user['id'])->pluck('roles_id')->toArray(); 50 | $menu_ids = MenuRoles::whereIn('roles_id', $role_ids)->pluck('menu_id')->toArray(); 51 | $menus = MenuModel::whereIn('id', $menu_ids)->get()->toArray(); 52 | 53 | $menu_tmp = []; 54 | foreach ($menus as $m) { 55 | $menu_tmp[$m['id']] = $m; 56 | //同时获取父级菜单 57 | if (0 != $m['pid'] && !array_key_exists($m['pid'], $menu_tmp)) { 58 | $menu_tmp[$m['pid']] = $menu_arr[$m['pid']]; 59 | } 60 | } 61 | MenuModel::menuTree($menu_tmp, $menu_tree); 62 | } 63 | 64 | View::share('menu_tree', $menu_tree); 65 | 66 | //控制菜单选中效果 67 | $currRouteName = Route::currentRouteName(); 68 | $cache_key = 'menu_route_'.session('user')['id']; 69 | if (Menu::where('route', $currRouteName)->count() > 0) { 70 | //当前路由为菜单 71 | Cache::put($cache_key, $currRouteName, 120); 72 | } else { 73 | if (Cache::has($cache_key)) { 74 | $currRouteName = Cache::get($cache_key); 75 | } 76 | } 77 | View::share('currRouteName', $currRouteName); 78 | 79 | return $next($request); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use Closure; 15 | use Illuminate\Support\Facades\Auth; 16 | 17 | class RedirectIfAuthenticated 18 | { 19 | /** 20 | * Handle an incoming request. 21 | * 22 | * @param \Illuminate\Http\Request $request 23 | * @param string|null $guard 24 | * 25 | * @return mixed 26 | */ 27 | public function handle($request, Closure $next, $guard = null) 28 | { 29 | if (Auth::guard($guard)->check()) { 30 | return redirect('/home'); 31 | } 32 | 33 | return $next($request); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware; 15 | 16 | class TrimStrings extends Middleware 17 | { 18 | /** 19 | * The names of the attributes that should not be trimmed. 20 | * 21 | * @var array 22 | */ 23 | protected $except = [ 24 | 'password', 25 | 'password_confirmation', 26 | ]; 27 | } 28 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use Illuminate\Http\Request; 15 | use Fideloper\Proxy\TrustProxies as Middleware; 16 | 17 | class TrustProxies extends Middleware 18 | { 19 | /** 20 | * The trusted proxies for this application. 21 | * 22 | * @var array 23 | */ 24 | protected $proxies; 25 | 26 | /** 27 | * The current proxy header mappings. 28 | * 29 | * @var array 30 | */ 31 | protected $headers = Request::HEADER_X_FORWARDED_ALL; 32 | //protected $headers = [ 33 | // Request::HEADER_FORWARDED => 'FORWARDED', 34 | // Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR', 35 | // Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST', 36 | // Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT', 37 | // Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO', 38 | //]; 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Middleware; 13 | 14 | use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; 15 | 16 | class VerifyCsrfToken extends Middleware 17 | { 18 | /** 19 | * The URIs that should be excluded from CSRF verification. 20 | * 21 | * @var array 22 | */ 23 | protected $except = [ 24 | ]; 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Models/Menu.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Models; 13 | 14 | use Illuminate\Database\Eloquent\Model; 15 | 16 | class Menu extends Model 17 | { 18 | protected $table = 'menu'; 19 | 20 | protected $guarded = []; 21 | 22 | public function roles() 23 | { 24 | return $this->belongsToMany('App\Http\Models\Roles', 'menu_roles'); 25 | } 26 | 27 | public static function menuTree(&$all_meuns, &$tree) 28 | { 29 | foreach ($all_meuns as $key => $menu) { 30 | if (isset($all_meuns[$menu['pid']])) { 31 | $all_meuns[$menu['pid']]['children'][] = &$all_meuns[$key]; 32 | } else { 33 | $tree[] = &$all_meuns[$menu['id']]; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/Http/Models/MenuRoles.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Models; 13 | 14 | use Illuminate\Database\Eloquent\Model; 15 | 16 | class MenuRoles extends Model 17 | { 18 | protected $table = 'menu_roles'; 19 | 20 | protected $guarded = []; 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Models/Permission.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Models; 13 | 14 | use Illuminate\Database\Eloquent\Model; 15 | 16 | class Permission extends Model 17 | { 18 | protected $table = 'permission'; 19 | 20 | protected $guarded = []; 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Models/RolePermission.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Models; 13 | 14 | use Illuminate\Database\Eloquent\Model; 15 | 16 | class RolePermission extends Model 17 | { 18 | protected $table = 'roles_permission'; 19 | 20 | protected $guarded = []; 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Models/Roles.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Models; 13 | 14 | use Illuminate\Database\Eloquent\Model; 15 | 16 | class Roles extends Model 17 | { 18 | protected $table = 'roles'; 19 | 20 | protected $guarded = []; 21 | 22 | public function permissions() 23 | { 24 | return $this->belongsToMany('App\Http\Models\Permission', 'roles_permission'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Models/Users.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Models; 13 | 14 | use Illuminate\Database\Eloquent\Model; 15 | 16 | class Users extends Model 17 | { 18 | protected $table = 'users'; 19 | 20 | protected $guarded = []; 21 | 22 | const STATUS_ENABLE = 1; 23 | 24 | const STATUS_DISABLE = 2; 25 | 26 | const ADMIN_YES = 1; 27 | 28 | const ADMIN_NO = 2; 29 | 30 | public function roles() 31 | { 32 | return $this->belongsToMany('App\Http\Models\Roles', 'users_roles'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Http/Models/UsersRoles.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Http\Models; 13 | 14 | use Illuminate\Database\Eloquent\Model; 15 | 16 | class UsersRoles extends Model 17 | { 18 | protected $table = 'users_roles'; 19 | 20 | protected $guarded = []; 21 | } 22 | -------------------------------------------------------------------------------- /app/Library/Response.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Library; 13 | 14 | class Response 15 | { 16 | const OK = 0; 17 | 18 | const BAD_REQUEST = 1000; 19 | 20 | const PARAM_ERROR = 1001; 21 | 22 | const SQL_ERROR = 4000; 23 | 24 | const FORBIDDEN = 4003; 25 | 26 | const SERVER_ERROR = 5000; 27 | 28 | public static $errMsg = [ 29 | self::BAD_REQUEST => '请求错误', 30 | self::PARAM_ERROR => '参数错误', 31 | self::SQL_ERROR => '数据库执行错误', 32 | self::SERVER_ERROR => '服务器错误', 33 | ]; 34 | 35 | public static function response(array $params = []) 36 | { 37 | $data = $params['data'] ?? []; 38 | if (env('APP_DEBUG') && array_key_exists('e', $params) && $params['e'] instanceof \Exception) { 39 | $code = $params['e']->getCode(); 40 | $msg = $params['e']->getMessage(); 41 | } else { 42 | $code = $params['code'] ?? 0; 43 | $msg = $params['msg'] ?? (array_key_exists($code, self::$errMsg) ? self::$errMsg[$code] : '未知错误'); 44 | } 45 | 46 | return response(['code' => $code, 'msg' => $msg, 'data' => $data]); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Providers; 13 | 14 | use Illuminate\Support\ServiceProvider; 15 | 16 | class AppServiceProvider extends ServiceProvider 17 | { 18 | /** 19 | * Bootstrap any application services. 20 | */ 21 | public function boot() 22 | { 23 | } 24 | 25 | /** 26 | * Register any application services. 27 | */ 28 | public function register() 29 | { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Providers; 13 | 14 | use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; 15 | 16 | class AuthServiceProvider extends ServiceProvider 17 | { 18 | /** 19 | * The policy mappings for the application. 20 | * 21 | * @var array 22 | */ 23 | protected $policies = [ 24 | 'App\Model' => 'App\Policies\ModelPolicy', 25 | ]; 26 | 27 | /** 28 | * Register any authentication / authorization services. 29 | */ 30 | public function boot() 31 | { 32 | $this->registerPolicies(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Providers; 13 | 14 | use Illuminate\Support\ServiceProvider; 15 | use Illuminate\Support\Facades\Broadcast; 16 | 17 | class BroadcastServiceProvider extends ServiceProvider 18 | { 19 | /** 20 | * Bootstrap any application services. 21 | */ 22 | public function boot() 23 | { 24 | Broadcast::routes(); 25 | 26 | require base_path('routes/channels.php'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Providers; 13 | 14 | use Illuminate\Support\Facades\Event; 15 | use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; 16 | 17 | class EventServiceProvider extends ServiceProvider 18 | { 19 | /** 20 | * The event listener mappings for the application. 21 | * 22 | * @var array 23 | */ 24 | protected $listen = [ 25 | 'App\Events\Event' => [ 26 | 'App\Listeners\EventListener', 27 | ], 28 | ]; 29 | 30 | /** 31 | * Register any events for your application. 32 | */ 33 | public function boot() 34 | { 35 | parent::boot(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Providers; 13 | 14 | use Illuminate\Support\Facades\Route; 15 | use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; 16 | 17 | class RouteServiceProvider extends ServiceProvider 18 | { 19 | /** 20 | * This namespace is applied to your controller routes. 21 | * 22 | * In addition, it is set as the URL generator's root namespace. 23 | * 24 | * @var string 25 | */ 26 | protected $namespace = 'App\Http\Controllers'; 27 | 28 | /** 29 | * Define your route model bindings, pattern filters, etc. 30 | */ 31 | public function boot() 32 | { 33 | parent::boot(); 34 | } 35 | 36 | /** 37 | * Define the routes for the application. 38 | */ 39 | public function map() 40 | { 41 | $this->mapApiRoutes(); 42 | 43 | $this->mapWebRoutes(); 44 | } 45 | 46 | /** 47 | * Define the "web" routes for the application. 48 | * 49 | * These routes all receive session state, CSRF protection, etc. 50 | */ 51 | protected function mapWebRoutes() 52 | { 53 | Route::middleware('web') 54 | ->namespace($this->namespace) 55 | ->group(base_path('routes/web.php')); 56 | } 57 | 58 | /** 59 | * Define the "api" routes for the application. 60 | * 61 | * These routes are typically stateless. 62 | */ 63 | protected function mapApiRoutes() 64 | { 65 | Route::prefix('api') 66 | ->middleware('api') 67 | ->namespace($this->namespace) 68 | ->group(base_path('routes/api.php')); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/Service/RouteService.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Service; 13 | 14 | use App\Http\Models\Menu; 15 | 16 | class RouteService 17 | { 18 | //获取所有路由 19 | public static function getRoutes() 20 | { 21 | $routes = []; 22 | 23 | $all_routes = app()->routes->getRoutes(); 24 | foreach ($all_routes as $k => $value) { 25 | if (array_key_exists('as', $value->action) && !ends_with($value->action['as'], '.white')) { 26 | $routes[] = $value->action['as']; 27 | } 28 | } 29 | 30 | return $routes; 31 | } 32 | 33 | //获取所有路由名称以.index结尾的路由 34 | public static function getMenuRoutes() 35 | { 36 | $routes = []; 37 | 38 | //使用过的路由不能再添加 39 | $all_used_routes = Menu::whereNotNull('route')->pluck('route')->toArray(); 40 | 41 | $all_routes = app()->routes->getRoutes(); 42 | foreach ($all_routes as $k => $value) { 43 | if (array_key_exists('as', $value->action) && !ends_with($value->action['as'], '.white') && ends_with($value->action['as'], '.index') && !in_array($value->action['as'], $all_used_routes)) { 44 | $routes[] = $value->action['as']; 45 | } 46 | } 47 | 48 | return $routes; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/User.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App; 13 | 14 | use Illuminate\Notifications\Notifiable; 15 | use Illuminate\Foundation\Auth\User as Authenticatable; 16 | 17 | class User extends Authenticatable 18 | { 19 | use Notifiable; 20 | 21 | /** 22 | * The attributes that are mass assignable. 23 | * 24 | * @var array 25 | */ 26 | protected $fillable = [ 27 | 'name', 'email', 'password', 28 | ]; 29 | 30 | /** 31 | * The attributes that should be hidden for arrays. 32 | * 33 | * @var array 34 | */ 35 | protected $hidden = [ 36 | 'password', 'remember_token', 37 | ]; 38 | } 39 | -------------------------------------------------------------------------------- /app/Validate/BaseValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use Illuminate\Support\Facades\Validator; 15 | 16 | class BaseValidate 17 | { 18 | protected $rules; 19 | 20 | protected $message; 21 | 22 | // 请求数据 23 | public $requestData; 24 | 25 | protected $validator; 26 | 27 | protected $request; 28 | 29 | public $errors = null; 30 | 31 | public function __construct($request) 32 | { 33 | $this->request = $request; 34 | } 35 | 36 | public function goCheck() 37 | { 38 | $this->validator = Validator::make($this->request->all(), $this->rules, $this->message); 39 | 40 | $this->requestData = $this->validator->getData(); 41 | 42 | $this->validator->after(function () { 43 | $this->customValidate(); 44 | }); 45 | 46 | if ($this->validator->fails()) { 47 | $this->errors = $this->validator->errors(); 48 | 49 | return false; 50 | } 51 | 52 | return true; 53 | } 54 | 55 | /** 56 | * 自定义验证 57 | * 如需要,子类重写该方法. 58 | */ 59 | protected function customValidate() 60 | { 61 | // 子类重写 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/Validate/MenuStoreValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Http\Models\Menu; 15 | use App\Http\Models\MenuRoles; 16 | use App\Http\Models\Roles; 17 | use App\Service\RouteService; 18 | 19 | class MenuStoreValidate extends BaseValidate 20 | { 21 | protected $rules = []; 22 | 23 | protected $message = [ 24 | 'name.unique' => '名称已存在', 25 | 'name.required' => '请输入名称', 26 | 'name.max' => '名称最长20个字符', 27 | 'route.required' => '请输入路由', 28 | 'pid.required' => '请选择父级菜单', 29 | 'role.required' => '请选择可见角色', 30 | ]; 31 | 32 | public function __construct($request) 33 | { 34 | parent::__construct($request); 35 | $this->rules = [ 36 | 'name' => 'required|unique:menu,name|max:20', 37 | 'route' => 'nullable', 38 | 'pid' => 'required', 39 | 'role' => 'required', 40 | ]; 41 | } 42 | 43 | protected function customValidate() 44 | { 45 | $pid = $this->requestData['pid']; 46 | $route = $this->requestData['route'] ?? ''; 47 | $role = $this->requestData['role'] ?? ''; 48 | 49 | if ($pid < 0) { 50 | $this->validator->errors()->add('pid', '父级菜单参数不正确'); 51 | 52 | return false; 53 | } elseif (1 == $pid) { 54 | $this->validator->errors()->add('pid', '不能在该菜单中添加子菜单'); 55 | 56 | return false; 57 | } elseif ($pid > 1) { 58 | if (!Menu::find($pid)) { 59 | $this->validator->errors()->add('pid', '父级菜单不存在'); 60 | 61 | return false; 62 | } 63 | } 64 | 65 | if (0 != $pid) { 66 | if (!$route) { 67 | $this->validator->errors()->add('route', '请选择菜单路由'); 68 | 69 | return false; 70 | } 71 | $routes = RouteService::getMenuRoutes(); 72 | if (!in_array($route, $routes)) { 73 | $this->validator->errors()->add('route', '菜单路由不存在'); 74 | 75 | return false; 76 | } 77 | } 78 | 79 | if (!$role) { 80 | $this->validator->errors()->add('role', '请选择可见角色'); 81 | 82 | return false; 83 | } else { 84 | if (0 == $pid) { 85 | if (count($role) != Roles::whereIn('id', $role)->count()) { 86 | $this->validator->errors()->add('route', '可见角色参数不正确'); 87 | 88 | return false; 89 | } 90 | } else { 91 | if (count($role) != MenuRoles::where('menu_id', $pid)->whereIn('roles_id', $role)->count()) { 92 | $this->validator->errors()->add('route', '可见角色参数不正确'); 93 | 94 | return false; 95 | } 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/Validate/MenuUpdateValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Http\Models\Menu; 15 | use App\Http\Models\MenuRoles; 16 | use App\Http\Models\Roles; 17 | use App\Service\RouteService; 18 | 19 | class MenuUpdateValidate extends BaseValidate 20 | { 21 | protected $rules = []; 22 | 23 | protected $message = [ 24 | 'id.required' => 'ID参数不存在', 25 | 'id.numeric' => 'ID参数不正确', 26 | 'name.required' => '请输入名称', 27 | 'name.max' => '名称最长20个字符', 28 | 'route.required' => '请输入路由', 29 | 'pid.required' => '请选择父级菜单', 30 | 'role.required' => '请选择可见角色', 31 | ]; 32 | 33 | public function __construct($request) 34 | { 35 | parent::__construct($request); 36 | $this->rules = [ 37 | 'id' => 'required|numeric', 38 | 'name' => 'required|max:20', 39 | 'route' => 'nullable', 40 | 'pid' => 'required', 41 | 'role' => 'required', 42 | ]; 43 | } 44 | 45 | protected function customValidate() 46 | { 47 | $id = $this->requestData['id']; 48 | $name = $this->requestData['name']; 49 | $pid = $this->requestData['pid']; 50 | $route = $this->requestData['route'] ?? ''; 51 | $role = $this->requestData['role'] ?? ''; 52 | 53 | if ($pid < 0) { 54 | $this->validator->errors()->add('pid', '父级菜单参数不正确'); 55 | 56 | return false; 57 | } elseif (1 == $pid) { 58 | $this->validator->errors()->add('pid', '不能在该菜单中添加子菜单'); 59 | 60 | return false; 61 | } elseif ($pid > 1) { 62 | if (!Menu::find($pid)) { 63 | $this->validator->errors()->add('pid', '父级菜单不存在'); 64 | 65 | return false; 66 | } 67 | } 68 | 69 | $menu = Menu::find($id); 70 | if (!$menu) { 71 | $this->validator->errors()->add('id', '菜单信息不正确'); 72 | 73 | return false; 74 | } 75 | 76 | if (Menu::where('id', '!=', $id)->where('name', '=', $name)->count() > 0) { 77 | $this->validator->errors()->add('name', '该名称已存在'); 78 | 79 | return false; 80 | } 81 | 82 | if (0 != $pid) { 83 | if (!$route) { 84 | $this->validator->errors()->add('route', '请选择菜单路由'); 85 | 86 | return false; 87 | } 88 | $routes = RouteService::getMenuRoutes(); 89 | if ($menu->route) { 90 | array_push($routes, $menu->route); 91 | } 92 | if (!in_array($route, $routes)) { 93 | $this->validator->errors()->add('route', '菜单路由不存在'); 94 | 95 | return false; 96 | } 97 | } 98 | 99 | if (!$role) { 100 | $this->validator->errors()->add('role', '请选择可见角色'); 101 | 102 | return false; 103 | } else { 104 | if (0 == $pid) { 105 | if (count($role) != Roles::whereIn('id', $role)->count()) { 106 | $this->validator->errors()->add('route', '可见角色参数不正确'); 107 | 108 | return false; 109 | } 110 | } else { 111 | if (count($role) != MenuRoles::where('menu_id', $pid)->whereIn('roles_id', $role)->count()) { 112 | $this->validator->errors()->add('route', '可见角色参数不正确'); 113 | 114 | return false; 115 | } 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/Validate/ModifyPwdValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | class ModifyPwdValidate extends BaseValidate 15 | { 16 | protected $rules = []; 17 | 18 | protected $message = [ 19 | 'password.required' => '请输入当前密码', 20 | 'password.between' => '密码长度为6-20个字符', 21 | 'password_repeat.required' => '请输入确认密码', 22 | 'password_repeat.same' => '两次填写的密码不一致', 23 | ]; 24 | 25 | public function __construct($request) 26 | { 27 | parent::__construct($request); 28 | $this->rules = [ 29 | 'password' => 'required|between:6,20', 30 | 'password_repeat' => 'required|same:password', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Validate/PermissionStoreValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Service\RouteService; 15 | 16 | class PermissionStoreValidate extends BaseValidate 17 | { 18 | protected $rules = []; 19 | 20 | protected $message = [ 21 | 'name.unique' => '名称已存在', 22 | 'name.required' => '请输入名称', 23 | 'name.max' => '名称最长20个字符', 24 | 'route.required' => '请选择路由', 25 | ]; 26 | 27 | public function __construct($request) 28 | { 29 | parent::__construct($request); 30 | $this->rules = [ 31 | 'name' => 'required|unique:permission,name|max:20', 32 | 'route' => 'required', 33 | ]; 34 | } 35 | 36 | protected function customValidate() 37 | { 38 | $route = $this->requestData['route'] ?? ''; 39 | 40 | if (!$route) { 41 | $this->validator->errors()->add('route', '请选择路由'); 42 | 43 | return false; 44 | } 45 | 46 | $all_routes = RouteService::getRoutes(); 47 | if (count($route) != count(array_intersect($route, $all_routes))) { 48 | $this->validator->errors()->add('route', '路由参数不正确'); 49 | 50 | return false; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/Validate/PermissionUpdateValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Http\Models\Permission; 15 | use App\Service\RouteService; 16 | 17 | class PermissionUpdateValidate extends BaseValidate 18 | { 19 | protected $rules = []; 20 | 21 | protected $message = [ 22 | 'id.required' => 'ID参数不能为空', 23 | 'id.numeric' => 'ID参数不正确', 24 | 'name.required' => '请输入名称', 25 | 'name.max' => '名称最长20个字符', 26 | 'route.required' => '请选择路由', 27 | ]; 28 | 29 | public function __construct($request) 30 | { 31 | parent::__construct($request); 32 | $this->rules = [ 33 | 'id' => 'required|numeric', 34 | 'name' => 'required|max:20', 35 | 'route' => 'required', 36 | ]; 37 | } 38 | 39 | protected function customValidate() 40 | { 41 | $id = $this->requestData['id']; 42 | $name = $this->requestData['name']; 43 | 44 | if (!Permission::find($id)) { 45 | $this->validator->errors()->add('id', '权限信息不正确'); 46 | 47 | return false; 48 | } 49 | 50 | if (Permission::where('id', '!=', $id)->where('name', '=', $name)->count() > 0) { 51 | $this->validator->errors()->add('name', '该名称已存在'); 52 | 53 | return false; 54 | } 55 | 56 | $route = $this->requestData['route'] ?? ''; 57 | if (!$route) { 58 | $this->validator->errors()->add('route', '请选择路由'); 59 | 60 | return false; 61 | } 62 | 63 | $all_routes = RouteService::getRoutes(); 64 | if (count($route) != count(array_intersect($route, $all_routes))) { 65 | $this->validator->errors()->add('route', '路由参数不正确'); 66 | 67 | return false; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/Validate/RolesStoreValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Http\Models\Permission; 15 | 16 | class RolesStoreValidate extends BaseValidate 17 | { 18 | protected $rules = []; 19 | 20 | protected $message = [ 21 | 'name.unique' => '名称已存在', 22 | 'name.required' => '请输入名称', 23 | 'name.max' => '名称最长20个字符', 24 | 'permission.required' => '请选择权限组', 25 | ]; 26 | 27 | public function __construct($request) 28 | { 29 | parent::__construct($request); 30 | $this->rules = [ 31 | 'name' => 'required|unique:roles,name|max:20', 32 | 'permission' => 'required', 33 | ]; 34 | } 35 | 36 | protected function customValidate() 37 | { 38 | if (!array_key_exists('permission', $this->requestData)) { 39 | $this->validator->errors()->add('permission', '权限组参数不正确'); 40 | 41 | return false; 42 | } 43 | 44 | $permissions = $this->requestData['permission']; 45 | 46 | $all_permissions = Permission::pluck('id')->toArray(); 47 | if (count($permissions) != count(array_intersect($permissions, $all_permissions))) { 48 | $this->validator->errors()->add('permission', '权限组参数不正确'); 49 | 50 | return false; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/Validate/RolesUpdateValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Http\Models\Permission; 15 | use App\Http\Models\Roles; 16 | 17 | class RolesUpdateValidate extends BaseValidate 18 | { 19 | protected $rules = []; 20 | 21 | protected $message = [ 22 | 'id.required' => 'ID参数不能为空', 23 | 'id.numeric' => 'ID参数不正确', 24 | 'name.required' => '请输入名称', 25 | 'name.max' => '名称最长20个字符', 26 | 'permission.required' => '请选择权限组', 27 | ]; 28 | 29 | public function __construct($request) 30 | { 31 | parent::__construct($request); 32 | $this->rules = [ 33 | 'id' => 'required|numeric', 34 | 'name' => 'required|max:20', 35 | 'permission' => 'required', 36 | ]; 37 | } 38 | 39 | protected function customValidate() 40 | { 41 | $id = $this->requestData['id']; 42 | $name = $this->requestData['name']; 43 | $permissions = $this->requestData['permission']; 44 | 45 | if (!Roles::find($id)) { 46 | $this->validator->errors()->add('id', '角色信息不正确'); 47 | 48 | return false; 49 | } 50 | 51 | if (Roles::where('id', '!=', $id)->where('name', '=', $name)->count() > 0) { 52 | $this->validator->errors()->add('name', '该名称已存在'); 53 | 54 | return false; 55 | } 56 | 57 | $all_permissions = Permission::pluck('id')->toArray(); 58 | if (count($permissions) != count(array_intersect($permissions, $all_permissions))) { 59 | $this->validator->errors()->add('route', '权限组参数不正确'); 60 | 61 | return false; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/Validate/UserStoreValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Http\Models\Users; 15 | use Illuminate\Validation\Rule; 16 | 17 | class UserStoreValidate extends BaseValidate 18 | { 19 | protected $rules = []; 20 | 21 | protected $message = [ 22 | 'name.required' => '请输入姓名', 23 | 'name.max' => '姓名最多20个字符', 24 | 'email.required' => '请输入邮箱', 25 | 'email.email' => '邮箱格式不正确', 26 | 'email.unique' => '邮箱已经存在', 27 | 'password.required' => '请输入密码', 28 | 'password.between' => '密码长度为6-20个字符', 29 | 'password_repeat.required' => '请输入确认密码', 30 | 'password_repeat.same' => '两次填写的密码不一致', 31 | 'status.required' => '请选择状态', 32 | 'status.in' => '状态值不正确', 33 | 'administrator.required' => '请选择是否管理员', 34 | 'administrator.in' => '管理员参数不正确', 35 | ]; 36 | 37 | public function __construct($request) 38 | { 39 | parent::__construct($request); 40 | $this->rules = [ 41 | 'name' => 'required|max:20', 42 | 'email' => 'required|email|unique:users,email', 43 | 'password' => 'required|between:6,20', 44 | 'password_repeat' => 'required|same:password', 45 | 'status' => ['required', Rule::in([1, 2])], 46 | 'administrator' => ['required', Rule::in([1, 2])], 47 | 'roles' => 'sometimes', 48 | ]; 49 | } 50 | 51 | protected function customValidate() 52 | { 53 | $roles = $this->requestData['roles'] ?? ''; 54 | $administrator = $this->requestData['administrator']; 55 | 56 | if (Users::ADMIN_NO == $administrator && !$roles) { 57 | $this->validator->errors()->add('roles', '请选择所属角色'); 58 | 59 | return false; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/Validate/UserUpdateValidate.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace App\Validate; 13 | 14 | use App\Http\Models\Users; 15 | use Illuminate\Validation\Rule; 16 | 17 | class UserUpdateValidate extends BaseValidate 18 | { 19 | protected $rules = []; 20 | 21 | protected $message = [ 22 | 'id.required' => 'ID参数不能为空', 23 | 'id.numeric' => 'ID参数错误', 24 | 'name.required' => '请输入姓名', 25 | 'name.max' => '姓名最多20个字符', 26 | 'email.required' => '请输入邮箱', 27 | 'email.email' => '邮箱格式不正确', 28 | 'password.between' => '密码长度为6-20个字符', 29 | 'password_repeat.same' => '两次填写的密码不一致', 30 | 'status.required' => '请选择状态', 31 | 'status.in' => '状态值不正确', 32 | 'administrator.required' => '请选择是否管理员', 33 | 'administrator.in' => '管理员参数不正确', 34 | ]; 35 | 36 | public function __construct($request) 37 | { 38 | parent::__construct($request); 39 | $this->rules = [ 40 | 'id' => 'required|numeric', 41 | 'name' => 'required|max:20', 42 | 'email' => 'required|email', 43 | 'password' => 'nullable|between:6,20', 44 | 'password_repeat' => 'nullable|same:password', 45 | //'status' => ['required', Rule::in([1, 2])], 46 | 'administrator' => ['required', Rule::in([1, 2])], 47 | 'roles' => 'sometimes', 48 | ]; 49 | } 50 | 51 | protected function customValidate() 52 | { 53 | $roles = $this->requestData['roles'] ?? ''; 54 | $administrator = $this->requestData['administrator']; 55 | $id = $this->requestData['id']; 56 | $email = $this->requestData['email']; 57 | 58 | if (Users::ADMIN_NO == $administrator) { 59 | if (!$roles) { 60 | $this->validator->errors()->add('roles', '请选择所属角色'); 61 | 62 | return false; 63 | } 64 | if (Users::where('id', '!=', $id)->where('administrator', Users::ADMIN_YES)->count() <= 0) { 65 | $this->validator->errors()->add('roles', '至少有一个超级管理员'); 66 | 67 | return false; 68 | } 69 | } 70 | 71 | if (!Users::find($id)) { 72 | $this->validator->errors()->add('id', 'ID参数有误'); 73 | 74 | return false; 75 | } 76 | 77 | $user = session()->get('user'); 78 | if ($user['id'] == $id && Users::ADMIN_YES == $user['administrator'] && Users::ADMIN_NO == $administrator) { 79 | $this->validator->errors()->add('roles', '你不能修改自己的超级管理员配置'); 80 | 81 | return false; 82 | } 83 | 84 | if (Users::where('id', '!=', $id)->where('email', '=', $email)->count() > 0) { 85 | $this->validator->errors()->add('name', '邮箱已经存在'); 86 | 87 | return false; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | $app = new Illuminate\Foundation\Application( 13 | realpath(__DIR__.'/../') 14 | ); 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Bind Important Interfaces 19 | |-------------------------------------------------------------------------- 20 | | 21 | | Next, we need to bind some important interfaces into the container so 22 | | we will be able to resolve them when needed. The kernels serve the 23 | | incoming requests to this application from both the web and CLI. 24 | | 25 | */ 26 | 27 | $app->singleton( 28 | Illuminate\Contracts\Http\Kernel::class, 29 | App\Http\Kernel::class 30 | ); 31 | 32 | $app->singleton( 33 | Illuminate\Contracts\Console\Kernel::class, 34 | App\Console\Kernel::class 35 | ); 36 | 37 | $app->singleton( 38 | Illuminate\Contracts\Debug\ExceptionHandler::class, 39 | App\Exceptions\Handler::class 40 | ); 41 | 42 | /* 43 | |-------------------------------------------------------------------------- 44 | | Return The Application 45 | |-------------------------------------------------------------------------- 46 | | 47 | | This script returns the application instance. The instance is given to 48 | | the calling script so we can separate the building of the instances 49 | | from the actual running of the application and sending responses. 50 | | 51 | */ 52 | 53 | return $app; 54 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "description": "The Laravel Framework.", 4 | "keywords": [ 5 | "framework", 6 | "laravel" 7 | ], 8 | "license": "MIT", 9 | "type": "project", 10 | "require": { 11 | "php": ">=7.0.0", 12 | "fideloper/proxy": "~4.0", 13 | "laravel/framework": "^6.0", 14 | "laravel/tinker": "~1.0", 15 | "mews/captcha": "^3.0" 16 | }, 17 | "require-dev": { 18 | "filp/whoops": "~2.0", 19 | "fzaninotto/faker": "~1.4", 20 | "mockery/mockery": "~1.0", 21 | "symfony/thanks": "^1.0" 22 | }, 23 | "autoload": { 24 | "classmap": [ 25 | "database/seeds", 26 | "database/factories" 27 | ], 28 | "psr-4": { 29 | "App\\": "app/" 30 | }, 31 | "files": [ 32 | "app/Helpers.php" 33 | ] 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "Tests\\": "tests/" 38 | } 39 | }, 40 | "extra": { 41 | "laravel": { 42 | "dont-discover": [] 43 | } 44 | }, 45 | "scripts": { 46 | "post-root-package-install": [ 47 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 48 | ], 49 | "post-create-project-cmd": [ 50 | "@php artisan key:generate" 51 | ], 52 | "post-autoload-dump": [ 53 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 54 | "@php artisan package:discover" 55 | ] 56 | }, 57 | "config": { 58 | "preferred-install": "dist", 59 | "sort-packages": true, 60 | "optimize-autoloader": true 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /config/auth.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Authentication Defaults 16 | |-------------------------------------------------------------------------- 17 | | 18 | | This option controls the default authentication "guard" and password 19 | | reset options for your application. You may change these defaults 20 | | as required, but they're a perfect start for most applications. 21 | | 22 | */ 23 | 24 | 'defaults' => [ 25 | 'guard' => 'web', 26 | 'passwords' => 'users', 27 | ], 28 | 29 | /* 30 | |-------------------------------------------------------------------------- 31 | | Authentication Guards 32 | |-------------------------------------------------------------------------- 33 | | 34 | | Next, you may define every authentication guard for your application. 35 | | Of course, a great default configuration has been defined for you 36 | | here which uses session storage and the Eloquent user provider. 37 | | 38 | | All authentication drivers have a user provider. This defines how the 39 | | users are actually retrieved out of your database or other storage 40 | | mechanisms used by this application to persist your user's data. 41 | | 42 | | Supported: "session", "token" 43 | | 44 | */ 45 | 46 | 'guards' => [ 47 | 'web' => [ 48 | 'driver' => 'session', 49 | 'provider' => 'users', 50 | ], 51 | 52 | 'api' => [ 53 | 'driver' => 'token', 54 | 'provider' => 'users', 55 | ], 56 | ], 57 | 58 | /* 59 | |-------------------------------------------------------------------------- 60 | | User Providers 61 | |-------------------------------------------------------------------------- 62 | | 63 | | All authentication drivers have a user provider. This defines how the 64 | | users are actually retrieved out of your database or other storage 65 | | mechanisms used by this application to persist your user's data. 66 | | 67 | | If you have multiple user tables or models you may configure multiple 68 | | sources which represent each model / table. These sources may then 69 | | be assigned to any extra authentication guards you have defined. 70 | | 71 | | Supported: "database", "eloquent" 72 | | 73 | */ 74 | 75 | 'providers' => [ 76 | 'users' => [ 77 | 'driver' => 'eloquent', 78 | 'model' => App\User::class, 79 | ], 80 | 81 | // 'users' => [ 82 | // 'driver' => 'database', 83 | // 'table' => 'users', 84 | // ], 85 | ], 86 | 87 | /* 88 | |-------------------------------------------------------------------------- 89 | | Resetting Passwords 90 | |-------------------------------------------------------------------------- 91 | | 92 | | You may specify multiple password reset configurations if you have more 93 | | than one user table or model in the application and you want to have 94 | | separate password reset settings based on the specific user types. 95 | | 96 | | The expire time is the number of minutes that the reset token should be 97 | | considered valid. This security feature keeps tokens short-lived so 98 | | they have less time to be guessed. You may change this as needed. 99 | | 100 | */ 101 | 102 | 'passwords' => [ 103 | 'users' => [ 104 | 'provider' => 'users', 105 | 'table' => 'password_resets', 106 | 'expire' => 60, 107 | ], 108 | ], 109 | ]; 110 | -------------------------------------------------------------------------------- /config/broadcasting.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Default Broadcaster 16 | |-------------------------------------------------------------------------- 17 | | 18 | | This option controls the default broadcaster that will be used by the 19 | | framework when an event needs to be broadcast. You may set this to 20 | | any of the connections defined in the "connections" array below. 21 | | 22 | | Supported: "pusher", "redis", "log", "null" 23 | | 24 | */ 25 | 26 | 'default' => env('BROADCAST_DRIVER', 'null'), 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Broadcast Connections 31 | |-------------------------------------------------------------------------- 32 | | 33 | | Here you may define all of the broadcast connections that will be used 34 | | to broadcast events to other systems or over websockets. Samples of 35 | | each available type of connection are provided inside this array. 36 | | 37 | */ 38 | 39 | 'connections' => [ 40 | 'pusher' => [ 41 | 'driver' => 'pusher', 42 | 'key' => env('PUSHER_APP_KEY'), 43 | 'secret' => env('PUSHER_APP_SECRET'), 44 | 'app_id' => env('PUSHER_APP_ID'), 45 | 'options' => [ 46 | 'cluster' => env('PUSHER_APP_CLUSTER'), 47 | 'encrypted' => true, 48 | ], 49 | ], 50 | 51 | 'redis' => [ 52 | 'driver' => 'redis', 53 | 'connection' => 'default', 54 | ], 55 | 56 | 'log' => [ 57 | 'driver' => 'log', 58 | ], 59 | 60 | 'null' => [ 61 | 'driver' => 'null', 62 | ], 63 | ], 64 | ]; 65 | -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Illuminate\Support\Str; 13 | 14 | return [ 15 | /* 16 | |-------------------------------------------------------------------------- 17 | | Default Cache Store 18 | |-------------------------------------------------------------------------- 19 | | 20 | | This option controls the default cache connection that gets used while 21 | | using this caching library. This connection is used when another is 22 | | not explicitly specified when executing a given caching function. 23 | | 24 | | Supported: "apc", "array", "database", "file", "memcached", "redis" 25 | | 26 | */ 27 | 28 | 'default' => env('CACHE_DRIVER', 'file'), 29 | 30 | /* 31 | |-------------------------------------------------------------------------- 32 | | Cache Stores 33 | |-------------------------------------------------------------------------- 34 | | 35 | | Here you may define all of the cache "stores" for your application as 36 | | well as their drivers. You may even define multiple stores for the 37 | | same cache driver to group types of items stored in your caches. 38 | | 39 | */ 40 | 41 | 'stores' => [ 42 | 'apc' => [ 43 | 'driver' => 'apc', 44 | ], 45 | 46 | 'array' => [ 47 | 'driver' => 'array', 48 | ], 49 | 50 | 'database' => [ 51 | 'driver' => 'database', 52 | 'table' => 'cache', 53 | 'connection' => null, 54 | ], 55 | 56 | 'file' => [ 57 | 'driver' => 'file', 58 | 'path' => storage_path('framework/cache/data'), 59 | ], 60 | 61 | 'memcached' => [ 62 | 'driver' => 'memcached', 63 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), 64 | 'sasl' => [ 65 | env('MEMCACHED_USERNAME'), 66 | env('MEMCACHED_PASSWORD'), 67 | ], 68 | 'options' => [ 69 | // Memcached::OPT_CONNECT_TIMEOUT => 2000, 70 | ], 71 | 'servers' => [ 72 | [ 73 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 74 | 'port' => env('MEMCACHED_PORT', 11211), 75 | 'weight' => 100, 76 | ], 77 | ], 78 | ], 79 | 80 | 'redis' => [ 81 | 'driver' => 'redis', 82 | 'connection' => 'default', 83 | ], 84 | ], 85 | 86 | /* 87 | |-------------------------------------------------------------------------- 88 | | Cache Key Prefix 89 | |-------------------------------------------------------------------------- 90 | | 91 | | When utilizing a RAM based store such as APC or Memcached, there might 92 | | be other applications utilizing the same cache. So, we'll specify a 93 | | value to get prefixed to all our keys so we can avoid collisions. 94 | | 95 | */ 96 | 97 | 'prefix' => env( 98 | 'CACHE_PREFIX', 99 | Str::slug(env('APP_NAME', 'laravel'), '_').'_cache' 100 | ), 101 | ]; 102 | -------------------------------------------------------------------------------- /config/captcha.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | 'characters' => ['2', '3', '4', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'm', 'n', 'p', 'q', 'r', 't', 'u', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'M', 'N', 'P', 'Q', 'R', 'T', 'U', 'X', 'Y', 'Z'], 14 | 'default' => [ 15 | 'length' => 9, 16 | 'width' => 120, 17 | 'height' => 36, 18 | 'quality' => 90, 19 | 'math' => false, 20 | ], 21 | 'math' => [ 22 | 'length' => 9, 23 | 'width' => 130, 24 | 'height' => 36, 25 | 'quality' => 90, 26 | 'math' => true, 27 | ], 28 | 29 | 'flat' => [ 30 | 'length' => 6, 31 | 'width' => 160, 32 | 'height' => 46, 33 | 'quality' => 90, 34 | 'lines' => 6, 35 | 'bgImage' => false, 36 | 'bgColor' => '#ecf2f4', 37 | 'fontColors' => ['#2c3e50', '#c0392b', '#16a085', '#c0392b', '#8e44ad', '#303f9f', '#f57c00', '#795548'], 38 | 'contrast' => -5, 39 | ], 40 | 'mini' => [ 41 | 'length' => 3, 42 | 'width' => 60, 43 | 'height' => 32, 44 | ], 45 | 'inverse' => [ 46 | 'length' => 5, 47 | 'width' => 120, 48 | 'height' => 36, 49 | 'quality' => 90, 50 | 'sensitive' => true, 51 | 'angle' => 12, 52 | 'sharpen' => 10, 53 | 'blur' => 2, 54 | 'invert' => true, 55 | 'contrast' => -5, 56 | ], 57 | ]; 58 | -------------------------------------------------------------------------------- /config/filesystems.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Default Filesystem Disk 16 | |-------------------------------------------------------------------------- 17 | | 18 | | Here you may specify the default filesystem disk that should be used 19 | | by the framework. The "local" disk, as well as a variety of cloud 20 | | based disks are available to your application. Just store away! 21 | | 22 | */ 23 | 24 | 'default' => env('FILESYSTEM_DRIVER', 'local'), 25 | 26 | /* 27 | |-------------------------------------------------------------------------- 28 | | Default Cloud Filesystem Disk 29 | |-------------------------------------------------------------------------- 30 | | 31 | | Many applications store files both locally and in the cloud. For this 32 | | reason, you may specify a default "cloud" driver here. This driver 33 | | will be bound as the Cloud disk implementation in the container. 34 | | 35 | */ 36 | 37 | 'cloud' => env('FILESYSTEM_CLOUD', 's3'), 38 | 39 | /* 40 | |-------------------------------------------------------------------------- 41 | | Filesystem Disks 42 | |-------------------------------------------------------------------------- 43 | | 44 | | Here you may configure as many filesystem "disks" as you wish, and you 45 | | may even configure multiple disks of the same driver. Defaults have 46 | | been setup for each driver as an example of the required options. 47 | | 48 | | Supported Drivers: "local", "ftp", "s3", "rackspace" 49 | | 50 | */ 51 | 52 | 'disks' => [ 53 | 'local' => [ 54 | 'driver' => 'local', 55 | 'root' => storage_path('app'), 56 | ], 57 | 58 | 'public' => [ 59 | 'driver' => 'local', 60 | 'root' => storage_path('app/public'), 61 | 'url' => env('APP_URL').'/storage', 62 | 'visibility' => 'public', 63 | ], 64 | 65 | 's3' => [ 66 | 'driver' => 's3', 67 | 'key' => env('AWS_ACCESS_KEY_ID'), 68 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 69 | 'region' => env('AWS_DEFAULT_REGION'), 70 | 'bucket' => env('AWS_BUCKET'), 71 | ], 72 | ], 73 | ]; 74 | -------------------------------------------------------------------------------- /config/queue.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Default Queue Driver 16 | |-------------------------------------------------------------------------- 17 | | 18 | | Laravel's queue API supports an assortment of back-ends via a single 19 | | API, giving you convenient access to each back-end using the same 20 | | syntax for each one. Here you may set the default queue driver. 21 | | 22 | | Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null" 23 | | 24 | */ 25 | 26 | 'default' => env('QUEUE_DRIVER', 'sync'), 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Queue Connections 31 | |-------------------------------------------------------------------------- 32 | | 33 | | Here you may configure the connection information for each server that 34 | | is used by your application. A default configuration has been added 35 | | for each back-end shipped with Laravel. You are free to add more. 36 | | 37 | */ 38 | 39 | 'connections' => [ 40 | 'sync' => [ 41 | 'driver' => 'sync', 42 | ], 43 | 44 | 'database' => [ 45 | 'driver' => 'database', 46 | 'table' => 'jobs', 47 | 'queue' => 'default', 48 | 'retry_after' => 90, 49 | ], 50 | 51 | 'beanstalkd' => [ 52 | 'driver' => 'beanstalkd', 53 | 'host' => 'localhost', 54 | 'queue' => 'default', 55 | 'retry_after' => 90, 56 | ], 57 | 58 | 'sqs' => [ 59 | 'driver' => 'sqs', 60 | 'key' => env('SQS_KEY', 'your-public-key'), 61 | 'secret' => env('SQS_SECRET', 'your-secret-key'), 62 | 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 63 | 'queue' => env('SQS_QUEUE', 'your-queue-name'), 64 | 'region' => env('SQS_REGION', 'us-east-1'), 65 | ], 66 | 67 | 'redis' => [ 68 | 'driver' => 'redis', 69 | 'connection' => 'default', 70 | 'queue' => 'default', 71 | 'retry_after' => 90, 72 | ], 73 | ], 74 | 75 | /* 76 | |-------------------------------------------------------------------------- 77 | | Failed Queue Jobs 78 | |-------------------------------------------------------------------------- 79 | | 80 | | These options configure the behavior of failed queue job logging so you 81 | | can control which database and table are used to store the jobs that 82 | | have failed. You may change them to any database / table you wish. 83 | | 84 | */ 85 | 86 | 'failed' => [ 87 | 'database' => env('DB_CONNECTION', 'mysql'), 88 | 'table' => 'failed_jobs', 89 | ], 90 | ]; 91 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Third Party Services 16 | |-------------------------------------------------------------------------- 17 | | 18 | | This file is for storing the credentials for third party services such 19 | | as Stripe, Mailgun, SparkPost and others. This file provides a sane 20 | | default location for this type of information, allowing packages 21 | | to have a conventional place to find your various credentials. 22 | | 23 | */ 24 | 25 | 'mailgun' => [ 26 | 'domain' => env('MAILGUN_DOMAIN'), 27 | 'secret' => env('MAILGUN_SECRET'), 28 | ], 29 | 30 | 'ses' => [ 31 | 'key' => env('SES_KEY'), 32 | 'secret' => env('SES_SECRET'), 33 | 'region' => 'us-east-1', 34 | ], 35 | 36 | 'sparkpost' => [ 37 | 'secret' => env('SPARKPOST_SECRET'), 38 | ], 39 | 40 | 'stripe' => [ 41 | 'model' => App\User::class, 42 | 'key' => env('STRIPE_KEY'), 43 | 'secret' => env('STRIPE_SECRET'), 44 | ], 45 | ]; 46 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | View Storage Paths 16 | |-------------------------------------------------------------------------- 17 | | 18 | | Most templating systems load templates from disk. Here you may specify 19 | | an array of paths that should be checked for your views. Of course 20 | | the usual Laravel view path has already been registered for you. 21 | | 22 | */ 23 | 24 | 'paths' => [ 25 | resource_path('views'), 26 | ], 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Compiled View Path 31 | |-------------------------------------------------------------------------- 32 | | 33 | | This option determines where all the compiled Blade templates will be 34 | | stored for your application. Typically, this is within the storage 35 | | directory. However, as usual, you are free to change this value. 36 | | 37 | */ 38 | 39 | 'compiled' => realpath(storage_path('framework/views')), 40 | ]; 41 | -------------------------------------------------------------------------------- /config/web.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | //list分页条数 14 | 'page_size' => env('PAGE_SIZE', 10), 15 | ]; 16 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Faker\Generator as Faker; 13 | 14 | /* 15 | |-------------------------------------------------------------------------- 16 | | Model Factories 17 | |-------------------------------------------------------------------------- 18 | | 19 | | This directory should contain each of the model factory definitions for 20 | | your application. Factories provide a convenient way to generate new 21 | | model instances for testing / seeding your application's database. 22 | | 23 | */ 24 | 25 | $factory->define(App\User::class, function (Faker $faker) { 26 | return [ 27 | 'name' => $faker->name, 28 | 'email' => $faker->unique()->safeEmail, 29 | 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 30 | 'remember_token' => str_random(10), 31 | ]; 32 | }); 33 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Illuminate\Support\Facades\Schema; 13 | use Illuminate\Database\Schema\Blueprint; 14 | use Illuminate\Database\Migrations\Migration; 15 | 16 | class CreateUsersTable extends Migration 17 | { 18 | /** 19 | * Run the migrations. 20 | */ 21 | public function up() 22 | { 23 | Schema::create('users', function (Blueprint $table) { 24 | $table->increments('id'); 25 | $table->string('name'); 26 | $table->string('email')->unique(); 27 | $table->string('password'); 28 | $table->rememberToken(); 29 | $table->timestamps(); 30 | }); 31 | } 32 | 33 | /** 34 | * Reverse the migrations. 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('users'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Illuminate\Support\Facades\Schema; 13 | use Illuminate\Database\Schema\Blueprint; 14 | use Illuminate\Database\Migrations\Migration; 15 | 16 | class CreatePasswordResetsTable extends Migration 17 | { 18 | /** 19 | * Run the migrations. 20 | */ 21 | public function up() 22 | { 23 | Schema::create('password_resets', function (Blueprint $table) { 24 | $table->string('email')->index(); 25 | $table->string('token'); 26 | $table->timestamp('created_at')->nullable(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('password_resets'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Illuminate\Database\Seeder; 13 | 14 | class DatabaseSeeder extends Seeder 15 | { 16 | /** 17 | * Run the database seeds. 18 | */ 19 | public function run() 20 | { 21 | // $this->call(UsersTableSeeder::class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /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 --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.18.1", 14 | "bootstrap-sass": "^3.3.7", 15 | "cross-env": "^5.1", 16 | "jquery": "^3.2", 17 | "laravel-mix": "^1.0", 18 | "lodash": "^4.17.4", 19 | "vue": "^2.5.7" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/.DS_Store -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /public/css/login.css: -------------------------------------------------------------------------------- 1 | html { 2 | background-color: #f2f2f2; 3 | color: #666; 4 | } 5 | 6 | #LAY_app, body, html { 7 | height: 100% 8 | } 9 | 10 | .layui-layout-body { 11 | overflow: auto 12 | } 13 | 14 | #LAY-user-login, .layadmin-user-display-show { 15 | display: block !important 16 | } 17 | 18 | .layadmin-user-login { 19 | position: relative; 20 | left: 0; 21 | top: 0; 22 | padding: 110px 0; 23 | min-height: 100%; 24 | box-sizing: border-box 25 | } 26 | 27 | .layadmin-user-login-main { 28 | width: 375px; 29 | margin: 0 auto; 30 | box-sizing: border-box 31 | } 32 | 33 | .layadmin-user-login-box { 34 | padding: 20px 35 | } 36 | 37 | .layadmin-user-login-header { 38 | text-align: center 39 | } 40 | 41 | .layadmin-user-login-header h2 { 42 | margin-bottom: 10px; 43 | font-weight: 300; 44 | font-size: 30px; 45 | color: #000 46 | } 47 | 48 | .layadmin-user-login-header p { 49 | font-weight: 300; 50 | color: #999 51 | } 52 | 53 | .layadmin-user-login-body .layui-form-item { 54 | position: relative 55 | } 56 | 57 | .layadmin-user-login-icon { 58 | position: absolute; 59 | left: 1px; 60 | top: 1px; 61 | width: 38px; 62 | line-height: 36px; 63 | text-align: center; 64 | color: #d2d2d2 65 | } 66 | 67 | .layadmin-user-login-body .layui-form-item .layui-input { 68 | padding-left: 38px 69 | } 70 | 71 | .layadmin-user-login-codeimg { 72 | max-height: 38px; 73 | width: 100%; 74 | cursor: pointer; 75 | box-sizing: border-box 76 | } 77 | 78 | .layadmin-user-login-other { 79 | position: relative; 80 | font-size: 0; 81 | line-height: 38px; 82 | padding-top: 20px 83 | } 84 | 85 | .layadmin-user-login-other > * { 86 | display: inline-block; 87 | vertical-align: middle; 88 | margin-right: 10px; 89 | font-size: 14px 90 | } 91 | 92 | .layadmin-user-login-other .layui-icon { 93 | position: relative; 94 | top: 2px; 95 | font-size: 26px 96 | } 97 | 98 | .layadmin-user-login-other a:hover { 99 | opacity: .8 100 | } 101 | 102 | .layadmin-user-jump-change { 103 | float: right 104 | } 105 | 106 | .layadmin-user-login-footer { 107 | position: absolute; 108 | left: 0; 109 | bottom: 0; 110 | width: 100%; 111 | line-height: 30px; 112 | padding: 20px; 113 | text-align: center; 114 | box-sizing: border-box; 115 | color: rgba(0, 0, 0, .5) 116 | } 117 | 118 | .layadmin-user-login-footer span { 119 | padding: 0 5px 120 | } 121 | 122 | .layadmin-user-login-footer a { 123 | padding: 0 5px; 124 | color: rgba(0, 0, 0, .5) 125 | } 126 | 127 | .layadmin-user-login-footer a:hover { 128 | color: rgba(0, 0, 0, 1) 129 | } 130 | 131 | .layadmin-user-login-main[bgimg] { 132 | background-color: #fff; 133 | box-shadow: 0 0 5px rgba(0, 0, 0, .05) 134 | } 135 | 136 | .ladmin-user-login-theme { 137 | position: fixed; 138 | bottom: 0; 139 | left: 0; 140 | width: 100%; 141 | text-align: center 142 | } 143 | 144 | .ladmin-user-login-theme ul { 145 | display: inline-block; 146 | padding: 5px; 147 | background-color: #fff 148 | } 149 | 150 | .ladmin-user-login-theme ul li { 151 | display: inline-block; 152 | vertical-align: top; 153 | width: 64px; 154 | height: 43px; 155 | cursor: pointer; 156 | transition: all .3s; 157 | -webkit-transition: all .3s; 158 | background-color: #f2f2f2 159 | } 160 | 161 | .ladmin-user-login-theme ul li:hover { 162 | opacity: .9 163 | } 164 | 165 | .layadmin-link { 166 | color: #029789 !important; 167 | } 168 | 169 | .layadmin-link:hover { 170 | opacity:.8 171 | } 172 | 173 | ::-webkit-input-placeholder { 174 | color: #999; 175 | } 176 | :-moz-placeholder {/* Firefox 18- */ 177 | color: #999; 178 | } 179 | ::-moz-placeholder{/* Firefox 19+ */ 180 | color: #999; 181 | } 182 | :-ms-input-placeholder { 183 | color: #999; 184 | } 185 | 186 | @media screen and (max-width: 768px) { 187 | .layadmin-user-login { 188 | padding-top: 60px 189 | } 190 | 191 | .layadmin-user-login-main { 192 | width: 300px 193 | } 194 | 195 | .layadmin-user-login-box { 196 | padding: 10px 197 | } 198 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | define('LARAVEL_START', microtime(true)); 13 | 14 | /* 15 | |-------------------------------------------------------------------------- 16 | | Register The Auto Loader 17 | |-------------------------------------------------------------------------- 18 | | 19 | | Composer provides a convenient, automatically generated class loader for 20 | | our application. We just need to utilize it! We'll simply require it 21 | | into the script here so that we don't have to worry about manual 22 | | loading any of our classes later on. It feels great to relax. 23 | | 24 | */ 25 | 26 | require __DIR__.'/../vendor/autoload.php'; 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Turn On The Lights 31 | |-------------------------------------------------------------------------- 32 | | 33 | | We need to illuminate PHP development, so let us turn on the lights. 34 | | This bootstraps the framework and gets it ready for use, then it 35 | | will load up this application so that we can run it and send 36 | | the responses back to the browser and delight our users. 37 | | 38 | */ 39 | 40 | $app = require_once __DIR__.'/../bootstrap/app.php'; 41 | 42 | /* 43 | |-------------------------------------------------------------------------- 44 | | Run The Application 45 | |-------------------------------------------------------------------------- 46 | | 47 | | Once we have the application, we can handle the incoming request 48 | | through the kernel, and send the associated response back to 49 | | the client's browser allowing them to enjoy the creative 50 | | and wonderful application we have prepared for them. 51 | | 52 | */ 53 | 54 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 55 | 56 | $response = $kernel->handle( 57 | $request = Illuminate\Http\Request::capture() 58 | ); 59 | 60 | $response->send(); 61 | 62 | $kernel->terminate($request, $response); 63 | -------------------------------------------------------------------------------- /public/js/layui/css/modules/code.css: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.5 MIT License By https://www.layui.com */ 2 | html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none} -------------------------------------------------------------------------------- /public/js/layui/css/modules/layer/default/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/css/modules/layer/default/icon-ext.png -------------------------------------------------------------------------------- /public/js/layui/css/modules/layer/default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/css/modules/layer/default/icon.png -------------------------------------------------------------------------------- /public/js/layui/css/modules/layer/default/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/css/modules/layer/default/loading-0.gif -------------------------------------------------------------------------------- /public/js/layui/css/modules/layer/default/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/css/modules/layer/default/loading-1.gif -------------------------------------------------------------------------------- /public/js/layui/css/modules/layer/default/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/css/modules/layer/default/loading-2.gif -------------------------------------------------------------------------------- /public/js/layui/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/font/iconfont.eot -------------------------------------------------------------------------------- /public/js/layui/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/font/iconfont.ttf -------------------------------------------------------------------------------- /public/js/layui/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/font/iconfont.woff -------------------------------------------------------------------------------- /public/js/layui/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/font/iconfont.woff2 -------------------------------------------------------------------------------- /public/js/layui/images/face/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/0.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/1.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/10.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/11.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/12.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/13.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/14.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/15.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/16.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/17.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/18.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/19.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/2.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/20.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/21.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/22.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/23.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/24.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/25.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/26.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/27.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/28.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/29.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/3.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/30.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/31.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/32.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/33.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/34.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/35.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/36.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/37.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/38.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/39.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/4.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/40.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/41.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/42.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/43.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/44.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/45.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/46.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/47.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/48.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/49.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/5.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/50.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/51.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/52.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/53.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/53.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/54.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/54.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/55.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/55.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/56.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/56.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/57.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/57.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/58.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/59.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/59.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/6.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/60.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/60.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/61.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/61.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/62.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/62.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/63.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/64.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/65.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/65.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/66.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/66.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/67.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/67.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/68.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/68.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/69.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/69.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/7.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/70.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/70.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/71.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/71.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/8.gif -------------------------------------------------------------------------------- /public/js/layui/images/face/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/laravel_rbac_permission/9d7c54cbe31175ec3a49006a6b7a9e4f99d70975/public/js/layui/images/face/9.gif -------------------------------------------------------------------------------- /public/js/layui/lay/modules/carousel.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(clearInterval(e.timer),e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['",'"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['
"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a/g,">").replace(/'/g,"'").replace(/"/g,""")),c.html('
  1. '+o.replace(/[\r\t\n]+/g,"
  2. ")+"
"),c.find(">.layui-code-h3")[0]||c.prepend('

'+(c.attr("lay-title")||e.title||"code")+(e.about?'layui.code':"")+"

");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss"); -------------------------------------------------------------------------------- /public/js/layui/lay/modules/flow.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="加载更多",h=l('
'+d+"
");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;su)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)}); -------------------------------------------------------------------------------- /public/js/layui/lay/modules/laypage.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.5 MIT License By https://www.layui.com */ 2 | ;layui.define(function(e){"use strict";var a=document,t="getElementById",n="getElementsByTagName",i="laypage",r="layui-disabled",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if("object"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups="groups"in a?0|a.groups:5;a.layout="object"==typeof a.layout?a.layout:["prev","page","next"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits="object"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev="prev"in a?a.prev:"上一页",a.next="next"in a?a.next:"下一页";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?''+a.prev+"":""}(),page:function(){var e=[];if(a.count<1)return"";n>1&&a.first!==!1&&0!==t&&e.push(''+(a.first||1)+"");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r2&&e.push('');r<=u;r++)r===a.curr?e.push('"+r+""):e.push(''+r+"");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1…'),0!==t&&e.push(''+(a.last||a.pages)+"")),e.join("")}(),next:function(){return a.next?''+a.next+"":""}(),count:'共 '+a.count+" 条",limit:function(){var e=['"}(),refresh:['','',""].join(""),skip:function(){return['到第','','页',""].join("")}()};return['
',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join("")}(),"
"].join("")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n]("button")[0],l=e[n]("input")[0],p=e[n]("select")[0],c=function(){var e=0|l.value.replace(/\s|\D/g,"");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;oi.pages||(i.curr=e,t.render())});p&&s.on(p,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,"click",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n]("input")[0];t&&s.on(t,"keyup",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\D/.test(n)&&(this.value=n.replace(/\D/,"")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t]("layui-laypage-"+i.index);n.jump(s),i.hash&&!e&&(location.hash="!"+i.hash+"="+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent("on"+a,function(a){a.target=a.srcElement,t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)}); -------------------------------------------------------------------------------- /public/js/layui/lay/modules/laytpl.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.5 MIT License By https://www.layui.com */ 2 | ;layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)}); -------------------------------------------------------------------------------- /public/js/layui/lay/modules/rate.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(e){"use strict";var a=layui.jquery,i={config:{},index:layui.rate?layui.rate.index+1e4:0,set:function(e){var i=this;return i.config=a.extend({},i.config,e),i},on:function(e,a){return layui.onevent.call(this,n,e,a)}},l=function(){var e=this,a=e.config;return{setvalue:function(a){e.setvalue.call(e,a)},config:a}},n="rate",t="layui-rate",o="layui-icon-rate",s="layui-icon-rate-solid",u="layui-icon-rate-half",r="layui-icon-rate-solid layui-icon-rate-half",c="layui-icon-rate-solid layui-icon-rate",f="layui-icon-rate layui-icon-rate-half",v=function(e){var l=this;l.index=++i.index,l.config=a.extend({},l.config,i.config,e),l.render()};v.prototype.config={length:5,text:!1,readonly:!1,half:!1,value:0,theme:""},v.prototype.render=function(){var e=this,i=e.config,l=i.theme?'style="color: '+i.theme+';"':"";i.elem=a(i.elem),parseInt(i.value)!==i.value&&(i.half||(i.value=Math.ceil(i.value)-i.value<.5?Math.ceil(i.value):Math.floor(i.value)));for(var n='
    ",u=1;u<=i.length;u++){var r='
  • ";i.half&&parseInt(i.value)!==i.value&&u==Math.ceil(i.value)?n=n+'
  • ":n+=r}n+="
"+(i.text?''+i.value+"星":"")+"";var c=i.elem,f=c.next("."+t);f[0]&&f.remove(),e.elemTemp=a(n),i.span=e.elemTemp.next("span"),i.setText&&i.setText(i.value),c.html(e.elemTemp),c.addClass("layui-inline"),i.readonly||e.action()},v.prototype.setvalue=function(e){var a=this,i=a.config;i.value=e,a.render()},v.prototype.action=function(){var e=this,i=e.config,l=e.elemTemp,n=l.find("i").width();l.children("li").each(function(e){var t=e+1,v=a(this);v.on("click",function(e){if(i.value=t,i.half){var o=e.pageX-a(this).offset().left;o<=n/2&&(i.value=i.value-.5)}i.text&&l.next("span").text(i.value+"星"),i.choose&&i.choose(i.value),i.setText&&i.setText(i.value)}),v.on("mousemove",function(e){if(l.find("i").each(function(){a(this).addClass(o).removeClass(r)}),l.find("i:lt("+t+")").each(function(){a(this).addClass(s).removeClass(f)}),i.half){var c=e.pageX-a(this).offset().left;c<=n/2&&v.children("i").addClass(u).removeClass(s)}}),v.on("mouseleave",function(){l.find("i").each(function(){a(this).addClass(o).removeClass(r)}),l.find("i:lt("+Math.floor(i.value)+")").each(function(){a(this).addClass(s).removeClass(f)}),i.half&&parseInt(i.value)!==i.value&&l.children("li:eq("+Math.floor(i.value)+")").children("i").addClass(u).removeClass(c)})})},v.prototype.events=function(){var e=this;e.config},i.render=function(e){var a=new v(e);return l.call(a)},e(n,i)}); -------------------------------------------------------------------------------- /public/js/layui/lay/modules/util.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.5 MIT License By https://www.layui.com */ 2 | ;layui.define("jquery",function(t){"use strict";var e=layui.$,i={fixbar:function(t){var i,n,a="layui-fixbar",o="layui-fixbar-top",r=e(document),l=e("body");t=e.extend({showHeight:200},t),t.bar1=t.bar1===!0?"":t.bar1,t.bar2=t.bar2===!0?"":t.bar2,t.bgcolor=t.bgcolor?"background-color:"+t.bgcolor:"";var c=[t.bar1,t.bar2,""],g=e(['
    ',t.bar1?'
  • '+c[0]+"
  • ":"",t.bar2?'
  • '+c[1]+"
  • ":"",'
  • '+c[2]+"
  • ","
"].join("")),s=g.find("."+o),u=function(){var e=r.scrollTop();e>=t.showHeight?i||(s.show(),i=1):i&&(s.hide(),i=0)};e("."+a)[0]||("object"==typeof t.css&&g.css(t.css),l.append(g),u(),g.find("li").on("click",function(){var i=e(this),n=i.attr("lay-type");"top"===n&&e("html,body").animate({scrollTop:0},200),t.click&&t.click.call(this,n)}),r.on("scroll",function(){clearTimeout(n),n=setTimeout(function(){u()},100)}))},countdown:function(t,e,i){var n=this,a="function"==typeof e,o=new Date(t).getTime(),r=new Date(!e||a?(new Date).getTime():e).getTime(),l=o-r,c=[Math.floor(l/864e5),Math.floor(l/36e5)%24,Math.floor(l/6e4)%60,Math.floor(l/1e3)%60];a&&(i=e);var g=setTimeout(function(){n.countdown(t,r+1e3,i)},1e3);return i&&i(l>0?c:[0,0,0,0],e,g),l<=0&&clearTimeout(g),g},timeAgo:function(t,e){var i=this,n=[[],[]],a=(new Date).getTime()-new Date(t).getTime();return a>6912e5?(a=new Date(t),n[0][0]=i.digit(a.getFullYear(),4),n[0][1]=i.digit(a.getMonth()+1),n[0][2]=i.digit(a.getDate()),e||(n[1][0]=i.digit(a.getHours()),n[1][1]=i.digit(a.getMinutes()),n[1][2]=i.digit(a.getSeconds())),n[0].join("-")+" "+n[1].join(":")):a>=864e5?(a/1e3/60/60/24|0)+"天前":a>=36e5?(a/1e3/60/60|0)+"小时前":a>=12e4?(a/1e3/60|0)+"分钟前":a<0?"未来":"刚刚"},digit:function(t,e){var i="";t=String(t),e=e||2;for(var n=t.length;n/g,">").replace(/'/g,"'").replace(/"/g,""")},event:function(t,n,a){n=i.event[t]=e.extend(!0,i.event[t],n)||{},e("body").on(a||"click","*["+t+"]",function(){var i=e(this),a=i.attr(t);n[a]&&n[a].call(this,i)})}};!function(t,e,i){"$:nomunge";function n(){a=e[l](function(){o.each(function(){var e=t(this),i=e.width(),n=e.height(),a=t.data(this,g);(i!==a.w||n!==a.h)&&e.trigger(c,[a.w=i,a.h=n])}),n()},r[s])}var a,o=t([]),r=t.resize=t.extend(t.resize,{}),l="setTimeout",c="resize",g=c+"-special-event",s="delay",u="throttleWindow";r[s]=250,r[u]=!0,t.event.special[c]={setup:function(){if(!r[u]&&this[l])return!1;var e=t(this);o=o.add(e),t.data(this,g,{w:e.width(),h:e.height()}),1===o.length&&n()},teardown:function(){if(!r[u]&&this[l])return!1;var e=t(this);o=o.not(e),e.removeData(g),o.length||clearTimeout(a)},add:function(e){function n(e,n,o){var r=t(this),l=t.data(this,g)||{};l.w=n!==i?n:r.width(),l.h=o!==i?o:r.height(),a.apply(this,arguments)}if(!r[u]&&this[l])return!1;var a;return t.isFunction(e)?(a=e,n):(a=e.handler,void(e.handler=n))}}}(e,window),t("util",i)}); -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Laravel RBAC Permission Admin 2 | 3 | 基于Laravel框架,前端采用Layui组件(基于Jquery),包含通用RBAC权限的后台管理系统。 4 | 5 | Demo: http://rbac.elnmp.com/admin 6 | 7 | user name:admin@admin.com 8 | 9 | password:admin123 10 | 11 | ## 环境要求 12 | 13 | * PHP >= 7.0 14 | * Laravel 5.5.* / 5.8.* / 6.x(理论上支持5.5以上及6.x所有版本,5.5、5.8、6.0测试通过) 15 | * Laravel 7.x 支持:https://github.com/gedongdong/laravel_rbac_permission/tree/laravel-7.x 16 | * Laravel 8.x 支持:https://github.com/gedongdong/laravel_rbac_permission/tree/laravel-8.x (PHP >= 7.3) 17 | 18 | ## 基础功能 19 | 20 | * 登录/登出 21 | * 登录验证码 22 | * 用户管理 23 | * 角色管理 24 | * 权限组管理 25 | * 基于角色的菜单管理 26 | * 密码修改 27 | 28 | ## 项目初始化 29 | 30 | 1. 将项目根目录的rbac.sql文件导入数据库 31 | 2. 配置nginx/apache 32 | 3. 拉取代码,再`composer install` 33 | 4. 由于涉及到初始超管用户密码加密的问题,先使用`.env.example`中的`APP_KEY`进行登录,然后再生成新的`APP_KEY`,重置超管密码 34 | 35 | ## 效果展示 36 | 37 | ![](http://docimg.elnmp.com/login.png) 38 | ![](http://docimg.elnmp.com/role_add.png) 39 | ![](http://docimg.elnmp.com/menu_add.png) 40 | ![](http://docimg.elnmp.com/role.png) 41 | ![](http://docimg.elnmp.com/user.png) 42 | ![](http://docimg.elnmp.com/user_add.png) 43 | ![](http://docimg.elnmp.com/permission.png) 44 | ![](http://docimg.elnmp.com/permission_add.png) 45 | ![](http://docimg.elnmp.com/menu.png) 46 | ![](http://docimg.elnmp.com/newpwd.png) 47 | -------------------------------------------------------------------------------- /resources/assets/js/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * First we will load all of this project's JavaScript dependencies which 4 | * includes Vue and other libraries. It is a great starting point when 5 | * building robust, powerful web applications using Vue and Laravel. 6 | */ 7 | 8 | require('./bootstrap'); 9 | 10 | window.Vue = require('vue'); 11 | 12 | /** 13 | * Next, we will create a fresh Vue application instance and attach it to 14 | * the page. Then, you may begin adding components to this application 15 | * or customize the JavaScript scaffolding to fit your unique needs. 16 | */ 17 | 18 | Vue.component('example-component', require('./components/ExampleComponent.vue')); 19 | 20 | const app = new Vue({ 21 | el: '#app' 22 | }); 23 | -------------------------------------------------------------------------------- /resources/assets/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | 2 | window._ = require('lodash'); 3 | 4 | /** 5 | * We'll load jQuery and the Bootstrap jQuery plugin which provides support 6 | * for JavaScript based Bootstrap features such as modals and tabs. This 7 | * code may be modified to fit the specific needs of your application. 8 | */ 9 | 10 | try { 11 | window.$ = window.jQuery = require('jquery'); 12 | 13 | require('bootstrap-sass'); 14 | } catch (e) {} 15 | 16 | /** 17 | * We'll load the axios HTTP library which allows us to easily issue requests 18 | * to our Laravel back-end. This library automatically handles sending the 19 | * CSRF token as a header based on the value of the "XSRF" token cookie. 20 | */ 21 | 22 | window.axios = require('axios'); 23 | 24 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 25 | 26 | /** 27 | * Next we will register the CSRF Token as a common header with Axios so that 28 | * all outgoing HTTP requests automatically have it attached. This is just 29 | * a simple convenience so we don't have to attach every token manually. 30 | */ 31 | 32 | let token = document.head.querySelector('meta[name="csrf-token"]'); 33 | 34 | if (token) { 35 | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content; 36 | } else { 37 | console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token'); 38 | } 39 | 40 | /** 41 | * Echo exposes an expressive API for subscribing to channels and listening 42 | * for events that are broadcast by Laravel. Echo and event broadcasting 43 | * allows your team to easily build robust real-time web applications. 44 | */ 45 | 46 | // import Echo from 'laravel-echo' 47 | 48 | // window.Pusher = require('pusher-js'); 49 | 50 | // window.Echo = new Echo({ 51 | // broadcaster: 'pusher', 52 | // key: 'your-pusher-key', 53 | // cluster: 'mt1', 54 | // encrypted: true 55 | // }); 56 | -------------------------------------------------------------------------------- /resources/assets/js/components/ExampleComponent.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /resources/assets/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | // Body 3 | $body-bg: #f5f8fa; 4 | 5 | // Borders 6 | $laravel-border-color: darken($body-bg, 10%); 7 | $list-group-border: $laravel-border-color; 8 | $navbar-default-border: $laravel-border-color; 9 | $panel-default-border: $laravel-border-color; 10 | $panel-inner-border: $laravel-border-color; 11 | 12 | // Brands 13 | $brand-primary: #3097D1; 14 | $brand-info: #8eb4cb; 15 | $brand-success: #2ab27b; 16 | $brand-warning: #cbb956; 17 | $brand-danger: #bf5329; 18 | 19 | // Typography 20 | $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/"; 21 | $font-family-sans-serif: "Raleway", sans-serif; 22 | $font-size-base: 14px; 23 | $line-height-base: 1.6; 24 | $text-color: #636b6f; 25 | 26 | // Navbar 27 | $navbar-default-bg: #fff; 28 | 29 | // Buttons 30 | $btn-default-color: $text-color; 31 | 32 | // Inputs 33 | $input-border: lighten($text-color, 40%); 34 | $input-border-focus: lighten($brand-primary, 25%); 35 | $input-color-placeholder: lighten($text-color, 30%); 36 | 37 | // Panels 38 | $panel-default-heading-bg: #fff; 39 | -------------------------------------------------------------------------------- /resources/assets/sass/app.scss: -------------------------------------------------------------------------------- 1 | 2 | // Fonts 3 | @import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600"); 4 | 5 | // Variables 6 | @import "variables"; 7 | 8 | // Bootstrap 9 | @import "~bootstrap-sass/assets/stylesheets/bootstrap"; 10 | -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Authentication Language Lines 16 | |-------------------------------------------------------------------------- 17 | | 18 | | The following language lines are used during authentication for various 19 | | messages that we need to display to the user. You are free to modify 20 | | these language lines according to your application's requirements. 21 | | 22 | */ 23 | 24 | 'failed' => 'These credentials do not match our records.', 25 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 26 | ]; 27 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Pagination Language Lines 16 | |-------------------------------------------------------------------------- 17 | | 18 | | The following language lines are used by the paginator library to build 19 | | the simple pagination links. You are free to change them to anything 20 | | you want to customize your views to better match your application. 21 | | 22 | */ 23 | 24 | 'previous' => '« Previous', 25 | 'next' => 'Next »', 26 | ]; 27 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | return [ 13 | /* 14 | |-------------------------------------------------------------------------- 15 | | Password Reset Language Lines 16 | |-------------------------------------------------------------------------- 17 | | 18 | | The following language lines are the default lines which match reasons 19 | | that are given by the password broker for a password update attempt 20 | | has failed, such as for an invalid token or invalid new password. 21 | | 22 | */ 23 | 24 | 'password' => 'Passwords must be at least six characters and match the confirmation.', 25 | 'reset' => 'Your password has been reset!', 26 | 'sent' => 'We have e-mailed your password reset link!', 27 | 'token' => 'This password reset token is invalid.', 28 | 'user' => "We can't find a user with that e-mail address.", 29 | ]; 30 | -------------------------------------------------------------------------------- /resources/views/admin/403.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 |
5 |
6 | 7 |
8 |
9 | 您没有被授权访问 10 |
11 |
12 | 13 |
14 |
15 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 | 管理后台首页 5 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/modifyPwd.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 |
5 |
修改密码
6 |
7 |
8 |
9 |
10 | 11 |
12 | 14 |
15 |
16 |
17 | 18 |
19 | 21 |
22 |
6到20个字符
23 |
24 |
25 | 26 |
27 | 29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 |
37 |
38 |
39 |
40 | @endsection 41 | 42 | @section('script') 43 | 96 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/permission/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 | 返回 5 |
6 |
7 |
8 | 9 |
10 | 12 |
13 |
14 |
15 | 16 |
17 | @foreach($routes as $route) 18 | 19 | @endforeach 20 |
21 |
22 |
23 |
24 | 25 | 26 |
27 |
28 |
29 | @endsection 30 | 31 | @section('script') 32 | 69 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/permission/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 | 返回 5 |
6 |
7 |
8 | 9 |
10 | 16 | @if($permission) 17 | 18 | @endif 19 |
20 |
21 |
22 | 23 |
24 | @foreach($routes as $route) 25 | routes)) 27 | checked 28 | @endif 29 | > 30 | @endforeach 31 |
32 |
33 |
34 |
35 | 36 |
37 |
38 |
39 | @endsection 40 | 41 | @section('script') 42 | 89 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/permission/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('style') 4 | 21 | @endsection 22 | 23 | @section('content') 24 | 添加权限 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | @foreach($permissions as $permission) 44 | 45 | 46 | 47 | 52 | 53 | 60 | 61 | @endforeach 62 | 63 |
ID名称路由创建时间操作
{{ $permission->id }}{{ $permission->name }} 48 | @foreach(explode(',',$permission->routes) as $route) 49 | {{ $route }} 50 | @endforeach 51 | {{ $permission->created_at }} 54 | 编辑 56 | 59 |
64 |
{{ $permissions->links() }}
65 | @endsection 66 | 67 | @section('script') 68 | 111 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/roles/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 | 返回 5 |
6 |
7 |
8 | 9 |
10 | 12 |
13 |
14 |
15 | 16 |
17 | @foreach($permissions as $permission) 18 | 19 | @endforeach 20 |
21 |
22 |
23 |
24 | 25 | 26 |
27 |
28 |
29 | @endsection 30 | 31 | @section('script') 32 | 69 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/roles/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 | 返回 5 |
6 |
7 |
8 | 9 |
10 | 16 | @if($role) 17 | 18 | @endif 19 |
20 |
21 |
22 | 23 |
24 | @foreach($permissions as $permission) 25 | id,$permission_ids)) 28 | checked 29 | @endif 30 | > 31 | @endforeach 32 |
33 |
34 |
35 |
36 | 37 |
38 |
39 |
40 | @endsection 41 | 42 | @section('script') 43 | 90 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/roles/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('style') 4 | 21 | @endsection 22 | 23 | @section('content') 24 | 添加角色 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | @foreach($roles as $role) 44 | 45 | 46 | 47 | 52 | 53 | 60 | 61 | @endforeach 62 | 63 |
ID名称权限组创建时间操作
{{ $role->id }}{{ $role->name }} 48 | @foreach($role->permissions as $permission) 49 | {{ $permission->name }} 50 | @endforeach 51 | {{ $role->created_at }} 54 | 编辑 56 | 59 |
64 |
{{ $roles->links() }}
65 | @endsection 66 | 67 | @section('script') 68 | 111 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/test.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.admin') 2 | 3 | @section('content') 4 | {{ $content }} 5 | @endsection -------------------------------------------------------------------------------- /resources/views/layouts/admin.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ env('APP_NAME','Laravel') }}-管理后台 7 | 8 | @yield('style') 9 | 10 | 11 |
12 |
13 | 14 | 15 | 28 | 50 |
51 | 52 |
53 |
54 | 55 |
    56 | @foreach($menu_tree as $menu) 57 |
  • 62 | {{ $menu['name'] }} 63 |
    64 | @if(key_exists('children',$menu)) 65 | @foreach($menu['children'] as $child) 66 |
    {{ $child['name'] }}
    71 | @endforeach 72 | @endif 73 |
    74 |
  • 75 | @endforeach 76 |
77 |
78 |
79 | 80 |
81 | 82 |
83 | @yield('content') 84 |
85 |
86 | 87 | 91 |
92 | 93 | 94 | 101 | @yield('script') 102 | 103 | -------------------------------------------------------------------------------- /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 | {{-- 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/semantic-ui.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 36 | @endif 37 | -------------------------------------------------------------------------------- /resources/views/vendor/pagination/simple-bootstrap-4.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 |
    3 | {{-- Previous Page Link --}} 4 | @if ($paginator->onFirstPage()) 5 |
  • @lang('pagination.previous')
  • 6 | @else 7 |
  • 8 | @endif 9 | 10 | {{-- Next Page Link --}} 11 | @if ($paginator->hasMorePages()) 12 |
  • 13 | @else 14 |
  • @lang('pagination.next')
  • 15 | @endif 16 |
17 | @endif 18 | -------------------------------------------------------------------------------- /resources/views/vendor/pagination/simple-default.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 |
    3 | {{-- Previous Page Link --}} 4 | @if ($paginator->onFirstPage()) 5 |
  • @lang('pagination.previous')
  • 6 | @else 7 |
  • 8 | @endif 9 | 10 | {{-- Next Page Link --}} 11 | @if ($paginator->hasMorePages()) 12 |
  • 13 | @else 14 |
  • @lang('pagination.next')
  • 15 | @endif 16 |
17 | @endif 18 | -------------------------------------------------------------------------------- /resources/views/welcome.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Laravel 9 | 10 | 11 | 12 | 13 | 14 | 66 | 67 | 68 |
69 | @if (Route::has('login')) 70 | 78 | @endif 79 | 80 |
81 |
82 | Laravel 83 |
84 | 85 | 92 |
93 |
94 | 95 | 96 | -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Illuminate\Http\Request; 13 | 14 | /* 15 | |-------------------------------------------------------------------------- 16 | | API Routes 17 | |-------------------------------------------------------------------------- 18 | | 19 | | Here is where you can register API routes for your application. These 20 | | routes are loaded by the RouteServiceProvider within a group which 21 | | is assigned the "api" middleware group. Enjoy building your API! 22 | | 23 | */ 24 | 25 | Route::middleware('auth:api')->get('/user', function (Request $request) { 26 | return $request->user(); 27 | }); 28 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | Broadcast::channel('App.User.{id}', function ($user, $id) { 13 | return (int) $user->id === (int) $id; 14 | }); 15 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | use Illuminate\Foundation\Inspiring; 13 | 14 | /* 15 | |-------------------------------------------------------------------------- 16 | | Console Routes 17 | |-------------------------------------------------------------------------- 18 | | 19 | | This file is where you may define all of your Closure based console 20 | | commands. Each Closure is bound to a command instance allowing a 21 | | simple approach to interacting with each command's IO methods. 22 | | 23 | */ 24 | 25 | Artisan::command('inspire', function () { 26 | $this->comment(Inspiring::quote()); 27 | })->describe('Display an inspiring quote'); 28 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | //以.white结尾的别名为不需要授权的路由 13 | 14 | Route::namespace('Admin')->prefix('admin')->group(function () { 15 | Route::get('login', 'LoginController@index')->name('admin.login.white'); 16 | Route::post('login', 'LoginController@login')->name('admin.login.post.white'); 17 | Route::post('logout', 'LoginController@logout')->name('admin.logout.white'); 18 | 19 | Route::middleware(['login', 'menu'])->group(function () { 20 | Route::get('/', 'AdminController@index')->name('admin.index.white'); 21 | Route::get('modify_pwd', 'AdminController@modifyPwd')->name('admin.modify_pwd.white'); 22 | Route::post('new_pwd', 'AdminController@newPwd')->name('admin.new_pwd.white'); 23 | Route::get('forbidden', function () { 24 | return view('admin.403'); 25 | })->name('admin.forbidden.white'); 26 | 27 | Route::middleware('auth.can')->group(function () { 28 | Route::get('/user', 'UserController@index')->name('admin.user.index'); 29 | Route::get('/user/create', 'UserController@create')->name('admin.user.create'); 30 | Route::post('/user/store', 'UserController@store')->name('admin.user.store'); 31 | Route::post('/user/status', 'UserController@status')->name('admin.user.status'); 32 | Route::get('/user/edit', 'UserController@edit')->name('admin.user.edit'); 33 | Route::post('/user/update', 'UserController@update')->name('admin.user.update'); 34 | Route::post('/user/reset', 'UserController@reset')->name('admin.user.reset'); 35 | 36 | Route::get('/permission', 'PermissionController@index')->name('admin.permission.index'); 37 | Route::get('/permission/create', 'PermissionController@create')->name('admin.permission.create'); 38 | Route::post('/permission/store', 'PermissionController@store')->name('admin.permission.store'); 39 | Route::get('/permission/edit', 'PermissionController@edit')->name('admin.permission.edit'); 40 | Route::post('/permission/update', 'PermissionController@update')->name('admin.permission.update'); 41 | Route::post('/permission/delete', 'PermissionController@delete')->name('admin.permission.delete'); 42 | 43 | Route::get('/roles', 'RolesController@index')->name('admin.roles.index'); 44 | Route::get('/roles/create', 'RolesController@create')->name('admin.roles.create'); 45 | Route::post('/roles/store', 'RolesController@store')->name('admin.roles.store'); 46 | Route::get('/roles/edit', 'RolesController@edit')->name('admin.roles.edit'); 47 | Route::post('/roles/update', 'RolesController@update')->name('admin.roles.update'); 48 | Route::post('/roles/delete', 'RolesController@delete')->name('admin.roles.delete'); 49 | 50 | Route::get('/menu', 'MenuController@index')->name('admin.menu.index'); 51 | Route::get('/menu/create', 'MenuController@create')->name('admin.menu.create'); 52 | Route::post('/menu/store', 'MenuController@store')->name('admin.menu.store'); 53 | Route::get('/menu/edit', 'MenuController@edit')->name('admin.menu.edit'); 54 | Route::post('/menu/update', 'MenuController@update')->name('admin.menu.update'); 55 | Route::post('/menu/delete', 'MenuController@delete')->name('admin.menu.delete'); 56 | 57 | Route::get('/test1', 'TestController@test1')->name('admin.test1.index'); 58 | Route::get('/test2', 'TestController@test2')->name('admin.test2.index'); 59 | Route::get('/test3', 'TestController@test3')->name('admin.test3.index'); 60 | Route::get('/test4', 'TestController@test4')->name('admin.test4.index'); 61 | Route::get('/test5', 'TestController@test5')->name('admin.test5.index'); 62 | }); 63 | }); 64 | }); 65 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | $uri = urldecode( 13 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 14 | ); 15 | 16 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 17 | // built-in PHP web server. This provides a convenient way to test a Laravel 18 | // application without having installed a "real" web server software here. 19 | if ('/' !== $uri && file_exists(__DIR__.'/public'.$uri)) { 20 | return false; 21 | } 22 | 23 | require_once __DIR__.'/public/index.php'; 24 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Tests; 13 | 14 | use Illuminate\Support\Facades\Hash; 15 | use Illuminate\Contracts\Console\Kernel; 16 | 17 | trait CreatesApplication 18 | { 19 | /** 20 | * Creates the application. 21 | * 22 | * @return \Illuminate\Foundation\Application 23 | */ 24 | public function createApplication() 25 | { 26 | $app = require __DIR__.'/../bootstrap/app.php'; 27 | 28 | $app->make(Kernel::class)->bootstrap(); 29 | 30 | Hash::setRounds(4); 31 | 32 | return $app; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Tests\Feature; 13 | 14 | use Tests\TestCase; 15 | 16 | class ExampleTest extends TestCase 17 | { 18 | /** 19 | * A basic test example. 20 | */ 21 | public function testBasicTest() 22 | { 23 | $response = $this->get('/'); 24 | 25 | $response->assertStatus(200); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Tests; 13 | 14 | use Illuminate\Foundation\Testing\TestCase as BaseTestCase; 15 | 16 | abstract class TestCase extends BaseTestCase 17 | { 18 | use CreatesApplication; 19 | } 20 | -------------------------------------------------------------------------------- /tests/Unit/ExampleTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Tests\Unit; 13 | 14 | use Tests\TestCase; 15 | 16 | class ExampleTest extends TestCase 17 | { 18 | /** 19 | * A basic test example. 20 | */ 21 | public function testBasicTest() 22 | { 23 | $this->assertTrue(true); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let 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 | --------------------------------------------------------------------------------