Moell 9 роки тому
батько
коміт
f524f13dd8

+ 155 - 0
app/Http/Controllers/Backend/UserController.php

@@ -0,0 +1,155 @@
+<?php
+
+namespace App\Http\Controllers\Backend;
+
+use Illuminate\Http\Request;
+
+use App\Http\Requests;
+use App\Http\Controllers\Controller;
+use App\Models\User;
+use App\Repositories\UserRepositoryEloquent;
+use App\Http\Requests\Backend\User\CreateRequest;
+use App\Http\Requests\Backend\User\UpdateRequest;
+use Storage;
+use App\Services\ImageUploads;
+
+class UserController extends Controller
+{
+    protected $user;
+
+    /**
+     * UserController constructor.
+     * @param UserRepositoryEloquent $user
+     */
+    public function __construct(UserRepositoryEloquent $user)
+    {
+        $this->user = $user;
+    }
+
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        $user = $this->user->all(['id', 'name', 'email', 'user_pic'])->toArray();
+        return view("backend.user.index", compact('user'));
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        return view('backend.user.create');
+    }
+
+    /**
+     * @param CreateRequest $request
+     * @param ImageUploads $imageUploads
+     * @return $this
+     */
+    public function store(CreateRequest $request, ImageUploads $imageUploads)
+    {
+        if ($request->hasFile('user_pic')) {
+            $file = $request->file('user_pic');
+
+            $upload = $imageUploads->uploadAvatar($file);
+            if (!$upload['status']) {
+                return redirect()
+                    ->back()
+                    ->withErrors($upload['msg']);
+            }
+        }
+
+        $avatarFileName = isset($upload['fileName']) ? $upload['fileName'] : '';
+
+        if ($this->user->store($request->all(), $avatarFileName)) {
+            return redirect('backend/user')
+                ->with('success', '用户添加成功');
+        }
+
+        return redirect(route('backend.user.create'))->withErrors('系统异常,用户添加失败');
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  int  $id
+     * @return \Illuminate\Http\Response
+     */
+    public function show($id)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  int  $id
+     * @return \Illuminate\Http\Response
+     */
+    public function edit($id)
+    {
+        $user = $this->user->find($id);
+        return view("backend.user.edit", compact('user'));
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  int  $id
+     * @return \Illuminate\Http\Response
+     */
+    public function update(UpdateRequest $request, $id, ImageUploads $imageUploads)
+    {
+        $user = $this->user->find($id);
+        if (!$user) {
+            return redirect(route('backend.user.edit'))->back()->withErrors('非法参数或者用户不存在');
+        }
+
+        if ($request->hasFile('user_pic')) {
+            $file = $request->file('user_pic');
+
+            $upload = $imageUploads->uploadAvatar($file);
+            if (!$upload['status']) {
+                return redirect()
+                    ->back()
+                    ->withErrors($upload['msg']);
+            }
+        }
+
+        $avatarFileName = isset($upload['fileName']) ? $upload['fileName'] : '';
+
+        if ($this->user->updateUser($request->all(), $id, $avatarFileName)) {
+            if ($avatarFileName != "" && $user['user_pic'] != "") {
+                Storage::disk('upload')->delete('avatar/'.$user['user_pic']);
+            }
+            return redirect('backend/user')
+                ->with('success', '用户修改成功');
+        }
+        return redirect()
+            ->back()
+            ->withErrors('用户修改失败');
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  int  $id
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy($id)
+    {
+        if ($this->user->find($id)) {
+            if ($this->user->delete($id)) {
+                return response()->json(['status' => 0]);
+            }
+        }
+        return response()->json(['status' => 1]);
+    }
+}

+ 45 - 0
app/Http/Requests/Backend/User/CreateRequest.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Http\Requests\Backend\User;
+
+use App\Http\Requests\Request;
+
+class CreateRequest extends Request
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     *
+     * @return bool
+     */
+    public function authorize()
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        return [
+            'name' => "required|min:2",
+            'email' => "required|email|unique:users",
+            'password' => 'required|between:8,30'
+        ];
+    }
+
+    public function messages()
+    {
+        return [
+            'name.required' => '姓名必须填写',
+            'name.min'      => '姓名最小不能小于两字符',
+            'email.required'=> '登录邮箱必须填写',
+            'email.unique'=> '登录邮箱必须唯一',
+            'email.email'=> '请填写合法的邮箱',
+            'password.required'=> '请填写登录密码',
+            'password.between'=> '请填写8-30位的密码'
+        ];
+    }
+}

