Просмотр исходного кода

用户 添加 工作组 项目组

king 4 лет назад
Родитель
Сommit
c33742e112

+ 12 - 1
app/Http/Controllers/Auth/RegisterController.php

@@ -79,7 +79,6 @@ class RegisterController extends Controller
     {
         $headTo=$request->input('headTo')??'';
         $this->validator($request->all())->validate();
-
         event(new Registered($user = $this->create($request->all())));
         $phone=$request->input('phone');
         if ($phone) UserDetail::query()->create([
@@ -109,6 +108,18 @@ class RegisterController extends Controller
         if ($userWorkgroupId){
             $user->userWorkgroups()->sync([$userWorkgroupId]);
         }
+
+        //工作组
+        $work_id = [];
+        $treeData = $request->input('treeData')??[];
+        foreach ($treeData as $v){
+            if (strrpos($v,'g') != 'FALSE') array_push($work_id, mb_substr($v,1));
+        }
+        if ($work_id)$user->workGroups()->sync($work_id);
+        //项目组
+        $owners = $request->input('ownerGroup')??'';
+        if ($owners)$user->ownerGroups()->sync($owners);
+
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),$user['id']);
         if($headTo){return redirect(url($headTo))->with('successTip',"录入用户 {$user->name} 成功");}
         return $this->registered($request, $user)

+ 57 - 6
app/Http/Controllers/UserController.php

@@ -3,16 +3,12 @@
 namespace App\Http\Controllers;
 
 use App\Components\AsyncResponse;
-use App\Owner;
-use App\OwnerGroup;
 use App\Role;
 use App\Supplier;
 use App\User;
 use App\UserDetail;
 use App\UserWorkgroup;
-use Doctrine\DBAL\Configuration;
 use Exception;
-use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Auth;
@@ -81,7 +77,12 @@ class UserController extends Controller
         $logistics=app('LogisticService')->getSelection(["id","name"],"物流");
         $userWorkgroups=UserWorkgroup::query()->get();
         $suppliers=Supplier::query()->get();
-        return view('maintenance.user.create',['rolesAll'=>$roles,'logistics'=>$logistics,'userWorkgroups'=>$userWorkgroups,'suppliers'=>$suppliers]);
+
+        //工作组 项目组
+        /* @var $user User */
+        $workGroup = app('WarehouseService')->getTreeData();
+        $ownerGroup = app('UserOwnerGroupService')->getSelection();
+        return view('maintenance.user.create',['rolesAll'=>$roles,'logistics'=>$logistics,'userWorkgroups'=>$userWorkgroups,'suppliers'=>$suppliers, 'ownerGroup' => $ownerGroup, 'workGroup'=>$workGroup]);
     }
 
 
@@ -117,7 +118,19 @@ class UserController extends Controller
         $userWorkgroup=$user->userWorkgroups()->first();
         $supplierUser=$user->suppliers()->get();
         $suppliers=Supplier::query()->get();
