Browse Source

微信登录

李浩杰 4 years ago
parent
commit
9bba548de3
43 changed files with 1983 additions and 70 deletions
  1. 5 4
      app/Http/Controllers/Admin/AdminUserController.php
  2. 1 1
      app/Http/Controllers/Admin/Auth/LoginController.php
  3. 2 2
      app/Http/Controllers/Admin/Base/IndexController.php
  4. 107 0
      app/Http/Controllers/Admin/RoleController.php
  5. 2 4
      app/Http/Controllers/Admin/TestController.php
  6. 154 0
      app/Http/Controllers/Admin/UserController.php
  7. 124 0
      app/Http/Controllers/Admin/UserResetController.php
  8. 19 10
      app/Http/Controllers/Api/mini/AuthController.php
  9. 5 4
      app/Http/Middleware/AuthMini.php
  10. 13 2
      app/Models/AdminUserModel.php
  11. 8 0
      app/Models/Role.php
  12. 65 0
      app/Models/User.php
  13. 10 0
      app/Models/UserReset.php
  14. 1 1
      composer.json
  15. 7 7
      config/auth.php
  16. 133 0
      config/wechat.php
  17. 40 0
      database/migrations/2020_12_03_130931_create_users_table.php
  18. 32 0
      database/migrations/2020_12_03_131536_create_roles_table.php
  19. 30 0
      database/migrations/2020_12_03_133519_alter_admin_menus_ico.php
  20. 30 0
      database/migrations/2020_12_03_135147_add_sort_to_roles.php
  21. 30 0
      database/migrations/2020_12_03_135419_add_key_to_roles.php
  22. 35 0
      database/migrations/2020_12_04_011658_create_user_resets_table.php
  23. 36 2
      mini/pages/login/index.js
  24. 3 3
      mini/pages/login/index.wxml
  25. 4 2
      mini/project.config.json
  26. 2 1
      mini/utils/http.js
  27. 4 1
      readme.md
  28. 3 3
      resources/views/admin/admin-users/create.blade.php
  29. 3 3
      resources/views/admin/admin-users/edit.blade.php
  30. 15 14
      resources/views/admin/admin-users/index.blade.php
  31. 6 6
      resources/views/admin/auth/login.blade.php
  32. 1 0
      resources/views/admin/base/index/index.blade.php
  33. 53 0
      resources/views/admin/roles/create.blade.php
  34. 54 0
      resources/views/admin/roles/edit.blade.php
  35. 219 0
      resources/views/admin/roles/index.blade.php
  36. 53 0
      resources/views/admin/user-resets/create.blade.php
  37. 54 0
      resources/views/admin/user-resets/edit.blade.php
  38. 220 0
      resources/views/admin/user-resets/index.blade.php
  39. 57 0
      resources/views/admin/users/change-password.blade.php
  40. 63 0
      resources/views/admin/users/create.blade.php
  41. 50 0
      resources/views/admin/users/edit.blade.php
  42. 229 0
      resources/views/admin/users/index.blade.php
  43. 1 0
      routes/api.php

+ 5 - 4
app/Http/Controllers/Admin/AdminUserController.php

xqd xqd xqd
@@ -42,7 +42,7 @@ class AdminUserController extends BaseController
     {
         $items = $this->model->where('id', '>', 0);
 
-        $tmp_items = collect(['mobile']);
+        $tmp_items = collect(['name']);
         foreach($tmp_items as $tmp_item) {
             if($request->has($tmp_item) && !empty($request->input($tmp_item))) {
                 $items = $items->where($tmp_item, 'like', '%' . $request->input($tmp_item) . '%');
@@ -57,9 +57,9 @@ class AdminUserController extends BaseController
         }
 
         $items = $items->paginate();
-        foreach($items as $item) {
-            $item->role_name = empty($item->adminRole) ? '' : $item->adminRole->name;
-        }
+//        foreach($items as $item) {
+//            $item->role_name = empty($item->adminRole) ? '' : $item->adminRole->name;
+//        }
         return response()->json(['code' => 0, 'message' => '', 'count' => $items->total(), 'data' => $items->items()]);
     }
 
@@ -101,6 +101,7 @@ class AdminUserController extends BaseController
         if($validator->fails()) {
             return back()->withErrors($validator)->withInput();
         }
+
         $data = $request->input('data');
         if(isset($data['password']) && !empty($data['password'])) {
             $data['password'] = bcrypt($data['password']);

+ 1 - 1
app/Http/Controllers/Admin/Auth/LoginController.php

xqd
@@ -62,7 +62,7 @@ class LoginController extends Controller
 
     public function username()
     {
-        return 'mobile';
+        return 'name';
     }
 
     public function login(\Illuminate\Http\Request $request)

+ 2 - 2
app/Http/Controllers/Admin/Base/IndexController.php

xqd
@@ -35,8 +35,8 @@ class IndexController extends Controller
         return view('admin.base.index.index',compact('menus'));
     }
     function welcome() {
-        return redirect('/admin/AdminUser/index');
-//        return view('admin.base.index.welcome');
+//        return redirect('/admin/AdminUser/index');
+        return view('admin.base.index.welcome');
     }
     
     function createAreaDate(){

+ 107 - 0
app/Http/Controllers/Admin/RoleController.php

xqd
@@ -0,0 +1,107 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Models\AdminRoleModel;
+use App\Models\Department;
+use App\Models\Road;
+use App\Models\Role;
+use Illuminate\Http\Request;
+
+class RoleController extends BaseController
+{
+    protected $model;
+
+    protected $department;
+
+    protected $model_name = '角色';
+
+    protected $pre_uri = '/admin/Role/';
+
+    protected $view_path = 'admin.roles.';
+
+    protected $redirect_index = '/admin/Role/index';
+
+    public function __construct()
+    {
+        $this->model = new Role();
+    }
+
+    public function index()
+    {
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'index', compact('model', 'model_name','pre_uri'));
+    }
+
+    public function get(Request $request)
+    {
+        $items = $this->model->where('id', '>', 0);
+
+        $tmp_items = collect(['name']);
+        foreach($tmp_items as $tmp_item) {
+            if($request->has($tmp_item) && !empty($request->input($tmp_item))) {
+                $items = $items->where($tmp_item, 'like', '%' . $request->input($tmp_item) . '%');
+            }
+        }
+
+        $select_items = collect([]);
+        foreach($select_items as $select_item) {
+            if($request->has($select_item) && !empty($request->input($select_item))) {
+                $items = $items->where($select_item, '=', $request->input($select_item));
+            }
+        }
+
+        $items = $items->paginate();
+
+        return response()->json(['code' => 0, 'message' => '', 'count' => $items->total(), 'data' => $items->items()]);
+    }
+
+    public function create()
+    {
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'create', compact('model', 'model_name','pre_uri'));
+    }
+
+    public function store(Request $request)
+    {
+        if(empty($request->input('data')) || !is_array($request->input('data'))) return back()->withErrors(['sg_error_info' => '数据错误']);
+        $validator = $this->model->getValidator($request, 'store');
+        if($validator->fails()) {
+            return back()->withErrors($validator)->withInput();
+        }
+        $data = $request->input('data');
+        $res = $this->model->create($data);
+        if(empty($res)) return back()->withErrors(['sg_error_info' => '保存失败']);
+        return redirect($this->pre_uri . 'create')->with(['sg_success_info' => '创建成功']);
+    }
+
+    public function edit(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return back()->withErrors(['sg_error_info' => '找不到要编辑的数据']);
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'edit', compact('model', 'model_name', 'pre_uri', 'item'));
+    }
+
+    public function update(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return back()->withErrors(['sg_error_info' => '找不到要编辑的数据']);
+        if(empty($request->input('data')) || !is_array($request->input('data'))) return back()->withErrors(['sg_error_info' => '数据错误']);
+        $validator = $this->model->getValidator($request, 'update');
+        if($validator->fails()) {
+            return back()->withErrors($validator)->withInput();
+        }
+        $data = $request->input('data');
+        $res = $this->model->where('id', $request->input('id'))->update($data);
+        if(!$res) return back()->withErrors(['sg_error_info' => '数据库保存失败!']);
+        return back()->with(['sg_success_info' => '编辑成功']);
+    }
+
+    public function delete(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return response()->json(['status' => 'fail', 'info' => '找不到要删除的数据']);
+        $res = $item->delete();
+        if (!$res) return response()->json(['status' => 'fail', 'info' => '删除失败']);
+        return response()->json(['status' => 'success', 'info' => '操作成功']);
+    }
+
+}

+ 2 - 4
app/Http/Controllers/Admin/TestController.php

xqd
@@ -3,16 +3,14 @@
 namespace App\Http\Controllers\Admin;
 
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 
 
 class TestController extends Controller
 {
     public function index(Request $request)
     {
-    	$option = [];
-    	foreach($option as $key => $val) {
-    		dd($key, $val);
-    	}
+    	dd(Auth::guard('mini')->attempt(['phone' => 13438082119, 'password' => 123456]));
     	return view('admin.test.index');
     }
 }

+ 154 - 0
app/Http/Controllers/Admin/UserController.php