+ 45 - 0
app/Http/Requests/Backend/User/UpdateRequest.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Http\Requests\Backend\User;
+
+use App\Http\Requests\Request;
+
+class UpdateRequest extends Request
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     *
+     * @return bool
+     */
+    public function authorize()
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        $id = $this->route('user');
+        return [
+            'name' => "required|min:2",
+            'email' => "required|email|unique:users,email,".$id,
+            'password' => 'between:8,30'
+        ];
+    }
+
+    public function messages()
+    {
+        return [
+            'name.required' => '姓名必须填写',
+            'name.min'      => '姓名最小不能小于两字符',
+            'email.required'=> '登录邮箱必须填写',
+            'email.unique'=> '登录邮箱必须唯一',
+            'email.email'=> '请填写合法的邮箱',
+            'password.between'=> '请填写8-30位的密码'
+        ];
+    }
+}

+ 1 - 0
app/Http/routes.php

@@ -27,5 +27,6 @@ Route::group(['prefix'=>'backend'], function(){
         Route::get('/', 'Backend\HomeController@index');
         Route::resource('article', 'Backend\ArticleController');
         Route::resource('category', 'Backend\CategoryController');
+        Route::resource('user', 'Backend\UserController');
     });
 });

+ 1 - 1
app/Models/User.php

@@ -17,7 +17,7 @@ class User extends Authenticatable implements Transformable
      * @var array
      */
     protected $fillable = [
-        'name', 'email', 'password',
+        'name', 'email', 'password', 'user_pic',
     ];
 
     /**

+ 31 - 1
app/Repositories/UserRepositoryEloquent.php

@@ -6,7 +6,6 @@ use Prettus\Repository\Eloquent\BaseRepository;
 use Prettus\Repository\Criteria\RequestCriteria;
 use App\Repositories\UserRepository;
 use App\Models\User;
-use App\Validators\UserValidator;
 
 /**
  * Class UserRepositoryEloquent
@@ -25,6 +24,37 @@ class UserRepositoryEloquent extends BaseRepository implements UserRepository
     }
 
     
+    public function store(array $input, $avatar){
+
+        $attr['email'] = $input['email'];
+        $attr['password'] = bcrypt($input['password']);
+        $attr['name'] = $input['name'];
+
+        if ($avatar != "") {
+            $attr['user_pic'] = $avatar;
+        }
+        if (parent::create($attr)) {
+            return true;
+        }
+        return false;
+    }
+
+    public function updateUser(array $input, $id, $avatar = '')
+    {
+        $attr['email'] = $input['email'];
+        $attr['name'] = $input['name'];
+        if ($input['password'] != "")  {
+            $attr['password'] = bcrypt($input['password']);
+        }
+        if ($avatar != "") {
+            $attr['user_pic'] = $avatar;
+        }
+
+        if (parent::update($attr, $id)) {
+            return true;
+        }
+        return false;
+    }
 
     /**
      * Boot up the repository, pushing criteria

+ 67 - 0
app/Services/ImageUploads.php

@@ -0,0 +1,67 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: moell
+ * Date: 16-8-16
+ * Time: 下午10:41
+ */
+
+namespace App\Services;
+
+
+class ImageUploads
+{
+    protected  $file;
+
+    public function uploadAvatar($file)
+    {
+        $this->file = $file;
+
+        $allowedExtensions = ["png", "jpg", "jpeg", "gif"];
+
+        $check = $this->check($allowedExtensions);
+        if (!$check['status']) {
+            return $check;
+        }
+
+        $destPath = public_path('uploads/avatar');
+
+        $newFileName = md5(time().rand(0,10000)).'.'.$this->file->getClientOriginalExtension();
+        if(!$this->file->move($destPath, $newFileName)){
+            return ['status' => '系统异常,文件保存失败'];
+        }
+
+        return ['status' => true, 'fileName' => $newFileName];
+    }
+
+    private function check($allowedExtensions)
+    {
+        if (!$this->file->isValid()) {
+            return ['status' => false, 'msg' => '文件上失败'];
+        }
+
+        if (!$this->checkAllowedExtensions($allowedExtensions)) {
+            return ['status' => false, 'msg' => '非法的图片格式'];
+        }
+
+        if ($this->file->getSize() > 2 * 1024 * 1024) {
+            return ['status' => false, 'msg' => '图片大小不能大于2M'];
+        }
+
+        return ['status' => true];
+    }
+
+    /**
+     * 检测上传文件是否合法
+     *
+     * @param $allowedExtensions
+     * @return bool
+     */
+    private function checkAllowedExtensions($allowedExtensions)
+    {
+        if (!in_array(strtolower($this->file->getClientOriginalExtension()), $allowedExtensions)) {
+            return false;
+        }
+        return true;
+    }
+}