-        return view('maintenance.user.edit',compact('user','rolesAll','roles','logistics','logisticUser','userWorkgroups','userWorkgroup','suppliers','supplierUser'));
+        //工作组 项目组
+        /* @var $user User */
+        $workGroup = app('WarehouseService')->getTreeData();
+        $group = $user->workGroups()->get();
+        $groups = [];
+        foreach ($group as $v){
+           array_push($groups,'g'.$v->id);
+           array_push($groups,'w'.$v->warehouse_id);
+        }
+        $workGroups = $groups;
+        $ownerGroup = app('UserOwnerGroupService')->getSelection();
+        $ownerGroups =  $user->ownerGroups->pluck('id');
+        return view('maintenance.user.edit',compact('user','rolesAll','roles','logistics','logisticUser','userWorkgroups','userWorkgroup','suppliers','supplierUser','workGroup','workGroups','ownerGroup','ownerGroups'));
     }
 
     /**
@@ -167,6 +180,18 @@ class UserController extends Controller
             if (!$user->userDetail) UserDetail::query()->create(['user_id'=>$user->id,'mobile_phone'=>$phone]);
             UserDetail::query()->where('user_id',$user->id) ->update(['mobile_phone'=>$phone]);
         }
+
+        //工作组
+        $work_id = [];
+        $treeData = $request->input('treeData')??[];
+        foreach ($treeData as $v){
+            if (strrpos($v,'g') != 'FALSE') array_push($work_id, mb_substr($v,1));
+        }
+        if ($work_id)$user->workGroups()->sync($work_id);
+        //项目组
+        $owners = $request->input('ownerGroup')??'';
+        if ($owners)$user->ownerGroups()->sync($owners);
+
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         app("UserService")->clearUserCache($user);
         return redirect('maintenance/user/')->with('successTip',"成功修改用户“{$user['name']}”!");
@@ -200,4 +225,30 @@ class UserController extends Controller
         $user->update(["password" => Hash::make(request("pwd"))]);
         $this->success();
     }
+
+    //工作组
+    public function saveWorkGroups(Request $request)
+    {
+        if(!Gate::allows('用户-编辑')){ return redirect(url('/'));  }
+        $params = $request->all();
+        $work_id = [];
+        foreach ($params['workGroups'] as $v){
+            if (strrpos($v,'g') != 'FALSE') array_push($work_id, mb_substr($v,1));
+        }
+        /* @var $user User */
+        $user = User::query()->find($params['id']);
+        $user->workGroups()->sync($work_id);
+        return ['success'=>true];
+    }
+
+    //工作组
+    public function saveOwnerGroups(Request $request)
+    {
+        if(!Gate::allows('用户-编辑')){ return redirect(url('/'));  }
+        $params = $request->all();
+        /* @var $user User */
+        $user = User::query()->find($params['id']);
+        $user->ownerGroups()->sync($params['ownerGroups']);
+        return ['success'=>true];
+    }
 }

+ 2 - 0
app/Providers/AppServiceProvider.php

@@ -183,6 +183,7 @@ use App\Services\WorkOrderTypeService;
 use App\Services\OrderPackageRemarkService;
 use App\Services\MeasureMonitorService;
 use App\Services\LaborCompanyService;
+use App\Services\UserAuthablesService;
 
 class AppServiceProvider extends ServiceProvider
 {
@@ -367,6 +368,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('TerminalPrinterService',TerminalPrinterService::class);
         app()->singleton('TerminalService',TerminalService::class);
         app()->singleton('UnitService', UnitService::class);
+        app()->singleton('UserAuthablesService',UserAuthablesService::class);
         app()->singleton('UserOwnerGroupService', UserOwnerGroupService::class);
         app()->singleton('UserService', UserService::class);
         app()->singleton('UserWorkgroupService', UserWorkgroupService::class);

+ 0 - 1
app/Services/UserWorkgroupService.php

@@ -16,5 +16,4 @@ class UserWorkgroupService
         }
         return UserWorkgroup::query()->select($column)->get();
     }
-
 }

+ 16 - 0
app/Services/WarehouseService.php

@@ -94,5 +94,21 @@ Class WarehouseService
             return null;
         });
     }
+
+    // 树状结构
+    public function getTreeData(){
+        $data = Warehouse::with(['userWorkgroups'])->get();
+        $return = [];
+        foreach ($data as $v){
+            $child = [];
+            if ($v->userWorkgroups){
+                foreach ($v->userWorkgroups as $val){
+                     array_push($child, ['id'=>'g'.$val->id, 'name'=>$val->name]);
+                }
+            }
+            array_push($return, ['id' => 'w'.$v->id, 'name'=> $v->name, 'child' => $child]);
+        }
+        return $return;
+    }
 }
 

+ 9 - 0
app/User.php

@@ -156,4 +156,13 @@ class User extends Authenticatable
         });
         return array_unique($labor_company_ids);
     }
+
+    public function workGroups()
+    {
+        return $this->morphedByMany(UserWorkgroup::class, 'user_authable');
+    }
+    public function ownerGroups()
+    {
+        return $this->morphedByMany(UserOwnerGroup::class, 'user_authable');
+    }
 }

+ 5 - 0
app/UserOwnerGroup.php