xqd
@@ -0,0 +1,154 @@
+<?php
+namespace App\Http\Controllers\Admin;
+
+use App\Models\AdminRoleModel;
+use App\Models\AdminUserModel;
+use App\Models\Role;
+use App\Models\User;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Hash;
+
+class UserController extends BaseController
+{
+    protected $model;
+
+    protected $role;
+
+    protected $road;
+
+    protected $zone;
+
+    protected $model_name = '用户';
+
+    protected $pre_uri = '/admin/User/';
+
+    protected $view_path = 'admin.users.';
+
+    protected $redirect_index = '/admin/User/index';
+
+    public function __construct()
+    {
+        $this->model = new User();
+        $this->role = new Role();
+    }
+
+    public function index()
+    {
+        $role_options = $this->role->getOptions();
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'index', compact('model', 'model_name','pre_uri', 'role_options'));
+    }
+
+    public function get(Request $request)
+    {
+        $items = $this->model->where('id', '>', 0);
+
+        $tmp_items = collect(['name']);
+        foreach($tmp_items as $tmp_item) {
+            if($request->has($tmp_item) && !empty($request->input($tmp_item))) {
+                $items = $items->where($tmp_item, 'like', '%' . $request->input($tmp_item) . '%');
+            }
+        }
+
+        $select_items = collect([]);
+        foreach($select_items as $select_item) {
+            if($request->has($select_item) && !empty($request->input($select_item))) {
+                $items = $items->where($select_item, '=', $request->input($select_item));
+            }
+        }
+
+        $items = $items->paginate();
+        foreach($items as $item) {
+            $item->role_name = empty($item->role) ? '' : $item->role->name;
+        }
+        return response()->json(['code' => 0, 'message' => '', 'count' => $items->total(), 'data' => $items->items()]);
+    }
+
+    public function create()
+    {
+        $role_options = $this->role->getOptions();
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'create', compact('model', 'model_name','pre_uri', 'role_options'));
+    }
+
+    public function store(Request $request)
+    {
+        if(empty($request->input('data')) || !is_array($request->input('data'))) return back()->withErrors(['sg_error_info' => '数据错误']);
+        $validator = $this->model->getValidator($request, 'store');
+        if($validator->fails()) {
+            return back()->withErrors($validator)->withInput();
+        }
+        $data = $request->input('data');
+        unset($data['password_confirmation']);
+        $data['password'] = bcrypt($data['password']);
+        $res = $this->model->create($data);
+        if(empty($res)) return back()->withErrors(['sg_error_info' => '保存失败']);
+        return redirect($this->pre_uri . 'create')->with(['sg_success_info' => '创建成功']);
+    }
+
+    public function edit(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return back()->withErrors(['sg_error_info' => '找不到要编辑的数据']);
+        $role_options = $this->role->getOptions();
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'edit', compact('model', 'model_name', 'pre_uri', 'item', 'role_options'));
+    }
+
+    public function update(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return back()->withErrors(['sg_error_info' => '找不到要编辑的数据']);
+        if(empty($request->input('data')) || !is_array($request->input('data'))) return back()->withErrors(['sg_error_info' => '数据错误']);
+        $validator = $this->model->getValidator($request, 'update');
+        if($validator->fails()) {
+            return back()->withErrors($validator)->withInput();
+        }
+
+        $data = $request->input('data');
+        if(isset($data['password']) && !empty($data['password'])) {
+            $data['password'] = bcrypt($data['password']);
+        } else {
+            unset($data['password']);
+        }
+        unset($data['password_confirmation']);
+        $res = $this->model->where('id', $request->input('id'))->update($data);
+        if(!$res) return back()->withErrors(['sg_error_info' => '数据库保存失败!']);
+        return back()->with(['sg_success_info' => '编辑成功']);
+    }
+
+    public function delete(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return response()->json(['status' => 'fail', 'info' => '找不到要删除的数据']);
+        $res = $item->delete();
+        if (!$res) return response()->json(['status' => 'fail', 'info' => '删除失败']);
+        return response()->json(['status' => 'success', 'info' => '操作成功']);
+    }
+
+    public function changePassword()
+    {
+        $item = Auth::guard('mini')->user();
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'change-password', compact('model', 'model_name', 'pre_uri', 'item'));
+    }
+
+    public function updatePassword(Request $request)
+    {
+        $validator = $this->model->getValidator($request, 'change-password');
+        $user = Auth::guard('mini')->user();
+        $data = $request->input('data');
+        $validator->after(function ($validator) use($request, $data, $user) {
+            if(!isset($data['old_password'])) {
+                $validator->errors()->add('old_password', '请填写原来密码');
+            } else if(!Hash::check($data['old_password'], $user['password'])) {
+                $validator->errors()->add('old_password', '原来密码错误');
+            }
+        });
+        if($validator->fails()) {
+            return back()->withErrors($validator)->withInput();
+        }
+
+        $this->model->where('id', $user['id'])->update(['password' => $data['password']]);
+
+        return back()->with(['sg_success_info' => '操作成功']);
+    }
+}

+ 124 - 0
app/Http/Controllers/Admin/UserResetController.php

xqd
@@ -0,0 +1,124 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Models\AdminRoleModel;
+use App\Models\AdminUserModel;
+use App\Models\AdminUserReset;
+use App\Models\Department;
+use App\Models\Road;
+use App\Models\User;
+use App\Models\UserReset;
+use Illuminate\Http\Request;
+
+class UserResetController extends BaseController
+{
+    protected $model;
+
+    protected $department;
+
+    protected $model_name = '密码重置';
+
+    protected $pre_uri = '/admin/UserReset/';
+
+    protected $view_path = 'admin.user-resets.';
+
+    protected $redirect_index = '/admin/UserReset/index';
+
+    public function __construct()
+    {
+        $this->model = new UserReset();
+    }
+
+    public function index()
+    {
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'index', compact('model', 'model_name','pre_uri'));
+    }
+
+    public function get(Request $request)
+    {
+        $items = $this->model->where('id', '>', 0)->orderBy('updated_at', 'desc');
+
+        $tmp_items = collect(['name']);
+        foreach($tmp_items as $tmp_item) {
+            if($request->has($tmp_item) && !empty($request->input($tmp_item))) {
+                $items = $items->where($tmp_item, 'like', '%' . $request->input($tmp_item) . '%');
+            }
+        }
+
+        $select_items = collect([]);
+        foreach($select_items as $select_item) {
+            if($request->has($select_item) && !empty($request->input($select_item))) {
+                $items = $items->where($select_item, '=', $request->input($select_item));
+            }
+        }
+
+        $items = $items->paginate();
+
+        foreach($items as $item) {
+            $item->status = $item->status == 1 ? '<span class="layui-badge">待重置</span>' : '<span class="layui-badge layui-bg-green">已重置</span>';
+        }
+
+        return response()->json(['code' => 0, 'message' => '', 'count' => $items->total(), 'data' => $items->items()]);
+    }
+
+    public function create()
+    {
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'create', compact('model', 'model_name','pre_uri'));
+    }
+
+    public function store(Request $request)
+    {
+        if(empty($request->input('data')) || !is_array($request->input('data'))) return back()->withErrors(['sg_error_info' => '数据错误']);
+        $validator = $this->model->getValidator($request, 'store');
+        if($validator->fails()) {
+            return back()->withErrors($validator)->withInput();
+        }
+        $data = $request->input('data');
+        $res = $this->model->create($data);
+        if(empty($res)) return back()->withErrors(['sg_error_info' => '保存失败']);
+        return redirect($this->pre_uri . 'create')->with(['sg_success_info' => '创建成功']);
+    }
+
+    public function edit(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return back()->withErrors(['sg_error_info' => '找不到要编辑的数据']);
+        list($model, $model_name, $pre_uri) = array($this->model, $this->model_name, $this->pre_uri);
+        return view($this->view_path . 'edit', compact('model', 'model_name', 'pre_uri', 'item'));
+    }
+
+    public function update(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return back()->withErrors(['sg_error_info' => '找不到要编辑的数据']);
+        if(empty($request->input('data')) || !is_array($request->input('data'))) return back()->withErrors(['sg_error_info' => '数据错误']);
+        $validator = $this->model->getValidator($request, 'update');
+        if($validator->fails()) {
+            return back()->withErrors($validator)->withInput();
+        }
+        $data = $request->input('data');
+        $res = $this->model->where('id', $request->input('id'))->update($data);
+        if(!$res) return back()->withErrors(['sg_error_info' => '数据库保存失败!']);
+        return back()->with(['sg_success_info' => '编辑成功']);
+    }
+
+    public function delete(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return response()->json(['status' => 'fail', 'info' => '找不到要删除的数据']);
+        $res = $item->delete();
+        if (!$res) return response()->json(['status' => 'fail', 'info' => '删除失败']);
+        return response()->json(['status' => 'success', 'info' => '操作成功']);
+    }
+
+    public function reset(Request $request)
+    {
+        if(empty($request->input('id')) || empty($item = $this->model->find($request->input('id')))) return response()->json(['status' => 'fail', 'info' => '找不到数据']);
+        $user = User::find($item->user_id);
+        if(empty($user)) return response()->json(['status' => 'fail', 'info' => '找不到数据']);
+        $res = $user->update(['password' => bcrypt('123456')]);
+        $item->update(['status' => 2]);
+        if (!$res) return response()->json(['status' => 'fail', 'info' => '操作失败']);
+        return response()->json(['status' => 'success', 'info' => '操作成功']);
+    }
+}