+ 5 - 0
config/filesystems.php

@@ -48,6 +48,11 @@ return [
             'root' => storage_path('app'),
         ],
 
+        'upload' => [
+            'driver' => 'local',
+            'root' => public_path('uploads')
+        ],
+
         'public' => [
             'driver' => 'local',
             'root' => storage_path('app/public'),

+ 31 - 0
database/migrations/2016_08_14_123836_add_users_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddUsersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->string('user_pic')->default('')->comment('博客用户头像');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('user_pic');
+        });
+    }
+}

+ 97 - 9
public/js/backend.js

@@ -24,11 +24,11 @@ $(function() {
         }
     });
 
-    /*$("#category-form #reset-btn").click(function(){
-        $('#category-form').data('bootstrapValidator').resetForm(true);
-        $('#category-form')[0].reset();
-    });*/
-    Moell.form.reset("#category-form", "#reset-btn");
+    $("#category-form #reset-btn").click(function(){
+        var categoryForm = $("#category-form");
+        categoryForm.data('bootstrapValidator').resetForm(true);
+        categoryForm[0].reset();
+    });
 
     /* 文章操作验证 */
     $("#article-form").bootstrapValidator({
@@ -51,11 +51,99 @@ $(function() {
         }
     });
 
-    /*$("#article-form #reset-btn").click(function(){
-        $('#article-form').data('bootstrapValidator').resetForm(true);
-    });*/
+    $("#article-form #reset-btn").click(function(){
+        var articleForm = $("#article-form");
+        articleForm.data('bootstrapValidator').resetForm(true);
+        articleForm[0].reset();
+    });
 
-    Moell.form.reset("#article-form", "#reset-btn");
+    /* user add */
+    $("#user-form").bootstrapValidator({
+        validatorDefaultParam,
+        fields : {
+            name : {
+                validators : {
+                    notEmpty : {
+                        message : "请输入姓名"
+                    },
+                    stringLength : {
+                        min : 2,
+                        max : 30,
+                        message : '姓名长度必须在2-30'
+                    }
+                }
+            },
+            email : {
+                validators : {
+                    notEmpty : {
+                        message : "请输入登录邮箱"
+                    },
+                    emailAddress : {
+                        message : "请输入正确的登录邮箱"
+                    }
+                }
+            },
+            password : {
+                validators : {
+                    notEmpty : {
+                        message : "请输入正确的登录密码"
+                    },
+                    stringLength : {
+                        min : 8,
+                        max : 30,
+                        message : '请输入8-30位的密码'
+                    }
+                }
+            }
+        }
+    });
 
+    $("#user-form #reset-btn").click(function(){
+        $("#user-form").data('bootstrapValidator').resetForm(true);
+        $("#user-form")[0].reset();
+    });
+
+    /* user edit */
+    $("#edit-user-form").bootstrapValidator({
+        validatorDefaultParam,
+        fields : {
+            name : {
+                validators : {
+                    notEmpty : {
+                        message : "请输入姓名"
+                    },
+                    stringLength : {
+                        min : 2,
+                        max : 30,
+                        message : '姓名长度必须在2-30'
+                    }
+                }
+            },
+            email : {
+                validators : {
+                    notEmpty : {
+                        message : "请输入登录邮箱"
+                    },
+                    emailAddress : {
+                        message : "请输入正确的登录邮箱"
+                    }
+                }
+            },
+            password : {
+                validators : {
+                    stringLength : {
+                        min : 8,
+                        max : 30,
+                        message : '请输入8-30位的密码'
+                    }
+                }
+            }
+        }
+    });
+
+    $("#edit-user-form #reset-btn").click(function(){
+        $("#user-form").data('bootstrapValidator').resetForm(true);
+        $("#user-form")[0].reset();
+    });
 
 });

+ 0 - 8
public/js/moell.js

@@ -24,13 +24,5 @@ var _token = $("meta[name='_token']").attr('content');
                 layer.close();
             })
         }