@@ -13,4 +13,9 @@ class UserOwnerGroup extends Model
     protected $fillable = [
         "name"  //名称
     ];
+
+    public function usersFromAuth()
+    {
+        return $this->morphToMany(User::class, 'user_authable');
+    }
 }

+ 5 - 0
app/UserWorkgroup.php

@@ -45,4 +45,9 @@ class UserWorkgroup extends Model
     {
         return $this->belongsToMany(OrderIssue::class);
     }
+
+    public function usersFromAuth()
+    {
+        return $this->morphToMany(User::class, 'user_authable');
+    }
 }

+ 33 - 0
database/migrations/2021_09_02_153438_create_user_authables_table.php

@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateUserAuthablesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('user_authables', function (Blueprint $table) {
+            $table->id();
+            $table->unsignedInteger('user_id');
+            $table->unsignedInteger('user_authable_id');
+            $table->string('user_authable_type');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('user_authables');
+    }
+}

+ 1 - 1
resources/js/vue/tree.vue

@@ -2,7 +2,7 @@
     <ul class="tree">
         <li v-for="item in list" :id="'li-'+item.id">
             <div class="custom-control custom-checkbox mb-3">
-                <input @change="checkedData(item.id,$event)" type="checkbox" class="custom-control-input" :value="item.id" :id="'check-'+item.id">
+                <input @change="checkedData(item.id,$event)" name="treeData[]" type="checkbox" class="custom-control-input" :value="item.id" :id="'check-'+item.id">
                 <label class="custom-control-label" :for="'check-'+item.id"></label>
                 <label style="cursor: pointer;" @click.prevent.stop="unfold(item.id)">{{item[column]}}&nbsp;
                 <i v-if="item.child && item.child.length>0" :id="'item-fa-'+item.id" class="fa fa-plus-circle"></i>

+ 81 - 0
resources/views/maintenance/user/create.blade.php

@@ -207,6 +207,58 @@
                                 </div>
                             </div>
 
+                            {{-- 工作组、项目组开始  --}}
+
+                            <div class="form-group row ">
+                                    <div class="col-6">
+                                        <div class="card-header row">
+                                            <div class="col-4">
+                                                <div class="pull-left h5 font-weight-bold mr-3">工作组</div>
+                                                <div class="pull-left text-muted">
+                                                    <div class="custom-control custom-checkbox">
+                                                        <input type="checkbox" class="custom-control-input" id="check-works" @change="hideNoSelected('workGroup',$event.target.checked)">
+                                                        <label class="custom-control-label ml-0" for="check-works">已拥有</label>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                            <div class="col-5">
+                                                <div class="btn-group">
+                                                    <a class="btn border btn-primary" @click="expand(true)">展开全部</a>
+                                                    <a class="btn border btn-primary" @click="expand(false)">收起全部</a>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div class="card-body overflow-scrollbar-200" style="max-height: 400px" id="workGroup">
+                                            <tree :list="workGroup" :column="'name'" ></tree>
+                                        </div>
+                                    </div>
+                                    <div class="col-6">
+                                        <div class="card-header row">
+                                            <div class="pull-left h5 font-weight-bold mr-3">项目组</div>
+                                            <div class="pull-left text-muted">
+                                                <div class="custom-control custom-checkbox">
+                                                    <input type="checkbox" class="custom-control-input" id="check-ownerGroups" @change="hideNoSelected('ownerGroup',$event.target.checked)">
+                                                    <label class="custom-control-label ml-0" for="check-ownerGroups">已拥有</label>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div class="card-body overflow-scrollbar-200" style="max-height: 400px">
+                                            <ul class="list-group">
+                                                <li class="list-group-item" v-for="owner in ownerGroup" v-show="!owner.hide">
+                                                    <div class="form-check">
+                                                        <label class="form-check-label w-100">
+                                                            <input type="checkbox" class="form-check-input" name="ownerGroup[]" v-model="ownerGroups"  :value="owner.id">@{{ owner.name }}
+                                                        </label>
+                                                    </div>
+                                                </li>
+                                            </ul>
+                                        </div>
+                                    </div>
+                                </div>
+
+                            {{-- 工作组、项目组结束--}}
+
+
                             <input type="hidden" value="{{url('maintenance/user/create')}}">
                             <div class="form-group row mb-0">
                                 <div class="col-md-7 offset-md-4">