+ 19 - 10
app/Http/Controllers/Api/mini/AuthController.php

xqd
@@ -2,31 +2,40 @@
 
 namespace App\Http\Controllers\Api\mini;
 
-use App\Models\AdminUserModel;
-use App\Models\AdminUserReset;
+use App\Models\User;
+use App\Models\UserReset;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Log;
 
 class AuthController extends BaseController
 {
     public function login(Request $request)
     {
-        $credentials = $request->only('mobile', 'password');
-        if(Auth::guard('admin')->attempt($credentials)) {
-            $admin_user = Auth::guard('admin')->user();
+        $credentials = $request->only('phone', 'password');
+        if(Auth::guard('mini')->attempt($credentials)) {
+            $admin_user = Auth::guard('mini')->user();
             $admin_user->updateToken();
             return $this->success(['data' => $admin_user]);
         }
         return $this->error(['msg' => '账号或密码错误']);
     }
 
+    public function loginByWechat(Request $request)
+    {
+        $app = app('wechat.mini_program');
+        if($request->input('code')) {
+            return $app->auth->session($request->input('code'));
+        }
+    }
+
     public function reset(Request $request)
     {
-        $admin_user = AdminUserModel::where('mobile', $request->input('mobile'))->first();
-        if(!$admin_user) return $this->error(['msg' => '账号不存在']);
-        AdminUserReset::create([
-            'admin_user_id' => $admin_user->id,
-            'mobile' => $request->input('mobile'),
+        $user = User::where('phone', $request->input('phone'))->first();
+        if(!$user) return $this->error(['msg' => '账号不存在']);
+        UserReset::create([
+            'user_id' => $user->id,
+            'phone' => $request->input('phone'),
             'name' => $request->input('name')
         ]);
         return $this->success();

+ 5 - 4
app/Http/Middleware/AuthMini.php

xqd xqd
@@ -3,6 +3,7 @@
 namespace App\Http\Middleware;
 
 use App\Models\AdminUserModel;
+use App\Models\User;
 use Closure;
 use Illuminate\Support\Facades\Auth;
 
@@ -17,12 +18,12 @@ class AuthMini
      */
     public function handle($request, Closure $next)
     {
-        if(in_array($request->path(), ['api/mini/login', 'api/mini/reset', 'api/mini/test'])) return $next($request);
+        if(in_array($request->path(), ['api/mini/login', 'api/mini/reset', 'api/mini/test', 'api/mini/loginByWechat'])) return $next($request);
         $token = $request->header('X-Token');
         if($token) {
-            $admin_user = AdminUserModel::where('token', $token)->first();
-            if(!empty($admin_user)) {
-                Auth::guard('admin')->login($admin_user);
+            $user = User::where('token', $token)->first();
+            if(!empty($user)) {
+                Auth::guard('mini')->login($user);
                 return $next($request);
             }
         }

+ 13 - 2
app/Models/AdminUserModel.php

xqd xqd
@@ -36,9 +36,10 @@ class AdminUserModel extends Authenticatable
     {
         if ($type == 'store') {
             $validator = Validator::make($request->input('data'), [
-                'name' => 'required'
+                'name' => 'required|unique:admin_users'
             ], [
-                'name.required' => '账号必填'
+                'name.required' => '用户名必填',
+                'name.unique' => '用户名已存在'
             ]);
         } else if ($type == 'change-password') {
             $validator = Validator::make($request->input('data'), [
@@ -56,6 +57,16 @@ class AdminUserModel extends Authenticatable
             ], [
                 'name.required' => '账号必填'
             ]);
+            $data = $request->input('data');
+            $check = $this->where([
+                ['id', '!=', $request->input('id')],
+                ['name', '=', $data['name']]
+            ])->first();
+            $validator->after(function ($validator) use($check) {
+                if ($check) {
+                    $validator->errors()->add('name', '用户名已存在');
+                }
+            });
         }
         return $validator;
     }

+ 8 - 0
app/Models/Role.php

xqd
@@ -0,0 +1,8 @@
+<?php
+
+namespace App\Models;
+
+class Role extends BaseModel
+{
+    protected $guarded = [];
+}

+ 65 - 0
app/Models/User.php

xqd
@@ -0,0 +1,65 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Foundation\Auth\User as Authenticatable;
+use Illuminate\Support\Str;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Validator;
+
+class User extends Authenticatable
+{
+    protected $guarded = [];
+
+    public function getValidator(Request $request, $type)
+    {
+        if ($type == 'store') {
+            $validator = Validator::make($request->input('data'), [
+                'name' => 'required|unique:users'
+            ], [
+                'name.required' => '用户名必填',
+                'name.unique' => '用户名已存在'
+            ]);
+        } else if ($type == 'change-password') {
+            $validator = Validator::make($request->input('data'), [
+                'old_password' => 'required',
+                'password' => 'required|min:6|confirmed'
+            ], [
+                'old_password.required' => '请填写原来密码',
+                'password.required' => '密码必填,且不能少于6位',
+                'password.min' => '密码必填,且不能少于6位',
+                'password.confirmed' => '两次填写的密码不一致'
+            ]);
+        } else {
+            $validator = Validator::make($request->input('data'), [
+                'name' => 'required'
+            ], [
+                'name.required' => '账号必填'
+            ]);
+            $data = $request->input('data');
+            $check = $this->where([
+                ['id', '!=', $request->input('id')],
+                ['name', '=', $data['name']]
+            ])->first();
+            $validator->after(function ($validator) use($check) {
+                if ($check) {
+                    $validator->errors()->add('name', '用户名已存在');
+                }
+            });
+        }
+        return $validator;
+    }
+
+    public function role()
+    {
+        return $this->belongsTo('App\Models\Role', 'role_id');
+    }
+
+    public function updateToken()
+    {
+        $token = Str::random(60);
+        $token = hash('sha256', $token);
+        $this->update(['token' => $token]);
+    }
+}

+ 10 - 0
app/Models/UserReset.php

xqd
@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+class UserReset extends Model
+{
+    protected $guarded = [];
+}

+ 1 - 1
composer.json

xqd
@@ -14,7 +14,7 @@
         "laravel/framework": "5.5.*",
         "laravel/passport": "^4.0",
         "laravel/tinker": "~1.0",
-        "overtrue/laravel-wechat": "~4.0"
+        "overtrue/laravel-wechat": "^5.1"
     },
     "require-dev": {
         "barryvdh/laravel-ide-helper": "^2.4",

+ 7 - 7
config/auth.php

xqd xqd
@@ -44,9 +44,9 @@ return [
             'driver' => 'session',
             'provider' => 'admin_users',
         ],
-        'api' => [
-            'driver' => 'passport',
-            'provider' => 'users',
+        'mini' => [
+            'driver' => 'session',
+            'provider' => 'mini',
         ],
     ],
 
@@ -78,10 +78,10 @@ return [
             'model' => App\Models\AdminUserModel::class,
         ],
 
-        // 'users' => [
-        //     'driver' => 'database',
-        //     'table' => 'users',
-        // ],
+         'mini' => [
+             'driver' => 'eloquent',
+             'model' => App\Models\User::class,
+         ],
     ],
 
     /*

+ 133 - 0
config/wechat.php

xqd
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of the overtrue/laravel-wechat.
+ *
+ * (c) overtrue <i@overtrue.me>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+return [
+    /*
+     * 默认配置,将会合并到各模块中
+     */
+    'defaults'         => [
+        /*
+         * 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
+         */
+        'response_type'     => 'array',
+
+        /*
+         * 使用 Laravel 的缓存系统
+         */
+        'use_laravel_cache' => true,
+
+        /*
+         * 日志配置
+         *
+         * level: 日志级别,可选为:
+         *                 debug/info/notice/warning/error/critical/alert/emergency
+         * file:日志文件位置(绝对路径!!!),要求可写权限
+         */
+        'log'               => [
+            'level' => env('WECHAT_LOG_LEVEL', 'debug'),
+            'file'  => env('WECHAT_LOG_FILE', storage_path('logs/wechat.log')),
+        ],
+    ],
+
+    /*
+     * 路由配置
+     */
+    'route'            => [
+        /*
+         * 开放平台第三方平台路由配置
+         */
+        // 'open_platform' => [
+        //     'uri' => 'serve',
+        //     'action' => Overtrue\LaravelWeChat\Controllers\OpenPlatformController::class,
+        //     'attributes' => [
+        //         'prefix' => 'open-platform',
+        //         'middleware' => null,
+        //     ],
+        // ],
+    ],
+
+    /*
+     * 公众号
+     */
+    'official_account' => [
+        'default' => [
+            'app_id'  => env('WECHAT_OFFICIAL_ACCOUNT_APPID', 'your-app-id'),         // AppID
+            'secret'  => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', 'your-app-secret'),    // AppSecret
+            'token'   => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', 'your-token'),           // Token
+            'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''),                 // EncodingAESKey
+
+            /*
+             * OAuth 配置
+             *
+             * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
+             * callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。)
+             * enforce_https:是否强制使用 HTTPS 跳转
+             */
+            // 'oauth'   => [
+            //     'scopes'        => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))),
+            //     'callback'      => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/examples/oauth_callback.php'),
+            //     'enforce_https' => true,
+            // ],
+        ],
+    ],
+
+    /*
+     * 开放平台第三方平台
+     */
+    // 'open_platform' => [
+    //     'default' => [
+    //         'app_id'  => env('WECHAT_OPEN_PLATFORM_APPID', ''),
+    //         'secret'  => env('WECHAT_OPEN_PLATFORM_SECRET', ''),
+    //         'token'   => env('WECHAT_OPEN_PLATFORM_TOKEN', ''),
+    //         'aes_key' => env('WECHAT_OPEN_PLATFORM_AES_KEY', ''),
+    //     ],
+    // ],
+
+    /*
+     * 小程序
+     */
+     'mini_program' => [
+         'default' => [
+             'app_id'  => env('WECHAT_MINI_PROGRAM_APPID', ''),
+             'secret'  => env('WECHAT_MINI_PROGRAM_SECRET', ''),
+             'token'   => env('WECHAT_MINI_PROGRAM_TOKEN', ''),
+             'aes_key' => env('WECHAT_MINI_PROGRAM_AES_KEY', ''),
+         ],
+     ],
+
+    /*
+     * 微信支付
+     */
+    // 'payment' => [
+    //     'default' => [
+    //         'sandbox'            => env('WECHAT_PAYMENT_SANDBOX', false),
+    //         'app_id'             => env('WECHAT_PAYMENT_APPID', ''),
+    //         'mch_id'             => env('WECHAT_PAYMENT_MCH_ID', 'your-mch-id'),
+    //         'key'                => env('WECHAT_PAYMENT_KEY', 'key-for-signature'),
+    //         'cert_path'          => env('WECHAT_PAYMENT_CERT_PATH', 'path/to/cert/apiclient_cert.pem'),    // XXX: 绝对路径!!!!
+    //         'key_path'           => env('WECHAT_PAYMENT_KEY_PATH', 'path/to/cert/apiclient_key.pem'),      // XXX: 绝对路径!!!!
+    //         'notify_url'         => 'http://example.com/payments/wechat-notify',                           // 默认支付结果通知地址
+    //     ],
+    //     // ...
+    // ],
+
+    /*
+     * 企业微信
+     */
+    // 'work' => [
+    //     'default' => [
+    //         'corp_id' => 'xxxxxxxxxxxxxxxxx',
+    //         'agent_id' => 100020,
+    //         'secret'   => env('WECHAT_WORK_AGENT_CONTACTS_SECRET', ''),
+    //          //...
+    //      ],
+    // ],
+];

+ 40 - 0
database/migrations/2020_12_03_130931_create_users_table.php

xqd
@@ -0,0 +1,40 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateUsersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('users', function (Blueprint $table) {
+            $table->increments('id');
+            $table->unsignedInteger('role_id')->nullable();
+            $table->string('phone', 50)->nullable();
+            $table->string('name', 200)->nullable();
+            $table->string('password', 200)->nullable();
+            $table->string('open_id', 200)->nullable();
+            $table->string('nickname', 200)->nullable();
+            $table->string('avatar', 200)->nullable();
+            $table->string('session_key', 200)->nullable();
+            $table->string('token', 200)->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('users');
+    }
+}

+ 32 - 0
database/migrations/2020_12_03_131536_create_roles_table.php

xqd
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateRolesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('roles', function (Blueprint $table) {
+            $table->increments('id');
+            $table->string('name', 200)->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('roles');
+    }
+}

+ 30 - 0
database/migrations/2020_12_03_133519_alter_admin_menus_ico.php

xqd
@@ -0,0 +1,30 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AlterAdminMenusIco extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('admin_menus', function (Blueprint $table) {
+            $table->string('ico', 200)->nullable()->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 30 - 0
database/migrations/2020_12_03_135147_add_sort_to_roles.php

xqd
@@ -0,0 +1,30 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddSortToRoles extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('roles', function (Blueprint $table) {
+            $table->integer('sort')->nullable()->comment('排序')->after('name');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 30 - 0
database/migrations/2020_12_03_135419_add_key_to_roles.php

xqd
@@ -0,0 +1,30 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddKeyToRoles extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('roles', function (Blueprint $table) {
+            $table->string('key', 200)->nullable()->after('sort');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 35 - 0
database/migrations/2020_12_04_011658_create_user_resets_table.php

xqd
@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateUserResetsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('user_resets', function (Blueprint $table) {
+            $table->increments('id');
+            $table->unsignedInteger('user_id')->nullable();
+            $table->string('phone', 200)->nullable();
+            $table->string('name', 200)->nullable();
+            $table->tinyInteger('status')->default(1)->comment('1待审核,2重置,3驳回');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('user_resets');
+    }
+}

+ 36 - 2
mini/pages/login/index.js

xqd xqd xqd
@@ -25,6 +25,40 @@ Page({
 
   },
 
+  getUserInfo: function(e) {
+    var that = this
+    if(e.detail.errMsg == 'getUserInfo:ok') {
+      // wx.checkSession({
+      //   success () {
+      //     that.wechatLogin(e.detail)
+      //   },
+      //   fail () {
+          // session_key 已经失效,需要重新执行登录流程
+          wx.login({
+            success (res) {
+              if(res.code) {
+                that.wechatLogin(Object.assign({}, e.detail, {code: res.code}))
+              }
+            }
+          }) //重新登录
+        // }
+      // })
+    }
+  },
+
+  wechatLogin: function(data) {
+    http({
+      url: 'loginByWechat',
+      data: data,
+      loadTitle: '登录中',
+      success: function(res) {
+        if(res.code == 0) {
+          app.loginCallback(res.data)
+        }
+      }
+    })
+  },
+
   switchType: function(e) {
     var type = e.currentTarget.dataset.type
     var title = '手机号登录'
@@ -58,7 +92,7 @@ Page({
     http({
       url: 'login',
       data: {
-        mobile: this.data.mobile,
+        phone: this.data.mobile,
         password: this.data.password
       },
       loadTitle: '登录中',
@@ -82,7 +116,7 @@ Page({
     http({
       url: 'reset',
       data: {
-        mobile: this.data.mobile,
+        phone: this.data.mobile,
         name: this.data.name
       },
       loadTitle: '提交中',

+ 3 - 3
mini/pages/login/index.wxml

xqd xqd xqd
@@ -29,7 +29,7 @@
       </block>
       <block wx:elif="{{ type == 'wechat' }}">
         <van-button type="primary" block="true" round="true" custom-class="sg-margin-top sg-shadow"
-          bindtap="forget" icon="http://app.rt/mini/wechat2.png">微信账号快捷登录</van-button>
+        bind:getuserinfo="getUserInfo" icon="http://t18.9026.com/mini/wechat2.png" open-type="getUserInfo">微信账号快捷登录</van-button>
           <van-button type="info" block="true" round="true" color="#195ED7" custom-class="sg-margin-top sg-shadow" bindtap="switchType" data-type="mobile">返回手机登录</van-button>
       </block>
       <block wx:if="{{ type == 'mobile' }}">
@@ -38,7 +38,7 @@
       <block wx:if="{{ type == 'mobile' }}">
         <van-divider contentPosition="center">其他登录方式</van-divider>
         <view class="sg-third-box">
-          <image src="http://app.rt/mini/wechat.png" class="sg-wechat-img" mode="widthFix" bindtap="switchType"
+          <image src="http://t18.9026.com/mini/wechat.png" class="sg-wechat-img" mode="widthFix" bindtap="switchType"
             data-type="wechat"></image>
         </view>
       </block>
@@ -51,5 +51,5 @@
       </block>
     </view>
   </view>
-  <image src="http://app.rt/mini/login-bg.png" mode="widthFix" class="sg-bg"></image>
+  <image src="http://t18.9026.com/mini/login-bg.png" mode="widthFix" class="sg-bg"></image>
 </view>

+ 4 - 2
mini/project.config.json

xqd
@@ -32,13 +32,15 @@
     "useIsolateContext": true,
     "useCompilerModule": true,
     "userConfirmedUseCompilerModuleSwitch": false,
+    "userConfirmedBundleSwitch": false,
     "packNpmManually": false,
     "packNpmRelationList": [],
-    "minifyWXSS": true
+    "minifyWXSS": true,
+    "bundle": false
   },
   "compileType": "miniprogram",
   "libVersion": "2.14.0",
-  "appid": "wx581b8a1a3719a44e",
+  "appid": "wx127fbc7abac491bd",
   "projectname": "mini",
   "debugOptions": {
     "hidedInDevtools": []

+ 2 - 1
mini/utils/http.js

xqd
@@ -1,4 +1,5 @@
-const baseUrl = 'http://app.rt/api/mini/';
+const isTest = true;
+const baseUrl = isTest ? 'http://app.rt/api/mini/' : 'http://t18.9026.com/api/mini/';
 
 const http = (data) => {
   var data = Object.assign({}, {

+ 4 - 1
readme.md

xqd
@@ -28,4 +28,7 @@
 小程序原型
 https://org.modao.cc/app/edfb182d437e2a9f298a275b9bc935d65a3cdd6c
 
-https://share.mubu.com/doc/1bwUiSTcCQC
+https://share.mubu.com/doc/1bwUiSTcCQC
+
+后台
+https://share.mubu.com/doc/4Bid7O5TWS

+ 3 - 3
resources/views/admin/admin-users/create.blade.php

xqd
@@ -13,9 +13,9 @@
 
                 {{ csrf_field() }}
                 <input type="hidden" name="data[is_root]" value="1">
-                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '登录账号', 'required' => true, 'value' => (old('data') ? old('data')['name'] : '')])
-                @include('share.layui-form-item', ['type' => 'select', 'name' => 'admin_role_id', 'label' => '角色', 'selected_id' => (old('data') ? old('data')['admin_role_id'] : ''), 'options' => $admin_role_options])
-                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'input', 'name' => 'mobile', 'label' => '手机号', 'required' => true, 'value' => ''])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '用户名', 'required' => true, 'value' => (old('data') ? old('data')['name'] : '')])
+                {{--@include('share.layui-form-item', ['type' => 'select', 'name' => 'admin_role_id', 'label' => '角色', 'selected_id' => (old('data') ? old('data')['admin_role_id'] : ''), 'options' => $admin_role_options])--}}
+                {{--@include('share.layui-form-item', ['type' => 'input', 'input_type' => 'input', 'name' => 'mobile', 'label' => '手机号', 'required' => true, 'value' => ''])--}}
                 @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password', 'label' => '密码', 'required' => true, 'value' => ''])
                 @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password_confirmation', 'label' => '确认密码', 'required' => true, 'value' => ''])
                 <div class="layui-form-item">

+ 3 - 3
resources/views/admin/admin-users/edit.blade.php

xqd
@@ -14,9 +14,9 @@
                 {{ csrf_field() }}
                 <input type="hidden" name="id" value="{{ $item->id }}">
                 <input type="hidden" name="is_root" value="1">
-                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '登录账号', 'required' => true, 'value' => $item->name])
-                @include('share.layui-form-item', ['type' => 'select', 'name' => 'admin_role_id', 'label' => '角色', 'selected_id' => $item->admin_role_id, 'options' => $admin_role_options])
-                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'input', 'name' => 'mobile', 'label' => '手机号', 'required' => true, 'value' => $item->mobile])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '用户名', 'required' => true, 'value' => $item->name])
+                {{--@include('share.layui-form-item', ['type' => 'select', 'name' => 'admin_role_id', 'label' => '角色', 'selected_id' => $item->admin_role_id, 'options' => $admin_role_options])--}}
+                {{--@include('share.layui-form-item', ['type' => 'input', 'input_type' => 'input', 'name' => 'mobile', 'label' => '手机号', 'required' => true, 'value' => $item->mobile])--}}
                 @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password', 'label' => '密码', 'value' => ''])
                 @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password_confirmation', 'label' => '确认密码', 'value' => ''])
                 <div class="layui-form-item">

+ 15 - 14
resources/views/admin/admin-users/index.blade.php

xqd xqd
@@ -17,19 +17,19 @@
         <div class="layui-card-body">
             <form class="layui-form" id="sg-search-form">
                 <div class="layui-form-item layui-row">
+                    {{--<div class="layui-inline">--}}
+                        {{--<div class="layui-input-inline">--}}
+                            {{--<select name="status">--}}
+                                {{--<option value="0">角色</option>--}}
+                                {{--@foreach($admin_role_options as $option)--}}
+                                    {{--<option value="{{ $option['id'] }}">{{ $option['name'] }}</option>--}}
+                                {{--@endforeach--}}
+                            {{--</select>--}}
+                        {{--</div>--}}
+                    {{--</div>--}}
                     <div class="layui-inline">
                         <div class="layui-input-inline">
-                            <select name="status">
-                                <option value="0">角色</option>
-                                @foreach($admin_role_options as $option)
-                                    <option value="{{ $option['id'] }}">{{ $option['name'] }}</option>
-                                @endforeach
-                            </select>
-                        </div>
-                    </div>
-                    <div class="layui-inline">
-                        <div class="layui-input-inline">
-                            <input type="text" name="mobile" placeholder="请输入账号" autocomplete="off" class="layui-input">
+                            <input type="text" name="name" placeholder="请输入用户名" autocomplete="off" class="layui-input" value="{{ request('name') }}">
                         </div>
                     </div>
                     <div class="layui-inline">
@@ -65,9 +65,10 @@
                     url: '{{ $pre_uri }}' + 'get',
                     cellMinWidth: 80,
                     cols: [[
-                        { field: 'name', title: '账号', align: 'center' },
-                        { field: 'mobile', title: '手机号', align: 'center' },
-                        { field: 'role_name', title: '角色', align: 'center' },
+                        { field: 'name', title: '用户名', align: 'center' },
+                        // { field: 'mobile', title: '手机号', align: 'center' },
+                        { field: 'created_at', title: '创建时间', align: 'center' },
+                        { field: 'updated_at', title: '更新时间', align: 'center' },
                         { title: '操作', align:'center', toolbar: '#sg-table-bar' }
                     ]],
                     page: {

+ 6 - 6
resources/views/admin/auth/login.blade.php

xqd xqd xqd
@@ -54,9 +54,9 @@
             </div>
             <form class="m-t" role="form" accept-charset="UTF-8" method="post" v-show="type == 'login'" autocomplete="off">
                 {{ csrf_field() }}
-                <div :class="{ 'sg-selected': mobileFocus, 'form-group sg-form-group': true }">
+                <div :class="{ 'sg-selected': nameFocus, 'form-group sg-form-group': true }">
                     <i class="glyphicon glyphicon-user"></i>
-                    <input name="name" class="form-control" placeholder="手机号" required="" autocomplete="off" @focus="inputChange('mobile', true)" @blur="inputChange('mobile', false)" value="{{ session('sg-mobile') }}">
+                    <input name="name" class="form-control" placeholder="用户名" required="" autocomplete="off" @focus="inputChange('name', true)" @blur="inputChange('name', false)" value="{{ session('sg-name') }}">
                 </div>
                 <div :class="{ 'sg-selected': passwordFocus, 'form-group sg-form-group': true }">
                     <i class="glyphicon glyphicon-lock"></i>
@@ -145,7 +145,7 @@
             data: {
                 // login, forget
                 type: 'login',
-                mobileFocus: false,
+                nameFocus: false,
                 passwordFocus: false,
                 checked: false
             },
@@ -157,11 +157,11 @@
                     this.checked = !this.checked;
                 },
                 inputChange(name, flag) {
-                    if(name === 'mobile') {
-                        this.mobileFocus = flag;
+                    if(name === 'name') {
+                        this.nameFocus = flag;
                         this.passwordFocus = !flag;
                     } else {
-                        this.mobileFocus = !flag;
+                        this.nameFocus = !flag;
                         this.passwordFocus = flag;
                     }
                 }

+ 1 - 0
resources/views/admin/base/index/index.blade.php

xqd
@@ -18,6 +18,7 @@
     <link href="/base/css/font-awesome.min.css?v=4.3.0" rel="stylesheet">
     <link href="/base/css/animate.min.css" rel="stylesheet">
     <link href="/base/css/style.min.css?v={{config("sys.version")}}" rel="stylesheet">
+    <link rel="stylesheet" href="https://at.alicdn.com/t/font_2246785_0hvgjr28pf47.css">
     <style type="text/css">
         #side-menu .nav-header {
             color: rgba(244, 240, 240, 100);

+ 53 - 0
resources/views/admin/roles/create.blade.php

xqd
@@ -0,0 +1,53 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-container sg-create-container">
+        <div class="layui-col-sm8 layui-col-sm-offset2">
+            <form class="layui-form" method="POST" action="{{ $pre_uri . 'store' }}">
+
+                {{ csrf_field() }}
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '名称', 'required' => true, 'value' => (old('data') ? old('data')['name'] : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'key', 'label' => '键值', 'required' => true, 'value' => (old('data') ? old('data')['key'] : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'sort', 'label' => '排序', 'required' => true, 'value' => (old('data') ? old('data')['sort'] : '')])
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
+                        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                </div>
+            </form>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['form', 'laydate'], function(){
+                var form = layui.form;
+                var laydate = layui.laydate;
+
+                // form.verify({
+                //     integer: function (value) {
+                //         var pattern = /^[1-9]\d*$/;
+                //         if(!(pattern.test(value) || value === '0')) {
+                //             return '组员人数必须为大于等于0的整数';
+                //         }
+                //     }
+                // });
+
+                laydate.render({
+                    elem: '.sg-select-date'
+                });
+            });
+        })
+    </script>
+@endsection

+ 54 - 0
resources/views/admin/roles/edit.blade.php

xqd
@@ -0,0 +1,54 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-container sg-create-container">
+        <div class="layui-col-sm8 layui-col-sm-offset2">
+            <form class="layui-form" method="POST" action="{{ $pre_uri . 'update' }}">
+
+                {{ csrf_field() }}
+                <input type="hidden" name="id" value="{{ $item->id }}">
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '名称', 'required' => true, 'value' => ($item->name ? $item->name : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'key', 'label' => '键值', 'required' => true, 'value' => ($item->key ? $item->key : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'sort', 'label' => '排序', 'required' => true, 'value' => ($item->sort ? $item->sort : '')])
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
+                        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                </div>
+            </form>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['form', 'laydate'], function(){
+                var form = layui.form;
+                var laydate = layui.laydate;
+
+                // form.verify({
+                //     integer: function (value) {
+                //         var pattern = /^[1-9]\d*$/;
+                //         if(!(pattern.test(value) || value === '0')) {
+                //             return '组员人数必须为大于等于0的整数';
+                //         }
+                //     }
+                // });
+
+                laydate.render({
+                    elem: '.sg-select-date'
+                });
+            });
+        })
+    </script>
+@endsection

+ 219 - 0
resources/views/admin/roles/index.blade.php

xqd
@@ -0,0 +1,219 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-card">
+        <div class="layui-card-header sg-card-header">
+            {{ $model_name }}管理
+            <div class="sg-card-create">
+                <button id="sg-create-btn" class="layui-btn layui-btn-sm">创建</button>
+            </div>
+        </div>
+        <div class="layui-card-body">
+            <form class="layui-form" id="sg-search-form">
+                <div class="layui-form-item layui-row">
+                    <div class="layui-inline">
+                        <div class="layui-input-inline">
+                            <input type="text" name="name" placeholder="请输入名称" autocomplete="off" class="layui-input" value="{{ request('name') }}">
+                        </div>
+                    </div>
+                    <div class="layui-inline">
+                        <div class="layui-btn" id="sg-search-btn">搜索</div>
+                    </div>
+                </div>
+            </form>
+            <table id="sg-main-table" class="layui-hide" lay-filter="tableEvent"></table>
+            <script type="text/html" id="sg-table-bar">
+                <div class="layui-btn-group">
+                    <div class="layui-btn-group">
+                        <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
+                        <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</a>
+                    </div>
+                </div>
+            </script>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['table', 'layer'], function(){
+                var table = layui.table,
+                    layer = layui.layer,
+                    form = layui.form,
+                    laydate = layui.laydate,
+                    top_window = window;
+
+                table.render({
+                    elem: '#sg-main-table',
+                    url: '{{ $pre_uri }}' + 'get',
+                    cellMinWidth: 80,
+                    cols: [[
+                        { field: 'id', title: 'ID', align: 'center' },
+                        { field: 'name', title: '名称', align: 'center' },
+                        { field: 'key', title: '键值', align: 'center' },
+                        { field: 'sort', title: '排序', align: 'center' },
+                        { title: '操作', align:'center', toolbar: '#sg-table-bar' }
+                    ]],
+                    page: {
+                        layout: ['count', 'prev', 'page', 'next', 'skip', 'refresh'],
+                        limit: 15
+                    },
+                    even: true,
+                    where: transformToJson($('#sg-search-form').serializeArray()),
+                    done: function(res, curr, count) {
+
+                    }
+                });
+                table.on('tool(tableEvent)', function(obj){
+                    var data = obj.data;
+                    if(obj.event === 'delete'){
+                        layer.confirm('确定要删除吗?', function(index) {
+                            $.ajax({
+                                method: 'POST',
+                                url: '{{ $pre_uri }}' + 'delete',
+                                headers: {
+                                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                                },
+                                data: {
+                                    id: data.id
+                                },
+                                success: function (data) {
+                                    if(data.status === 'success') {
+                                        obj.del();
+                                    } else {
+                                        layer.msg(data.info, {
+                                            icon: 2
+                                        });
+                                    }
+                                    layer.close(index);
+                                },
+                                error: function () {
+                                    layer.close(index);
+                                    layer.msg('删除失败', {
+                                        icon: 2
+                                    });
+                                }
+                            });
+                        });
+                    } else if(obj.event === 'edit') {
+                        layer.open({
+                            title: '编辑成员',
+                            type: 2,
+                            area: ['90%', '90%'],
+                            content: '{{ $pre_uri }}' + 'edit?id=' + data.id,
+                            end: function () {
+                                top_window.location.reload();
+                            }
+                        });
+                    }
+                });
+
+                if($('#search-begin-date').length > 0) {
+                    laydate.render({
+                        elem: '#search-begin-date',
+                        done: function () {
+                            updateTableBySearch();
+                        }
+                    });
+                }
+
+                if($('#search-end-date').length > 0) {
+                    laydate.render({
+                        elem: '#search-end-date',
+                        done: function () {
+                            updateTableBySearch();
+                        }
+                    });
+                }
+
+                function transformToJson(formData){
+                    var obj={};
+                    for (var i in formData) {
+                        obj[formData[i].name]=formData[i]['value'];
+                    }
+                    return obj;
+                }
+
+                function updateTableBySearch() {
+                    table.reload('sg-main-table', {
+                        where: transformToJson($('#sg-search-form').serializeArray()),
+                        page: {
+                            curr: 1
+                        }
+                    });
+                }
+
+                $('#sg-search-btn').click(function() {
+                    updateTableBySearch();
+                });
+                // $('#sg-search-form').change(function () {
+                //     updateTableBySearch();
+                // });
+                //
+                // form.on('select()', function(){
+                //     updateTableBySearch();
+                // });
+
+                $('#sg-create-btn').on('click', function () {
+                    layer.open({
+                        title: '创建' + '{{ $model_name }}',
+                        type: 2,
+                        area: ['90%', '90%'],
+                        content: '{{ $pre_uri }}' + 'create',
+                        end: function () {
+                            top_window.location.reload();
+                        }
+                    });
+                });
+
+                $('#sg-table-top-container').on('click', '.btn-delete-many', function () {
+                    layer.confirm('确定要删除所有选中行吗?', function () {
+                        var data = table.checkStatus('sg-main-table').data;
+                        if(data.length <= 0) {
+                            layer.msg('选择不能为空', {
+                                icon: 2
+                            });
+                            return false;
+                        }
+                        var ids = [];
+                        for(var i = 0; i < data.length; ++i) {
+                            ids.push(data[i]['id']);
+                        }
+                        $.ajax({
+                            method: 'POST',
+                            url: '{{ $pre_uri }}' + 'deleteMany',
+                            headers: {
+                                'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                            },
+                            data: {
+                                ids: JSON.stringify(ids)
+                            },
+                            success: function (data) {
+                                if(data.status === 'success') {
+                                    top_window.location.reload();
+                                } else {
+                                    layer.msg(data.info, {
+                                        icon: 2
+                                    });
+                                }
+
+                            },
+                            error: function () {
+                                layer.msg('删除失败', {
+                                    icon: 2
+                                });
+                            }
+                        });
+                    })
+                });
+            });
+        })
+    </script>
+@endsection

+ 53 - 0
resources/views/admin/user-resets/create.blade.php

xqd
@@ -0,0 +1,53 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-container sg-create-container">
+        <div class="layui-col-sm8 layui-col-sm-offset2">
+            <form class="layui-form" method="POST" action="{{ $pre_uri . 'store' }}">
+
+                {{ csrf_field() }}
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '名称', 'required' => true, 'value' => (old('data') ? old('data')['name'] : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'key', 'label' => '键值', 'required' => true, 'value' => (old('data') ? old('data')['key'] : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'sort', 'label' => '排序', 'required' => true, 'value' => (old('data') ? old('data')['sort'] : '')])
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
+                        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                </div>
+            </form>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['form', 'laydate'], function(){
+                var form = layui.form;
+                var laydate = layui.laydate;
+
+                // form.verify({
+                //     integer: function (value) {
+                //         var pattern = /^[1-9]\d*$/;
+                //         if(!(pattern.test(value) || value === '0')) {
+                //             return '组员人数必须为大于等于0的整数';
+                //         }
+                //     }
+                // });
+
+                laydate.render({
+                    elem: '.sg-select-date'
+                });
+            });
+        })
+    </script>
+@endsection

+ 54 - 0
resources/views/admin/user-resets/edit.blade.php

xqd
@@ -0,0 +1,54 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-container sg-create-container">
+        <div class="layui-col-sm8 layui-col-sm-offset2">
+            <form class="layui-form" method="POST" action="{{ $pre_uri . 'update' }}">
+
+                {{ csrf_field() }}
+                <input type="hidden" name="id" value="{{ $item->id }}">
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '名称', 'required' => true, 'value' => ($item->name ? $item->name : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'key', 'label' => '键值', 'required' => true, 'value' => ($item->key ? $item->key : '')])
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'sort', 'label' => '排序', 'required' => true, 'value' => ($item->sort ? $item->sort : '')])
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
+                        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                </div>
+            </form>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['form', 'laydate'], function(){
+                var form = layui.form;
+                var laydate = layui.laydate;
+
+                // form.verify({
+                //     integer: function (value) {
+                //         var pattern = /^[1-9]\d*$/;
+                //         if(!(pattern.test(value) || value === '0')) {
+                //             return '组员人数必须为大于等于0的整数';
+                //         }
+                //     }
+                // });
+
+                laydate.render({
+                    elem: '.sg-select-date'
+                });
+            });
+        })
+    </script>
+@endsection