-    },
-    Moell.form = {
-        reset: function (form, resetBtn) {
-            $(resetBtn).click(function () {
-                $(form).data('bootstrapValidator').resetForm(true);
-                $(form)[0].reset();
-            });
-        }
     }
 })(Moell);

BIN
public/uploads/avatar/72777ce91c0c411f33dbe1db6fd7d343.jpg


BIN
public/uploads/avatar/7b128e6fed4b3069c1ae302f8f20f236.jpg


+ 65 - 0
resources/views/backend/user/create.blade.php

@@ -0,0 +1,65 @@
+@extends('layouts.backend')
+
+@section('title', '博客用户添加')
+
+@section('header')
+    <h1>
+        博客用户添加
+    </h1>
+@endsection
+
+@section('content')
+    <div class="row">
+        <div class="col-xs-12">
+            @include('backend.alert.warning')
+            <div class="box box-solid">
+                <form role="form" method="post" enctype="multipart/form-data" action="{{ url('backend/user') }}" id="user-form" >
+                    <div class="box-body">
+                        <div class="form-group">
+                            <label for="user_pic">头像</label>
+                            <div class="row">
+                                <div class='col-md-6'>
+                                    <input type="file" name="user_pic" id="user_pic" accept="image/png,image/gif,image/jpeg">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="name">名字</label>
+                            <div class="row">
+                                <div class='col-md-6'>
+                                    <input type='text' class='form-control' name="name" id='name' placeholder='请输入名字'>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="email">登录邮箱</label>
+                            <div class="row">
+                                <div class='col-md-6'>
+                                    <input type="text" class='form-control' name="email" id="email" placeholder="请输入唯一的邮箱">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="password">登录密码</label>
+                            <div class="row">
+                                <div class='col-md-6'>
+                                    <input type="password" class='form-control' name="password" id="password" placeholder="请输入大于等于8位的密码">
+                                </div>
+                            </div>
+                        </div>
+
+                    </div>
+
+                    {{ csrf_field() }}
+
+
+                    <div class="box-footer">
+                        <button type="submit" class="btn btn-primary">确定</button>
+                        <button type="button" class="btn btn-warning" id="reset-btn">重置</button>
+                    </div>
+                </form>
+            </div>
+            <!-- /.box -->
+        </div>
+    </div>
+@endsection

+ 69 - 0
resources/views/backend/user/edit.blade.php

@@ -0,0 +1,69 @@
+@extends('layouts.backend')
+
+@section('title', '博客用户修改')
+
+@section('header')
+    <h1>
+        博客用户修改
+    </h1>
+@endsection
+
+@section('content')
+    <div class="row">
+        <div class="col-xs-12">
+            @include('backend.alert.warning')
+            <div class="box box-solid">
+                <form role="form" method="post" enctype="multipart/form-data" action="{{ route('backend.user.update', ['id' => $user->id]) }}" id="edit-user-form">
+                    <div class="box-body">
+                        <div class="form-group">
+                            <label for="user_pic">头像</label>
+                            <div class="row">
+                                <div class='col-md-3'>
+                                    <input type="file" name="user_pic" id="user_pic" accept="image/png,image/gif,image/jpeg" >
+                                </div>
+                                <div class='col-md-6'>
+                                    <img src="{{ asset('uploads/avatar') }}/{{ $user->user_pic }}" class="img-circle" style="width:80px;height:auto;">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="name">名字</label>
+                            <div class="row">
+                                <div class='col-md-6'>
+                                    <input type='text' value="{{ $user->name }}" class='form-control' name="name" id='name' placeholder='请输入名字'>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="email">登录邮箱</label>
+                            <div class="row">
+                                <div class='col-md-6'>
+                                    <input type="text" value="{{ $user->email }}" class='form-control' name="email" id="email" placeholder="请输入唯一的邮箱">
+                                </div>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="password">登录密码</label>
+                            <div class="row">
+                                <div class='col-md-6'>
+                                    <input type="password" class='form-control' name="password" id="password" placeholder="请输入大于等于8位的密码">
+                                </div>
+                            </div>
+                        </div>
+
+                    </div>
+
+                    {{ csrf_field() }}
+                    {{ method_field('PUT') }}
+
+
+                    <div class="box-footer">
+                        <button type="submit" class="btn btn-primary">确定</button>
+                        <button type="button" class="btn btn-warning" id="reset-btn">重置</button>
+                    </div>
+                </form>
+            </div>
+            <!-- /.box -->
+        </div>
+    </div>
+@endsection