@@ -283,6 +335,12 @@
                 ],
                 supplier: [{{old('supplier')}}],
                 suppliersList: [],
+
+                workGroup: [@foreach($workGroup as $wg)@json($wg),@endforeach],
+                ownerGroup: [@foreach($ownerGroup as $group)@json($group),@endforeach],
+            },
+            components:{
+                'tree':"url:{{asset("js/vue/tree.vue")}}"
             },
             mounted: function () {
                 $(".tooltipTarget").tooltip({ boundary: 'window' });
@@ -531,6 +589,29 @@
                         $(".tooltipTarget").tooltip({ boundary: 'window' });
                     }, 10 )
                 },
+
+                expand(isExpand){
+                    if (isExpand) $("#workGroup .up").slideDown();
+                    else $("#workGroup .up").slideUp();
+                },
+                hideNoSelected(type,isHide = true){
+                    switch (type) {
+                        case "ownerGroup":
+                            this.owners.forEach((owner,i)=>{
+                                let check =  isHide;
+                                if (owner.hide !== check)this.$set(this.owners[i],"hide",check);
+                            });
+                            break;
+                        case "workGroup":
+                            let nodes = document.getElementById("workGroup").getElementsByTagName("INPUT");
+                            for (let i=0;i<nodes.length;i++){
+                                if (!nodes[i].checked && isHide)nodes[i].parentElement.parentElement.className = "d-none";
+                                else nodes[i].parentElement.parentElement.className = "";
+                            }
+                            break;
+                        default: break;
+                    }
+                },
             },
         });
 

+ 119 - 0
resources/views/maintenance/user/edit.blade.php

@@ -140,6 +140,63 @@
                             </div>
                         </div>
                     </div>
+
+                    {{-- 工作组、项目组开始  --}}
+                    <hr class="col-8 offset-2 border-info">
+                    <div class="col-8 offset-2 border-info">
+                        <div class="form-group row ">
+                            <div class="col-6">
+                                <div class="card-header row">
+                                    <div class="col-4">
+                                        <div class="pull-left h5 font-weight-bold mr-3">工作组</div>
+                                        <div class="pull-left text-muted">
+                                            <div class="custom-control custom-checkbox">
+                                                <input type="checkbox" class="custom-control-input" id="check-works" @change="hideNoSelected('workGroup',$event.target.checked)">
+                                                <label class="custom-control-label ml-0" for="check-works">已拥有</label>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="col-5">
+                                        <div class="btn-group">
+                                            <a class="btn border btn-primary" @click="expand(true)">展开全部</a>
+                                            <a class="btn border btn-primary" @click="expand(false)">收起全部</a>
+                                        </div>
+                                    </div>
+                                    <div class="col-3">
+                                        <a class="pull-right btn btn-outline-success" @click="saveWorkGroups()">保存</a>
+                                    </div>
+                                </div>
+                                <div class="card-body overflow-scrollbar-200" style="max-height: 400px" id="workGroup">
+                                    <tree :list="workGroup" :column="'name'" ></tree>
+                                </div>
+                            </div>
+                            <div class="col-6">
+                                <div class="card-header row">
+                                    <div class="pull-left h5 font-weight-bold mr-3">项目组</div>
+                                    <div class="pull-left text-muted">
+                                        <div class="custom-control custom-checkbox">
+                                            <input type="checkbox" class="custom-control-input" id="check-ownerGroups" @change="hideNoSelected('ownerGroup',$event.target.checked)">
+                                            <label class="custom-control-label ml-0" for="check-ownerGroups">已拥有</label>
+                                        </div>
+                                    </div>
+                                    <a class="pull-right btn btn-outline-success" @click="saveOwnerGroups()">保存</a>
+                                </div>
+                                <div class="card-body overflow-scrollbar-200" style="max-height: 400px">
+                                    <ul class="list-group">
+                                        <li class="list-group-item" v-for="owner in ownerGroup" v-show="!owner.hide">
+                                            <div class="form-check">
+                                                <label class="form-check-label w-100">
+                                                    <input type="checkbox" class="form-check-input" name="ownerGroup[]" v-model="ownerGroups"  :value="owner.id">@{{ owner.name }}
+                                                </label>
+                                            </div>
+                                        </li>
+                                    </ul>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    {{-- 工作组、项目组结束--}}
+
                     <hr class="col-8 offset-2 border-info">
                     <div class="form-group row">
                         <div class="col-8 offset-2">