+ 220 - 0
resources/views/admin/user-resets/index.blade.php

xqd
@@ -0,0 +1,220 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-card">
+        <div class="layui-card-header sg-card-header">
+            {{ $model_name }}管理
+            {{--<div class="sg-card-create">--}}
+                {{--<button id="sg-create-btn" class="layui-btn layui-btn-sm">创建</button>--}}
+            {{--</div>--}}
+        </div>
+        <div class="layui-card-body">
+            {{--<form class="layui-form" id="sg-search-form">--}}
+                {{--<div class="layui-form-item layui-row">--}}
+                    {{--<div class="layui-inline">--}}
+                        {{--<div class="layui-input-inline">--}}
+                            {{--<input type="text" name="name" placeholder="请输入名称" autocomplete="off" class="layui-input" value="{{ request('name') }}">--}}
+                        {{--</div>--}}
+                    {{--</div>--}}
+                    {{--<div class="layui-inline">--}}
+                        {{--<div class="layui-btn" id="sg-search-btn">搜索</div>--}}
+                    {{--</div>--}}
+                {{--</div>--}}
+            {{--</form>--}}
+            <table id="sg-main-table" class="layui-hide" lay-filter="tableEvent"></table>
+            <script type="text/html" id="sg-table-bar">
+                <div class="layui-btn-group">
+                    <div class="layui-btn-group">
+                        <a class="layui-btn layui-btn-xs" lay-event="reset">重置</a>
+                    </div>
+                </div>
+            </script>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['table', 'layer'], function(){
+                var table = layui.table,
+                    layer = layui.layer,
+                    form = layui.form,
+                    laydate = layui.laydate,
+                    top_window = window;
+
+                table.render({
+                    elem: '#sg-main-table',
+                    url: '{{ $pre_uri }}' + 'get',
+                    cellMinWidth: 80,
+                    cols: [[
+                        { field: 'id', title: 'ID', align: 'center' },
+                        { field: 'phone', title: '手机', align: 'center' },
+                        { field: 'name', title: '姓名', align: 'center' },
+                        { field: 'created_at', title: '提交日期', align: 'center' },
+                        { field: 'status', title: '状态', align: 'center' },
+                        { title: '操作', align:'center', toolbar: '#sg-table-bar' }
+                    ]],
+                    page: {
+                        layout: ['count', 'prev', 'page', 'next', 'skip', 'refresh'],
+                        limit: 15
+                    },
+                    even: true,
+                    where: transformToJson($('#sg-search-form').serializeArray()),
+                    done: function(res, curr, count) {
+
+                    }
+                });
+                table.on('tool(tableEvent)', function(obj){
+                    var data = obj.data;
+                    if(obj.event === 'reset'){
+                        layer.confirm('确定要重置吗?', function(index) {
+                            $.ajax({
+                                method: 'POST',
+                                url: '{{ $pre_uri }}' + 'reset',
+                                headers: {
+                                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                                },
+                                data: {
+                                    id: data.id
+                                },
+                                success: function (data) {
+                                    if(data.status === 'success') {
+                                        // obj.del();
+                                        top_window.location.reload();
+                                    } else {
+                                        layer.msg(data.info, {
+                                            icon: 2
+                                        });
+                                    }
+                                    layer.close(index);
+                                },
+                                error: function () {
+                                    layer.close(index);
+                                    layer.msg('操作失败', {
+                                        icon: 2
+                                    });
+                                }
+                            });
+                        });
+                    } else if(obj.event === 'edit') {
+                        layer.open({
+                            title: '编辑成员',
+                            type: 2,
+                            area: ['90%', '90%'],
+                            content: '{{ $pre_uri }}' + 'edit?id=' + data.id,
+                            end: function () {
+                                top_window.location.reload();
+                            }
+                        });
+                    }
+                });
+
+                if($('#search-begin-date').length > 0) {
+                    laydate.render({
+                        elem: '#search-begin-date',
+                        done: function () {
+                            updateTableBySearch();
+                        }
+                    });
+                }
+
+                if($('#search-end-date').length > 0) {
+                    laydate.render({
+                        elem: '#search-end-date',
+                        done: function () {
+                            updateTableBySearch();
+                        }
+                    });
+                }
+
+                function transformToJson(formData){
+                    var obj={};
+                    for (var i in formData) {
+                        obj[formData[i].name]=formData[i]['value'];
+                    }
+                    return obj;
+                }
+
+                function updateTableBySearch() {
+                    table.reload('sg-main-table', {
+                        where: transformToJson($('#sg-search-form').serializeArray()),
+                        page: {
+                            curr: 1
+                        }
+                    });
+                }
+
+                $('#sg-search-btn').click(function() {
+                    updateTableBySearch();
+                });
+                // $('#sg-search-form').change(function () {
+                //     updateTableBySearch();
+                // });
+                //
+                // form.on('select()', function(){
+                //     updateTableBySearch();
+                // });
+
+                $('#sg-create-btn').on('click', function () {
+                    layer.open({
+                        title: '创建' + '{{ $model_name }}',
+                        type: 2,
+                        area: ['90%', '90%'],
+                        content: '{{ $pre_uri }}' + 'create',
+                        end: function () {
+                            top_window.location.reload();
+                        }
+                    });
+                });
+
+                $('#sg-table-top-container').on('click', '.btn-delete-many', function () {
+                    layer.confirm('确定要删除所有选中行吗?', function () {
+                        var data = table.checkStatus('sg-main-table').data;
+                        if(data.length <= 0) {
+                            layer.msg('选择不能为空', {
+                                icon: 2
+                            });
+                            return false;
+                        }
+                        var ids = [];
+                        for(var i = 0; i < data.length; ++i) {
+                            ids.push(data[i]['id']);
+                        }
+                        $.ajax({
+                            method: 'POST',
+                            url: '{{ $pre_uri }}' + 'deleteMany',
+                            headers: {
+                                'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                            },
+                            data: {
+                                ids: JSON.stringify(ids)
+                            },
+                            success: function (data) {
+                                if(data.status === 'success') {
+                                    top_window.location.reload();
+                                } else {
+                                    layer.msg(data.info, {
+                                        icon: 2
+                                    });
+                                }
+
+                            },
+                            error: function () {
+                                layer.msg('删除失败', {
+                                    icon: 2
+                                });
+                            }
+                        });
+                    })
+                });
+            });
+        })
+    </script>
+@endsection