+ 73 - 0
resources/views/backend/user/index.blade.php

@@ -0,0 +1,73 @@
+@extends('layouts.backend')
+
+@section('title', '用户列表')
+
+@section('header')
+    <h1>
+        用户列表
+    </h1>
+@endsection
+
+@section('content')
+    <div class="row">
+        <div class="col-xs-12">
+            @include('backend.alert.success')
+            <div class="box box-solid">
+                <!-- /.box-header -->
+                <div class="box-header">
+                    <div class="pull-right">
+                        <div class="btn-group">
+                            <a href="{{ route('backend.user.create') }}" class="btn btn-white tooltips"
+                               data-toggle="tooltip" data-original-title="新增"><i
+                                        class="glyphicon glyphicon-plus"></i></a>
+                        </div>
+                    </div><!-- pull-right -->
+                </div>
+                <div class="box-body table-responsive no-padding ">
+                    <table class="table table-hover">
+                        <tr>
+                            <th>序号</th>
+                            <th>头像</th>
+                            <th>名字</th>
+                            <th>邮箱</th>
+                            <th>操作</th>
+                        </tr>
+                        @if ($user)
+                            <?php $line = 1  ?>
+                            @foreach($user as $u)
+                                <tr>
+                                    <td>{{ $line }}</td>
+                                    <td>
+                                        <img src="{{ asset('uploads/avatar') }}/{{ $u['user_pic'] }}" class="img-circle" style="width:30px;height:auto;">
+                                    </td>
+                                    <td>{{ $u['name'] }}</td>
+                                    <td>{{ $u['email'] }}</td>
+                                    <td>
+                                        <a href='{{ route("backend.user.edit", ["id" => $u['id']]) }}' class='btn btn-info btn-xs'>
+                                            <i class="fa fa-pencil"></i> 修改</a>
+                                        <a data-href='{{ route("backend.user.destroy", ["id" => $u['id']]) }}'
+                                           class='btn btn-danger btn-xs user-delete'><i class="fa fa-trash-o"></i> 删除</a>
+                                    </td>
+                                </tr>
+                                <?php $line++ ?>
+                            @endforeach
+                        @endif
+                    </table>
+                </div>
+                <!-- /.box-body -->
+            </div>
+            <!-- /.box -->
+        </div>
+    </div>
+@endsection
+
+@section('javascript')
+    <script>
+        $(function() {
+            $(".user-delete").click(function(){
+                var url = $(this).attr('data-href');
+                Moell.ajax.delete(url);
+            });
+        });
+    </script>
+@endsection

+ 4 - 4
resources/views/layouts/backend.blade.php

@@ -35,7 +35,7 @@
 
     <header class="main-header">
         <!-- Logo -->
-        <a href="index2.html" class="logo">
+        <a href="{{ url('backend/' )}}" class="logo">
             <!-- mini logo for sidebar mini 50x50 pixels -->
             <span class="logo-mini"><b>M</b>B</span>
             <!-- logo for regular state and mobile devices -->
@@ -131,13 +131,13 @@
                     <!-- User Account: style can be found in dropdown.less -->
                     <li class="dropdown user user-menu">
                         <a href="#" class="dropdown-toggle" data-toggle="dropdown">
-                            <img src="{{ asset('uploads/images/moell.jpg') }}" class="user-image" alt="User Image">
+                            <img src="{{ asset('uploads/avatar')."/".Auth::user()->user_pic }}" class="user-image" alt="User Image">
                             <span class="hidden-xs"></span>
                         </a>
                         <ul class="dropdown-menu">
                             <!-- User image -->
                             <li class="user-header">
-                                <img src="{{ asset('uploads/images/moell.jpg') }}" class="img-circle" alt="User Image">
+                                <img src="{{ asset('uploads/avatar')."/".Auth::user()->user_pic }}" class="img-circle" alt="User Image">
 
                                 <p>
                                     Moell Blog - 做努力的自己
@@ -181,7 +181,7 @@
             <!-- Sidebar user panel -->
             <div class="user-panel">
                 <div class="pull-left image">
-                    <img src="{{ asset('uploads/images/moell.jpg') }}" class="img-circle" alt="User Image">
+                    <img src="{{ asset('uploads/avatar')."/".Auth::user()->user_pic }}" class="img-circle" alt="User Image">
                 </div>
                 <div class="pull-left info">
                     <p></p>