@@ -226,6 +283,16 @@
                     @endif
                 ],
                 suppliersList: [],
+
+                workGroup: [@foreach($workGroup as $wg)@json($wg),@endforeach],
+                workGroups: [@foreach($workGroups as $wgs)@json($wgs),@endforeach],
+
+                ownerGroup: [@foreach($ownerGroup as $group)@json($group),@endforeach],
+                ownerGroups: [@foreach($ownerGroups as $groups){!! "'".$groups."'" !!},@endforeach],
+                isFirst:0,
+            },
+            components:{
+                'tree':"url:{{asset("js/vue/tree.vue")}}"
             },
             mounted:function(){
                 $(".tooltipTarget").tooltip({'trigger':'hover'});
@@ -481,6 +548,58 @@
                         }
                     }
                 },
+
+                hideNoSelected(type,isHide = true){
+                    switch (type) {
+                        case "ownerGroup":
+                            this.owners.forEach((owner,i)=>{
+                                let check =  !this._includes(ownerGroups,owner.id) && isHide;
+                                if (owner.hide !== check)this.$set(this.owners[i],"hide",check);
+                            });
+                            break;
+                        case "workGroup":
+                            let nodes = document.getElementById("workGroup").getElementsByTagName("INPUT");
+                            for (let i=0;i<nodes.length;i++){
+                                if (!nodes[i].checked && isHide)nodes[i].parentElement.parentElement.className = "d-none";
+                                else nodes[i].parentElement.parentElement.className = "";
+                            }
+                            break;
+                        default: break;
+                    }
+                },
+                expand(isExpand){
+                    if (isExpand) $("#workGroup .up").slideDown();
+                    else $("#workGroup .up").slideUp();
+                },
+                _includes(arr,id){
+                    return !(arr.every(data=>{
+                        return !(data==id);
+                    }));
+                },
+                saveWorkGroups(){
+                    let workGroups = [];
+                    let nodes = document.getElementById("workGroup").getElementsByTagName("INPUT");
+                    for (let i=0;i<nodes.length;i++)if (nodes[i].checked)workGroups.push(nodes[i].value);
+                    window.tempTip.postBasicRequest("{{url('maintenance/user/saveWorkGroups')}}",{id:"{{$user->id}}",workGroups:workGroups},()=>{
+                        return "保存成功";
+                    });
+                },
+                saveOwnerGroups(){
+                    window.tempTip.postBasicRequest("{{url('maintenance/user/saveOwnerGroups')}}",{id:"{{$user->id}}",ownerGroups:this.ownerGroups},()=>{
+                        return "保存成功";
+                    });
+                },
+            },
+            updated() {
+                if (this.isFirst == 0){
+                    let nodes = document.getElementById("workGroup").getElementsByTagName("INPUT");
+                    for (let i=0;i<nodes.length;i++){
+                        let checked = this._includes(this.workGroups,nodes[i].value);
+                        if (nodes[i].checked!==checked)nodes[i].checked = checked;
+                        this.isFirst = 1;
+                    }
+                }
+
             }
         });
 

+ 2 - 0
routes/web.php

@@ -290,6 +290,8 @@ Route::group(['middleware'=>'auth'],function ($route){
         /** 用户 */
         Route::group(['prefix'=>"user"],function (){
             Route::post("resetPassword",'UserController@resetPassword');
+            Route::post("saveWorkGroups",'UserController@saveWorkGroups');
+            Route::post("saveOwnerGroups",'UserController@saveOwnerGroups');
         });
         /** 项目耗材 */
         Route::group(['prefix'=>"ownerMaterial"],function (){