+ 57 - 0
resources/views/admin/users/change-password.blade.php

xqd
@@ -0,0 +1,57 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-card">
+        <div class="layui-card-header sg-card-header">修改密码</div>
+        <div class="layui-card-body">
+            <div class="layui-container">
+                <div class="layui-row">
+                    <div class="layui-col-sm8 layui-col-sm-offset2">
+                        <form class="layui-form" method="POST" action="{{ $pre_uri . 'updatePassword' }}">
+
+                            {{ csrf_field() }}
+                            <input type="hidden" name="id" value="{{ $item->id }}">
+                            @include('share.layui-form-item', ['type' => 'input', 'input_type' =>
+                            'password', 'name' => 'old_password', 'label' => '原来密码', 'value' => '', 'placeholder' => '请输入原来密码'])
+                            @include('share.layui-form-item', ['type' => 'input', 'input_type' =>
+                            'password', 'name' => 'password', 'label' => '新的密码', 'value' => '', 'placeholder' => '请输入新密码'])
+                            @include('share.layui-form-item', ['type' => 'input', 'input_type' =>
+                            'password', 'name' => 'password_confirmation', 'label' => '确认密码', 'value' => ''])
+                            <div class="layui-form-item">
+                                <div class="layui-input-block">
+                                    <button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
+                                    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use('form', function(){
+                // var form = layui.form;
+
+                // form.verify({
+                //     integer: function (value) {
+                //         var pattern = /^[1-9]\d*$/;
+                //         if(!(pattern.test(value) || value === '0')) {
+                //             return '排序必须为大于等于0的整数';
+                //         }
+                //     }
+                // })
+            });
+        })
+    </script>
+@endsection

+ 63 - 0
resources/views/admin/users/create.blade.php

xqd
@@ -0,0 +1,63 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-container sg-create-container">
+        <div class="layui-col-sm8 layui-col-sm-offset2">
+            <form class="layui-form" method="POST" action="{{ $pre_uri . 'store' }}">
+
+                {{ csrf_field() }}
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '姓名', 'required' => true, 'value' => (old('data') ? old('data')['name'] : '')])
+                @include('share.layui-form-item', ['type' => 'select', 'name' => 'role_id', 'label' => '角色', 'selected_id' => (old('data') ? old('data')['role_id'] : ''), 'options' => $role_options])
+                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'input', 'name' => 'phone', 'label' => '手机号', 'required' => true, 'value' => ''])
+                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password', 'label' => '密码', 'required' => true, 'value' => ''])
+                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password_confirmation', 'label' => '确认密码', 'required' => true, 'value' => ''])
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <button class="layui-btn" lay-submit lay-filter="*">提交</button>
+                        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                </div>
+            </form>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['form', 'laydate'], function(){
+                var form = layui.form;
+                var laydate = layui.laydate;
+
+                // form.verify({
+                //     integer: function (value) {
+                //         var pattern = /^[1-9]\d*$/;
+                //         if(!(pattern.test(value) || value === '0')) {
+                //             return '组员人数必须为大于等于0的整数';
+                //         }
+                //     }
+                // });
+
+                form.on('submit(*)', function(data) {
+                    var field = data.field;
+                    if(field['data[road_id]'] !== '-1' && field['data[zone_id]'] === '-1') {
+                        layer.msg('选择街道前请先选择功能区');
+                        return false;
+                    }
+                });
+
+                laydate.render({
+                    elem: '.sg-select-date'
+                });
+            });
+        })
+    </script>
+@endsection

+ 50 - 0
resources/views/admin/users/edit.blade.php

xqd
@@ -0,0 +1,50 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-container sg-create-container">
+        <div class="layui-col-sm8 layui-col-sm-offset2">
+            <form class="layui-form" method="POST" action="{{ $pre_uri . 'update' }}">
+
+                {{ csrf_field() }}
+                <input type="hidden" name="id" value="{{ $item->id }}">
+                <input type="hidden" name="is_root" value="1">
+                @include('share.layui-form-item', ['type' => 'input', 'name' => 'name', 'label' => '用户名', 'required' => true, 'value' => $item->name])
+                @include('share.layui-form-item', ['type' => 'select', 'name' => 'role_id', 'label' => '角色', 'selected_id' => $item->role_id, 'options' => $role_options])
+                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'input', 'name' => 'phone', 'label' => '手机号', 'required' => true, 'value' => $item->phone])
+                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password', 'label' => '密码', 'value' => '', 'placeholder' => '请输入密码,不修改留空'])
+                @include('share.layui-form-item', ['type' => 'input', 'input_type' => 'password', 'name' => 'password_confirmation', 'label' => '确认密码', 'value' => ''])
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
+                        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
+                    </div>
+                </div>
+            </form>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use('form', function(){
+                // var form = layui.form;
+
+                // form.verify({
+                //     integer: function (value) {
+                //         var pattern = /^[1-9]\d*$/;
+                //         if(!(pattern.test(value) || value === '0')) {
+                //             return '排序必须为大于等于0的整数';
+                //         }
+                //     }
+                // })
+            });
+        })
+    </script>
+@endsection

+ 229 - 0
resources/views/admin/users/index.blade.php

xqd
@@ -0,0 +1,229 @@
+@extends('admin.layout-content')
+
+@section('header')
+    <style>
+
+    </style>
+@endsection
+
+@section('content')
+    <div class="layui-card">
+        <div class="layui-card-header sg-card-header">
+            {{ $model_name }}管理
+            <div class="sg-card-create">
+                <button id="sg-create-btn" class="layui-btn layui-btn-sm">创建{{ $model_name }}</button>
+            </div>
+        </div>
+        <div class="layui-card-body">
+            <form class="layui-form" id="sg-search-form">
+                <div class="layui-form-item layui-row">
+                    <div class="layui-inline">
+                        <div class="layui-input-inline">
+                            <select name="role_id">
+                                <option value="0">角色</option>
+                                @foreach($role_options as $option)
+                                    <option value="{{ $option['id'] }}" {{ request('role_id') == $option['id'] ? 'selected' : ''  }}>{{ $option['name'] }}</option>
+                                @endforeach
+                            </select>
+                        </div>
+                    </div>
+                    <div class="layui-inline">
+                        <div class="layui-input-inline">
+                            <input type="text" name="name" placeholder="请输入用户名" autocomplete="off" class="layui-input" value="{{ request('name') }}">
+                        </div>
+                    </div>
+                    <div class="layui-inline">
+                        <div class="layui-btn" id="sg-search-btn">搜索</div>
+                    </div>
+                </div>
+            </form>
+            <table id="sg-main-table" class="layui-hide" lay-filter="tableEvent"></table>
+            <script type="text/html" id="sg-table-bar">
+                <div class="layui-btn-group">
+                    <div class="layui-btn-group">
+                        <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
+                        <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</a>
+                    </div>
+                </div>
+            </script>
+        </div>
+    </div>
+@endsection
+
+@section('footer')
+    <script>
+        $(function () {
+            layui.use(['table', 'layer'], function(){
+                var table = layui.table,
+                    layer = layui.layer,
+                    form = layui.form,
+                    laydate = layui.laydate,
+                    top_window = window;
+
+                table.render({
+                    elem: '#sg-main-table',
+                    url: '{{ $pre_uri }}' + 'get',
+                    cellMinWidth: 80,
+                    cols: [[
+                        { field: 'name', title: '姓名', align: 'center' },
+                        { field: 'phone', title: '手机号', align: 'center' },
+                        { field: 'role_name', title: '角色', align: 'center' },
+                        { field: 'created_at', title: '创建时间', align: 'center' },
+                        { title: '操作', align:'center', toolbar: '#sg-table-bar' }
+                    ]],
+                    page: {
+                        layout: ['count', 'prev', 'page', 'next', 'skip', 'refresh'],
+                        limit: 15
+                    },
+                    even: true,
+                    where: transformToJson($('#sg-search-form').serializeArray()),
+                    done: function(res, curr, count) {
+
+                    }
+                });
+                table.on('tool(tableEvent)', function(obj){
+                    var data = obj.data;
+                    if(obj.event === 'delete'){
+                        layer.confirm('确定要删除吗?', function(index) {
+                            $.ajax({
+                                method: 'POST',
+                                url: '{{ $pre_uri }}' + 'delete',
+                                headers: {
+                                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                                },
+                                data: {
+                                    id: data.id
+                                },
+                                success: function (data) {
+                                    if(data.status === 'success') {
+                                        obj.del();
+                                    } else {
+                                        layer.msg(data.info, {
+                                            icon: 2
+                                        });
+                                    }
+                                    layer.close(index);
+                                },
+                                error: function () {
+                                    layer.close(index);
+                                    layer.msg('删除失败', {
+                                        icon: 2
+                                    });
+                                }
+                            });
+                        });
+                    } else if(obj.event === 'edit') {
+                        layer.open({
+                            title: '编辑账号',
+                            type: 2,
+                            area: ['90%', '90%'],
+                            content: '{{ $pre_uri }}' + 'edit?id=' + data.id,
+                            end: function () {
+                                top_window.location.reload();
+                            }
+                        });
+                    }
+                });
+
+                if($('#search-begin-date').length > 0) {
+                    laydate.render({
+                        elem: '#search-begin-date',
+                        done: function () {
+                            updateTableBySearch();
+                        }
+                    });
+                }
+
+                if($('#search-end-date').length > 0) {
+                    laydate.render({
+                        elem: '#search-end-date',
+                        done: function () {
+                            updateTableBySearch();
+                        }
+                    });
+                }
+
+                function transformToJson(formData){
+                    var obj={};
+                    for (var i in formData) {
+                        obj[formData[i].name]=formData[i]['value'];
+                    }
+                    return obj;
+                }
+
+                function updateTableBySearch() {
+                    table.reload('sg-main-table', {
+                        where: transformToJson($('#sg-search-form').serializeArray()),
+                        page: {
+                            curr: 1
+                        }
+                    });
+                }
+
+                $('#sg-search-btn').click(function() {
+                    updateTableBySearch();
+                });
+                // $('#sg-search-form').change(function () {
+                //     updateTableBySearch();
+                // });
+                //
+                // form.on('select()', function(){
+                //     updateTableBySearch();
+                // });
+
+                $('#sg-create-btn').on('click', function () {
+                    layer.open({
+                        title: '创建' + '{{ $model_name }}',
+                        type: 2,
+                        area: ['90%', '90%'],
+                        content: '{{ $pre_uri }}' + 'create',
+                        end: function () {
+                            top_window.location.reload();
+                        }
+                    });
+                });
+
+                $('#sg-table-top-container').on('click', '.btn-delete-many', function () {
+                    layer.confirm('确定要删除所有选中行吗?', function () {
+                        var data = table.checkStatus('sg-main-table').data;
+                        if(data.length <= 0) {
+                            layer.msg('选择不能为空', {
+                                icon: 2
+                            });
+                            return false;
+                        }
+                        var ids = [];
+                        for(var i = 0; i < data.length; ++i) {
+                            ids.push(data[i]['id']);
+                        }
+                        $.ajax({
+                            method: 'POST',
+                            url: '{{ $pre_uri }}' + 'deleteMany',
+                            headers: {
+                                'X-CSRF-TOKEN': '{{ csrf_token() }}'
+                            },
+                            data: {
+                                ids: JSON.stringify(ids)
+                            },
+                            success: function (data) {
+                                if(data.status === 'success') {
+                                    top_window.location.reload();
+                                } else {
+                                    layer.msg(data.info, {
+                                        icon: 2
+                                    });
+                                }
+
+                            },
+                            error: function () {
+                                layer.msg('删除失败', {
+                                    icon: 2
+                                });
+                            }
+                        });
+                    })
+                });
+            });
+        })
+    </script>
+@endsection

+ 1 - 0
routes/api.php

xqd
@@ -18,4 +18,5 @@ $api->version('v1', ['namespace' => 'App\Http\Controllers\Api\mini', 'prefix' =>
     $api->any('test', 'TestController@index');
     $api->any('login', 'AuthController@login');
     $api->any('reset', 'AuthController@reset');
+    $api->any('loginByWechat', 'AuthController@loginByWechat');
 });