Browse Source

Merge branch 'master' into Haozi

# Conflicts:
#	resources/views/layouts/menu.blade.php
#	resources/views/personnel/laborReport/menu.blade.php
#	resources/views/personnel/menu.blade.php
hu hao 4 năm trước cách đây
mục cha
commit
804e64ff39
100 tập tin đã thay đổi với 3510 bổ sung1425 xóa
  1. 4 2
      app/Authority.php
  2. 19 0
      app/CommodityMaterialBoxModel.php
  3. 1 3
      app/Console/Commands/CheckCacheRackStorage.php
  4. 60 0
      app/Console/Commands/OrderCountingRecordTask.php
  5. 2 1
      app/Console/Kernel.php
  6. 2 0
      app/Events/BroadcastToStation.php
  7. 1 1
      app/Http/Controllers/Auth/LoginController.php
  8. 12 5
      app/Http/Controllers/Auth/PasswordController.php
  9. 48 138
      app/Http/Controllers/AuthorityController.php
  10. 11 10
      app/Http/Controllers/CacheShelfController.php
  11. 3 3
      app/Http/Controllers/ControlPanelController.php
  12. 2 1
      app/Http/Controllers/DeliveryAppointmentController.php
  13. 50 12
      app/Http/Controllers/DischargeTaskController.php
  14. 1 1
      app/Http/Controllers/HomeController.php
  15. 2 2
      app/Http/Controllers/InventoryController.php
  16. 8 8
      app/Http/Controllers/LogisticController.php
  17. 128 0
      app/Http/Controllers/MenuController.php
  18. 1 1
      app/Http/Controllers/OrderCommodityAssignController.php
  19. 85 0
      app/Http/Controllers/OwnerLogisticFeeDetailController.php
  20. 85 0
      app/Http/Controllers/OwnerLogisticFeeReportController.php
  21. 1 1
      app/Http/Controllers/RejectedController.php
  22. 64 130
      app/Http/Controllers/RoleController.php
  23. 162 146
      app/Http/Controllers/StorageController.php
  24. 8 0
      app/Http/Controllers/StoreController.php
  25. 88 32
      app/Http/Controllers/TestController.php
  26. 4 4
      app/Http/Controllers/WaybillController.php
  27. 1 1
      app/Http/Controllers/WaybillFinancialExceptedController.php
  28. 2 2
      app/Http/Controllers/WaybillFinancialSnapshotsController.php
  29. 21 254
      app/Http/Controllers/api/thirdPart/goodscan/PackageController.php
  30. 28 12
      app/Http/Controllers/api/thirdPart/haiq/LightController.php
  31. 24 21
      app/Http/Controllers/api/thirdPart/hengli/PackageController.php
  32. 37 315
      app/Http/Controllers/api/thirdPart/weight/PackageController.php
  33. 10 0
      app/Http/Requests/DischargeTask/DischargeTaskRequest.php
  34. 83 0
      app/Imports/DischargeTaskImport.php
  35. 3 1
      app/Imports/StoreCheckingReceiveImport.php
  36. 1 1
      app/Jobs/LogisticSFSync.php
  37. 6 4
      app/Jobs/LogisticYDSync.php
  38. 2 2
      app/Jobs/LogisticYTOSync.php
  39. 1 2
      app/Jobs/LogisticZopSync.php
  40. 5 1
      app/MaterialBox.php
  41. 16 0
      app/MaterialBoxModel.php
  42. 1 1
      app/Menu.php
  43. 8 0
      app/Observers/OwnerObserver.php
  44. 16 0
      app/Observers/UserWorkGroupObserver.php
  45. 14 1
      app/OrderCountingRecord.php
  46. 4 0
      app/Owner.php
  47. 12 0
      app/OwnerFeeDetail.php
  48. 6 0
      app/OwnerFeeDetailLogistic.php
  49. 26 0
      app/OwnerLogisticFeeDetail.php
  50. 14 0
      app/OwnerLogisticFeeReport.php
  51. 31 8
      app/Providers/AppServiceProvider.php
  52. 1 0
      app/Providers/AuthServiceProvider.php
  53. 1 1
      app/RejectedBill.php
  54. 9 0
      app/Role.php
  55. 87 0
      app/Services/AuthorityService.php
  56. 19 10
      app/Services/BatchService.php
  57. 120 140
      app/Services/CacheShelfService.php
  58. 51 0
      app/Services/CommodityMaterialBoxModelService.php
  59. 2 2
      app/Services/DischargeTaskService.php
  60. 43 50
      app/Services/ForeignHaiRoboticsService.php
  61. 11 9
      app/Services/LaborReportsCountingRecordService.php
  62. 1 1
      app/Services/LogisticRouteInterface.php
  63. 18 5
      app/Services/LogisticYDService.php
  64. 8 2
      app/Services/LogisticYTOService.php
  65. 16 14
      app/Services/LogisticZopService.php
  66. 22 4
      app/Services/MaterialBoxService.php
  67. 127 0
      app/Services/MenuService.php
  68. 257 20
      app/Services/NewOrderCountingRecordService.php
  69. 10 6
      app/Services/OrderPackageReceivedSyncService.php
  70. 95 0
      app/Services/OwnerLogisticFeeDetailService.php
  71. 13 0
      app/Services/OwnerLogisticFeeReportService.php
  72. 5 1
      app/Services/PackageStatisticsService.php
  73. 1 0
      app/Services/RejectedService.php
  74. 33 0
      app/Services/RoleService.php
  75. 16 0
      app/Services/StationService.php
  76. 22 4
      app/Services/StationTaskMaterialBoxService.php
  77. 431 7
      app/Services/StorageService.php
  78. 71 0
      app/Services/UserService.php
  79. 42 0
      app/Services/weight/GoodScanWeightService.php
  80. 49 0
      app/Services/weight/HaoChuangWeightService.php
  81. 45 0
      app/Services/weight/HengLiWeightService.php
  82. 503 0
      app/Services/weight/WeightService.php
  83. 5 0
      app/Station.php
  84. 42 0
      app/TaskTransaction.php
  85. 8 4
      app/User.php
  86. 4 0
      app/UserWorkgroup.php
  87. 10 1
      app/Utils/helpers.php
  88. 2 2
      config/cache.php
  89. 0 1
      database/factories/OrderCountingRecordFactory.php
  90. 17 0
      database/factories/OwnerLogisticFeeDetailFactory.php
  91. 12 0
      database/factories/OwnerLogisticFeeReportFactory.php
  92. 1 0
      database/factories/StationTaskFactory.php
  93. 6 1
      database/factories/StationTaskMaterialBoxFactory.php
  94. 15 0
      database/factories/StorageFactory.php
  95. 0 4
      database/migrations/2019_12_03_174626_add_data_authorities_waybill.php
  96. 0 5
      database/migrations/2020_03_09_132100_add_store_transfer_authority.php
  97. 1 1
      database/migrations/2020_11_23_143015_create_value_stores_table.php
  98. 0 1
      database/migrations/2020_12_02_150054_create_order_commodity_assigns_table.php
  99. 0 2
      database/migrations/2020_12_12_093011_change_authorities_order_assign.php
  100. 34 0
      database/migrations/2021_04_27_104357_change_menus_table_add_font_column.php

+ 4 - 2
app/Authority.php

@@ -7,13 +7,15 @@ use Illuminate\Database\Eloquent\Model;
 use App\Traits\ModelTimeFormat;
 
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Support\Facades\DB;
 
 class Authority extends Model
 {
     use ModelLogChanging;
-
+    //use SoftDeletes;
     use ModelTimeFormat;
-    protected $fillable = ['name','remark','id_parent','alias_name','type','relevance','permission'];
+    protected $fillable = ['name','parent_id','alias_name','permission'];
     function roles(){
         return $this->belongsToMany('App\Role','authority_role','id_authority','id_role');
     }

+ 19 - 0
app/CommodityMaterialBoxModel.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class CommodityMaterialBoxModel extends Model
+{
+    use ModelLogChanging;
+
+    protected $table = "commodity_material_box_model";
+    public $timestamps = false;
+
+    protected $fillable=[
+        "commodity_id","material_box_model_id","maximum"
+    ];
+}

+ 1 - 3
app/Console/Commands/CheckCacheRackStorage.php

@@ -4,9 +4,7 @@ namespace App\Console\Commands;
 
 use App\Station;
 use App\StationTask;
-use App\StationTaskMaterialBox;
 use Illuminate\Console\Command;
-use Illuminate\Support\Collection;
 
 class CheckCacheRackStorage extends Command
 {
@@ -46,6 +44,6 @@ class CheckCacheRackStorage extends Command
                 ->where("status","!=","完成")->whereIn("station_id",Station::query()->select("id")->where("station_type_id",5)
                     ->whereNotNull("parent_id"))->groupBy("station_id"))
             ->get();
-        app("StorageService")->paddingCacheShelf($stations);
+        app("ForeignHaiRoboticsService")->paddingCacheShelf($stations);
     }
 }

+ 60 - 0
app/Console/Commands/OrderCountingRecordTask.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\LogService;
+use App\Services\NewOrderCountingRecordService;
+use Illuminate\Console\Command;
+
+class OrderCountingRecordTask extends Command
+{
+    /**
+     * @var NewOrderCountingRecordService $service
+     */
+    public $service;
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'orderCountingRecordTask';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @throws \Exception
+     */
+    public function handle()
+    {
+        LogService::log(OrderCountingRecordTask::class, "订单量统计", '');
+        ini_set('memory_limit', '2226M');
+        $this->service = app('NewOrderCountingRecordService');
+        if (now()->toDateString() == now()->startOfMonth()->toDateString()) {//是否为月初
+            //统计上月的数据
+            $this->service->recordOrder(now()->subMonth()->startOfMonth()->toDateString(), now()->subMonth()->endOfMonth()->toDateString(), '月');
+        }
+        if (now()->toDateString() == now()->startOfYear()->toDateString()) {//是否为年初
+            //统计上年的数据
+            $this->service->recordOrder(now()->subYear()->startofYear()->toDateString(), now()->subYear()->endOfYear()->toDateString(), '年');
+        }
+        //统计前一天的数据
+        $this->service->recordOrder(now()->subDay()->toDateString(), now()->subDay()->toDateString(), '日');
+    }
+}

+ 2 - 1
app/Console/Kernel.php

@@ -80,7 +80,8 @@ class  Kernel extends ConsoleKernel
         $schedule->command('create:weightStatistic')->dailyAt("00:30");
         $schedule->command('sync:carrier')->hourlyAt(1);
         $schedule->command('createProcurementTotalBill')->monthlyOn(1);
-        $schedule->command('check:cacheRack')->everyMinute();
+        $schedule->command('orderCountingRecordTask')->dailyAt("1:00");
+        //$schedule->command('check:cacheRack')->everyMinute();
     }
 
     /**

+ 2 - 0
app/Events/BroadcastToStation.php

@@ -19,6 +19,7 @@ class BroadcastToStation implements ShouldBroadcastNow
      */
     public function __construct(int $id, string $json)
     {
+        app('LogService')->log('海柔','broadcast1',$id.$json);
         $this->id = $id;// 0意味着通用站,所有站都需要收发的意思
         $this->json = $json;
     }
@@ -30,6 +31,7 @@ class BroadcastToStation implements ShouldBroadcastNow
      */
     public function broadcastOn()
     {
+        app('LogService')->log('海柔','broadcast2',$this->id.$this->json);
         return new Channel('station-'.$this->id);
     }
 }

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

@@ -86,7 +86,7 @@ class LoginController extends Controller
             if(env('DB_USERNAME')!='developer')
                 app('LogService')->log(__METHOD__,__FUNCTION__,'',Auth::user()['id']);
             if($request['is_json']){
-                return ['success'=>true,'url'=>url($this->redirectTo)];
+                return ['success'=>true,'url'=>url($this->redirectTo),'menus'=>app("MenuService")->getVisibleFunctionList()];
             }
             return $this->sendLoginResponse($request)->header('Cache-Control','no-store');
         }

+ 12 - 5
app/Http/Controllers/Auth/PasswordController.php

@@ -2,9 +2,10 @@
 
 namespace App\Http\Controllers\Auth;
 
+use App\Components\AsyncResponse;
 use App\Http\Controllers\Controller;
+use App\User;
 use Illuminate\Auth\Events\PasswordReset;
-use Illuminate\Foundation\Auth\ResetsPasswords;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Hash;
@@ -12,7 +13,7 @@ use Illuminate\Support\Str;
 
 class PasswordController extends Controller
 {
-
+    use AsyncResponse;
 
     /**
      * Where to redirect users after resetting their password.
@@ -34,16 +35,22 @@ class PasswordController extends Controller
     {
         return view('auth.passwords.change');
     }
-    public function update(Request $request)
+    public function update(/*Request $request*/)
     {
+        /** @var User|\stdClass $user */
         $user=Auth::user();
-        $request->validate($this->rules(), $this->validationErrorMessages());
+        if (!$user)$this->error("登录过期,请重新登录");
+        if (!Hash::check(\request("old"),$user->password))$this->error("旧密码输入有误");
+        if (Hash::check(\request("pwd"),$user->password))$this->error("新密码不得与旧密码相同");
+        $user->update(["password" => Hash::make(\request("pwd"))]);
+        $this->success();
+        /*$request->validate($this->rules(), $this->validationErrorMessages());
         $user->password = Hash::make($request->input('password'));
         $user->setRememberToken(Str::random(60));
         $user->save();
         event(new PasswordReset($user));
         Auth::guard()->login($user);
-        return view('auth.passwords.changed');
+        return view('auth.passwords.changed');*/
     }
     protected function rules()
     {

+ 48 - 138
app/Http/Controllers/AuthorityController.php

@@ -4,12 +4,8 @@ namespace App\Http\Controllers;
 
 use App\Authority;
 use App\Components\AsyncResponse;
-use App\Owner;
+use App\Services\common\BatchUpdateService;
 use App\User;
-use Exception;
-use Illuminate\Http\Request;
-use Illuminate\Http\Response;
-use Illuminate\Queue\RedisQueue;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Validator;
@@ -17,152 +13,66 @@ use Illuminate\Support\Facades\Validator;
 class AuthorityController extends Controller
 {
     use AsyncResponse;
-
-    /**
-     * Display a listing of the resource.
-     *
-     * @return string
-     */
     public function index()
     {
-
-        if(!Gate::allows('权限-查询')){ return redirect(url('/'));  }
-        $authorities=Authority::orderBy('id','asc')->paginate(100);
+        if (!Gate::allows('权限-查询')){return view("exception.authority"); }
+        $authorities = app("AuthorityService")->format(Authority::query()->get());
         return view('maintenance.authority.index',['authorities'=>$authorities]);
     }
 
-    /**
-     * Show the form for creating a new resource.
-     *
-     * @return string
-     */
-    public function create()
-    {
-        if(!Gate::allows('权限-录入')){ return redirect(url('/'));  }
-        $owners=Owner::all();
-        return view('maintenance.authority.create',compact('owners'));
-    }
-
-//    /**
-//     * Store a newly created resource in storage.
-//     *
-//     * @param Request $request
-//     * @return string
-//     */
-//    public function store(Request $request)
-//    {
-//        if(!Gate::allows('权限-录入')){ return redirect(url('/'));  }
-//        $inputs=$request->all();
-//        $inputs['combinedName']=$request->input('name').'_'.$request->input('id_owner');
-//        $this->validatorCreate($inputs)->validate();
-//        $successName= $request->input('name')??'';
-//        $inputs['name']=$inputs['combinedName'];
-//
-//        if($request->input('id_owner')??''){
-//            $owner=Owner::find($inputs['id_owner']);
-//            if(isset($inputs['remark'])){
-//                $inputs['remark'].="(key: {$inputs['combinedName']})";
-//            }else{
-//                $inputs['remark']="(key: {$inputs['combinedName']})";
-//            }
-//            $inputs['alias_name']=$request->input('name')."_(货主:$owner->name)";
-//            $successName.="(货主:$owner->name)";
-//        }else{
-//            $inputs['alias_name']=$request->input('name');
-//        }
-//        $authority=new Authority($inputs);
-//        $authority->save();
-//
-//        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-//        return redirect('maintenance/authority/create')->with('successTip',"成功录入权限“{$successName}”");
-//    }
-
-    public function store(Request $request)
-    {
-        if(!Gate::allows('权限-录入')){ return redirect(url('/'));  }
-        $this->validatorCreate($request->all())->validate();
-        $owner=Owner::find($request->input('id_owner'));
-
-        $authority=new Authority(['alias_name'=>"(货主:{$owner['name']})",'name'=>"_{$owner['id']}",'remark'=>"(key: _{$owner['id']})"]);
-        $authority->save();
-
-        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-        return redirect('maintenance/authority/create')->with('successTip',"成功录入权限: (货主:{$owner['name']})");
-    }
-
-    protected function validatorCreate(array $data)
+    public function store()
     {
-        $data['name']="_{$data['id_owner']}";
-        return Validator::make($data, [
-            'id_owner' => ['required', 'exists:owners,id'],
-            'name' => ['unique:authorities,name'],
-        ],[
-            'id_owner.required' => '必须选一个货主',
-            'id_owner.exists' => '当前货主不存在',
-            'name.unique' => '该货主对应权限已添加过',
+        $this->gate("权限-录入");
+        $errors = Validator::make(\request()->input(),
+            ['parent_id'=>['nullable',"integer"],
+             'name'=>'required',
+             'alias_name'=>['required','unique:authorities,alias_name'],
+             'permission'=>'required',
+            ],[
+            'integer'=>':attribute 非法参数',
+            'required'=>':attribute 必填',
+            ],[
+                'parent_id'=>'父级',
+                'name'=>'权限名',
+                'alias_name'=>'唯一标识',
+                'permission'=>'许可',
+                'unique'=>'重复'
+            ])->errors();
+        if ($errors->count()>0)$this->success(["errors"=>$errors]);
+        $authority = Authority::query()->create([
+            'name'          => \request("name"),
+            'parent_id'     => \request("parent_id"),
+            'alias_name'    => \request("alias_name"),
+            'permission'    => \request("permission")
         ]);
+        app("AuthorityService")->removeAdminAuth();
+        $this->success($authority);
     }
 
-    protected function validatorUpdate(array $data)
-    {
-        return Validator::make($data, [
-            'name' => ['required', 'string', 'max:50'],
-        ]);
-    }
-    /**
-     * Display the specified resource.
-     *
-     * @param Authority $authority
-     * @return Response
-     */
-    public function show(Authority $authority)
-    {
-        //
-    }
-
-    /**
-     * Show the form for editing the specified resource.
-     *
-     * @param \App\Http\Controllers\Authority $authority
-     * @return Response
-     */
-    public function edit(Authority $authority)
-    {
-        if(!Gate::allows('权限-编辑')){ return redirect(url('/'));  }
-        $owners=Owner::all();
-        return view('maintenance.authority.edit',compact('owners','authority'));
-    }
-
-    /**
-     * Update the specified resource in storage.
-     *
-     * @param Request $request
-     * @param \App\Http\Controllers\Authority $authority
-     * @return Response
-     */
-    public function update(Request $request, Authority $authority)
+    public function update()
     {
-        if(!Gate::allows('权限-编辑')){ return redirect(url('/'));  }
-        $this->validatorUpdate($request->all())->validate();
-        $authority->fill($request->all());
-        $authority->update();
-        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-        return redirect('maintenance/authority/')->with('successTip',"成功修改权限“{$authority['name']}”!");
+        $this->gate("权限-编辑");
+        $list = request("list");
+        if (!$list || count($list)<1)$this->success();
+        array_unshift($list,["id","name"]);
+        app(BatchUpdateService::class)->batchUpdate("authorities",$list);//更新权限名
+        app("AuthorityService")->removeAllAuth();//刷掉权限缓存
+        $updateMenu = [["id","name"]];
+        $mapping = array_flip(app("MenuService")->getMenuAndAuthorityMapping());//获取菜单与权限映射并反转
+        foreach (request("list") as $data)if (isset($mapping[$data["id"]]))$updateMenu[] = ["id"=>$mapping[$data["id"]],"name"=>$data["name"]];//验证更新的权限中是否存在有映射关系的缓存并记录
+        if (count($updateMenu)>1){
+            app(BatchUpdateService::class)->batchUpdate("menus",$updateMenu);//存在映射关系的缓存更新映射对象
+            app("MenuService")->setMenu();//重建菜单缓存
+        }
+        $this->success();
     }
 
-    /**
-     * Remove the specified resource from storage.
-     *
-     * @param \App\Http\Controllers\Authority $authority
-     * @return array|Response
-     * @throws Exception
-     */
-    public function destroy(Authority $authority)
+    public function destroy()
     {
-        if(!Gate::allows('权限-删除')){ return redirect(url('/'));  }
-        app('LogService')->log(__METHOD__,__FUNCTION__,$authority->toJson(),Auth::user()['id']);
-        $re=$authority->delete();
-        return ['success'=>$re];
+        $this->gate("权限-删除");
+        Authority::destroy(request("ids"));
+        app("AuthorityService")->removeAllAuth();//刷掉权限缓存
+        $this->success();
     }
 
     public function getAuthoritiesApi()

+ 11 - 10
app/Http/Controllers/CacheShelfController.php

@@ -30,16 +30,15 @@ class CacheShelfController extends Controller
     }
 
     /**
-     * 获取缓存货架上的任务列表
+     * 获取缓存货架上的料箱
      * @param Request $request
      * @param string $id
      * @param CacheShelfService $service
      */
-    public function getTasksApi(Request $request,string $id,CacheShelfService $service)
+    public function getChildStationApi(Request $request,string $id,CacheShelfService $service)
     {
-        /** @var Station $station */
-        $station = $service->getChildStation($id);
-        $this->success($station);
+        $stations = $service->getChildStation($id);
+        $this->success($stations);
     }
 
     /**
@@ -48,21 +47,23 @@ class CacheShelfController extends Controller
      * @param CacheShelfService $service
      * @return mixed
      */
-    public function lightOnApi(Request $request,CacheShelfService $service)
+    public function lightOnApi(Request $request,CacheShelfService $service): array
     {
-        if($request['stationCode'] && $request['materialBoxCode'])
-           return $service->createStationTask($request['stationCode'],$request['materialBoxCode']);
+        if($request['stationCode'] && $request['materialBoxCode']){
+            return  $service->bindMaterialBox($request['stationCode'],$request['materialBoxCode']);
+        }
         return ['success' => false,'message' => '参数错误'];
     }
 
     /**
      * @param Request $request
+     * @param CacheShelfService $service
      * @return array|bool[]
      */
-    public function clearTaskApi(Request $request): array
+    public function clearTaskApi(Request $request,CacheShelfService $service): array
     {
         $code = $request['station'];
-        return app(CacheShelfService::class)->clearTask($code);
+        return $service->clearTask($code);
     }
 
 }

+ 3 - 3
app/Http/Controllers/ControlPanelController.php

@@ -51,7 +51,7 @@ class ControlPanelController extends Controller
         $end = Carbon::parse($request->end)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->end;
         $ownerIds=$request->owner_ids;
         if (!$ownerIds || in_array('all',$ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
-        $orderCountingRecords = $orderCountingRecordService->orderCountingRecords($start, $end, $request->unit, $ownerIds);
+        $orderCountingRecords = $orderCountingRecordService->getOrderCountingRecordsApi($start, $end, $request->unit, $ownerIds);
         return compact('orderCountingRecords');
     }
 
@@ -65,7 +65,7 @@ class ControlPanelController extends Controller
         $end = Carbon::parse($request->end)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->end;
         $ownerIds=$request->input('owner_ids');
         if (!$ownerIds || in_array('all',$ownerIds)) $ownerIds = $this->getCountingOwnerIds(null);
-        $logisticsCountingRecords = $orderCountingRecordService->logisticsCountingRecords($start, $end, $ownerIds);
+        $logisticsCountingRecords = $orderCountingRecordService->getLogisticRecordsApi($start, $end, $ownerIds);
         return compact('logisticsCountingRecords');
     }
 
@@ -78,7 +78,7 @@ class ControlPanelController extends Controller
         $start = Carbon::parse($request->start)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->start;
         $end = Carbon::parse($request->end)->gt(Carbon::now()) ? Carbon::now()->toDateString() : $request->end;
         $ownerIds = $this->getCountingOwnerIds(null);
-        $warehouseCountingRecords = $orderCountingRecordService->warehouseCountingRecords($start, $end, $ownerIds);
+        $warehouseCountingRecords = $orderCountingRecordService->getWareHouseRecordsApi($start, $end, $ownerIds);
         return compact('warehouseCountingRecords');
     }
 

+ 2 - 1
app/Http/Controllers/DeliveryAppointmentController.php

@@ -35,7 +35,8 @@ class DeliveryAppointmentController extends Controller
 
         $warehouses = Warehouse::query()->select("id","name")->get();
         $owners = app("OwnerService")->getIntersectPermitting();
-        return view("store.deliveryAppointment.list",compact("list","warehouses","owners"));
+        $params = request()->input();
+        return view("store.deliveryAppointment.list",compact("list","warehouses","owners","params"));
     }
 
     public function appointment()

+ 50 - 12
app/Http/Controllers/DischargeTaskController.php

@@ -7,11 +7,16 @@ use App\Facilitator;
 use App\DischargeTask;
 use App\Filters\DischargeTaskFilters;
 use App\Http\Requests\DischargeTask\DischargeTaskRequest;
+use App\Imports\CommodityImport;
+use App\Imports\DischargeTaskImport;
+use App\Owner;
 use App\Services\common\ExportService;
 use App\Services\OwnerService;
 use App\Warehouse;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Gate;
+use Maatwebsite\Excel\Facades\Excel;
 use Oursdreams\Export\Export;
 use function Sodium\compare;
 
@@ -25,13 +30,18 @@ class DischargeTaskController extends Controller
         if (!Gate::allows('人事管理-卸货-查询')) {
             return redirect(url('/'));
         }
+        if(Gate::allows('人事管理-卸货-货主可见全部')){
+            $owners = Owner::query()->get();
+            $dischargeTasks = DischargeTask::query()->with(['facilitator', 'owner', 'warehouse'])->filter($filters)->orderByDesc('income_at')->paginate($request['paginate'] ?? 50);
+        }else{
+            $owners = app(OwnerService::class)->getAuthorizedOwners();
+            $dischargeTasks = DischargeTask::query()->with(['facilitator', 'owner', 'warehouse'])->filter($filters)->whereIn('owner_id',data_get($owners,'*.id'))->orderByDesc('income_at')->paginate($request['paginate'] ?? 50);
+        }
 
-        $dischargeTasks = DischargeTask::query()->with(['facilitator', 'owner','warehouse'])->filter($filters)->orderByDesc('id')->paginate($request['paginate'] ?? 50);
-        $owners = app(OwnerService::class)->getAuthorizedOwners();
-        $warehouses = Warehouse::query()->select('id','name')->get();
+        $warehouses = Warehouse::query()->select('id', 'name')->get();
         $facilitators = Facilitator::query()->select('name', 'id')->get();
 
-        return view('personnel.discharge.task.index', compact('dischargeTasks', 'owners', 'facilitators','warehouses'));
+        return view('personnel.discharge.task.index', compact('dischargeTasks', 'owners', 'facilitators', 'warehouses'));
     }
 
     // 结算报表
@@ -41,7 +51,7 @@ class DischargeTaskController extends Controller
             return redirect(url('/'));
         }
 
-        $dischargeStatements = DischargeTask::query()->with('facilitator')->filter($filters)->orderByDesc('id')->paginate($request['paginate'] ?? 50);
+        $dischargeStatements = DischargeTask::query()->with('facilitator')->filter($filters)->orderByDesc('income_at')->paginate($request['paginate'] ?? 50);
         $owners = app(OwnerService::class)->getAuthorizedOwners();
         $facilitators = Facilitator::query()->select('name', 'id')->get();
 
@@ -115,13 +125,17 @@ class DischargeTaskController extends Controller
     {
         $this->gate('人事管理-卸货-查询');
 
-        $dischargeTasks = DischargeTask::query()->with(['Facilitator', 'owner'])->filter($filters)->orderByDesc('id')->get();
+        if(Gate::allows('人事管理-卸货-货主可见全部')){
+            $dischargeTasks = DischargeTask::query()->with(['Facilitator', 'owner'])->filter($filters)->orderByDesc('id')->get();
+        }else{
+            $owners = app(OwnerService::class)->getAuthorizedOwners();
+            $dischargeTasks = DischargeTask::query()->with(['Facilitator', 'owner'])->filter($filters)->whereIn('owner_id',data_get($owners,'*.id'))->orderByDesc('id')->get();
+        }
 
         $row = ['日期', '客户名称', '作业名称', '入库单号', '数量', '单位', '单价', '收费', '状态', '备注'];
         $json = app('DischargeTaskService')->getJson($dischargeTasks);
 
         return Export::make($row, $json, "卸货任务");
-        //return app(ExportService::class)->json($row, $json, "卸货任务");
     }
 
     // 结算报表下载
@@ -129,38 +143,62 @@ class DischargeTaskController extends Controller
     {
         $this->gate('人事管理-卸货-结算报表-查询');
 
-        $dischargeTasks = DischargeTask::query()->with(['facilitator', 'owner','warehouse'])->filter($filters)->orderByDesc('id')->get();
+        $dischargeTasks = DischargeTask::query()->with(['facilitator', 'owner', 'warehouse'])->filter($filters)->orderByDesc('id')->get();
 
-        $row = ['日期', '客户名称','仓库', '作业名称', '入库单号', '数量', '单位', '收入单价', '收入合计', '装卸队', '数量', '单位', '支出单价', '支出合计', '状态', '收入备注', '支出备注'];
+        $row = ['日期', '客户名称', '仓库', '作业名称', '入库单号', '数量', '单位', '收入单价', '收入合计', '装卸队', '数量', '单位', '支出单价', '支出合计', '状态', '收入备注', '支出备注'];
         $json = app('DischargeTaskService')->getStatementsJson($dischargeTasks);
 
         return Export::make($row, $json, "卸货结算报表");
         //return app(ExportService::class)->json($row, $json, "卸货结算报表");
     }
 
-    // 回执单
     public function receipt(Request $request)
     {
-        $task = DischargeTask::query()->with(['facilitator', 'owner','warehouse'])->where('id' , $request['id'])->first();
+        $task = DischargeTask::query()->with(['facilitator', 'owner', 'warehouse'])->where('id', $request['id'])->first();
         $task->type = DischargeTask::types[$task->type];
-        return view('personnel.discharge.task.receipt',compact('task'));
+        return view('personnel.discharge.task.receipt', compact('task'));
+    }
+
+    public function importApi(Request $request): array
+    {
+        $this->gate('人事管理-卸货-创建');
+
+        $extension = $request->file()['file']->getClientOriginalExtension();
+        if (in_array($extension, ['xlsx', 'xlsm', 'xltx', 'xltm', 'xls', 'xlt', 'ods', 'ots', 'slk', 'xml', 'gnumeric', 'htm', 'html', 'csv', 'tsv']))
+            return ['success' => false,'message'=>'请检查导入文件是否符合要求'];
+        $extension[0] = strtoupper($extension[0]);
+        try {
+            Excel::import(new DischargeTaskImport(), $request->file()['file']->path(), null, $extension);
+        } catch (\Exception $e) {
+            return ['success' => false, 'message' => ['请检查导入文件是否符合要求']];
+        }
+        if (Cache::has('exception')) {
+            return ['success' => false, 'errors' => Cache::get('exception')];
+        }
+        return ['success' => true];
     }
 
+
     public function show(DischargeTask $dischargeTask)
     {
     }
+
     public function edit(DischargeTask $dischargeTask)
     {
     }
+
     public function update(Request $request, DischargeTask $dischargeTask)
     {
     }
+
     public function store(Request $request)
     {
     }
+
     public function create()
     {
     }
+
     public function destroy(DischargeTask $dischargeTask)
     {
 

+ 1 - 1
app/Http/Controllers/HomeController.php

@@ -26,7 +26,7 @@ class HomeController extends Controller
     {
         if(!Gate::allows('退货管理-查询')){
             if(!Gate::allows('运输管理-运单-查询')){ return view('home');}
-            return redirect(url('waybill'));
+            return view("home");
         }
         return redirect(url('rejected/index/general'));
     }

+ 2 - 2
app/Http/Controllers/InventoryController.php

@@ -68,7 +68,7 @@ class InventoryController extends Controller
         }else return "暂时关闭,如需开启请联系管理员";
     }
     public function exportAllInventory(Request $request){
-        if(!Gate::allows("库存管理-库存")){ return redirect(url('/'));  }
+        if(!Gate::allows("库存管理-库存")){ return view("denied");  }
         if ($request->checkAllSign){
             $params = $request->input();
             unset($params['checkAllSign']);
@@ -83,7 +83,7 @@ class InventoryController extends Controller
                 "产品编码"=>"产品编码","产品条码"=>"产品条码",
                 "商品名称"=>"商品名称","属性仓"=>"属性仓",
                 "质量状态"=>"质量状态","失效日期"=>"失效日期",
-                "批号"=>"批号"
+                "批号"=>"批号","在库数量"=>"在库数量","占用数量"=>"占用数量"
             ])->direct();
         }else return "暂时关闭,如需开启请联系管理员";
     }

+ 8 - 8
app/Http/Controllers/LogisticController.php

@@ -19,7 +19,7 @@ class LogisticController extends Controller
      */
     public function index()
     {
-        if(!Gate::allows('物流公司-查询')){ return redirect(url('/'));  }
+        if(!Gate::allows('承运商-查询')){ return view("exception.authority");  }
         $logistics=Logistic::orderBy('id','desc')->paginate(35);
         return view('maintenance.logistic.index',['logistics'=>$logistics]);
     }
@@ -31,7 +31,7 @@ class LogisticController extends Controller
      */
     public function create()
     {
-        if(!Gate::allows('物流公司-录入')){ return redirect(url('/'));  }
+        if(!Gate::allows('承运商-录入')){ return view("exception.authority");  }
         return view('maintenance.logistic.create');
     }
 
@@ -43,14 +43,14 @@ class LogisticController extends Controller
      */
     public function store(Request $request)
     {
-        if(!Gate::allows('物流公司-录入')){ return redirect(url('/'));  }
+        if(!Gate::allows('承运商-录入')){ return view("exception.authority");  }
         $this->validatorCreate($request->all())->validate();
         $request->offsetSet("is_bunched",$request->input("is_bunched") ? 'Y' : 'N');
         $logistic=new Logistic($request->all());
         $logistic->save();
 
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-        return redirect('maintenance/logistic/create')->with('successTip',"成功录入物流公司“{$request->input('name')}”");
+        return redirect('maintenance/logistic/create')->with('successTip',"成功录入承运商“{$request->input('name')}”");
     }
     protected function validatorCreate(array $data)
     {
@@ -89,19 +89,19 @@ class LogisticController extends Controller
      */
     public function edit(Logistic $logistic)
     {
-        if(!Gate::allows('物流公司-编辑')){ return redirect(url('/'));  }
+        if(!Gate::allows('承运商-编辑')){ return view("exception.authority");  }
         return view('maintenance.logistic.edit',['logistic'=>$logistic]);
     }
 
     public function update(Request $request, Logistic $logistic)
     {
-        if(!Gate::allows('物流公司-编辑')){ return redirect(url('/'));  }
+        if(!Gate::allows('承运商-编辑')){ return redirect(url('/'));  }
         $this->validatorUpdate($request->all(),$logistic->id)->validate();
         $request->offsetSet("is_bunched",$request->input("is_bunched") ? 'Y' : 'N');
         $logistic->fill($request->all());
         $logistic->update();
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-        return redirect('maintenance/logistic/')->with('successTip',"成功修改物流公司“{$logistic['name']}”!");
+        return redirect('maintenance/logistic/')->with('successTip',"成功修改承运商“{$logistic['name']}”!");
     }
 
     /**
@@ -113,7 +113,7 @@ class LogisticController extends Controller
      */
     public function destroy(Logistic $logistic)
     {
-        if(!Gate::allows('物流公司-删除')){ return redirect(url('/'));  }
+        if(!Gate::allows('承运商-删除')){ return view("exception.authority");  }
         app('LogService')->log(__METHOD__,__FUNCTION__,$logistic->toJson(),Auth::user()['id']);
         $re=$logistic->delete();
         return ['success'=>$re];

+ 128 - 0
app/Http/Controllers/MenuController.php

@@ -0,0 +1,128 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Authority;
+use App\Components\AsyncResponse;
+use App\Menu;
+use App\Services\common\BatchUpdateService;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Gate;
+
+class MenuController extends Controller
+{
+    use AsyncResponse;
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\View\View
+     */
+    public function index()
+    {
+        if (!Gate::allows('基础设置-菜单')){return view("exception.authority"); }
+        return \view("maintenance.menu.index",["menus"=>Menu::query()->orderByRaw("level DESC,sequence")->get()]);
+    }
+
+    public function update()
+    {
+        $this->gate("基础设置-菜单-编辑");
+        $update = [];
+        $mapping = app("MenuService")->getMenuAndAuthorityMapping();
+        $authorityUpdate = [];
+        if (request()->has("parent_id")){
+            $update["parent_id"] = request("parent_id");
+            $authorityUpdate["parent_id"] = request("parent_id") ? ($mapping[request("parent_id")] ?? null) : null;
+        }
+        if (request()->has("level"))$update["level"] = request("level");
+        if (request()->has("name")){
+            $update["name"] = request("name");
+            $authorityUpdate["name"] = $mapping[request("name")];
+        }
+        if (request()->has("font"))$update["font"] = request("font");
+        if (request()->has("font_style"))$update["font_style"] = request("font_style");
+        if (request()->has("route"))$update["route"] = request("route");
+        if (request()->has("diff")){
+            $diff = request("diff");
+            Menu::query()->whereIn("id",request("child"))->update(["level"=>DB::raw("level - {$diff}")]);
+        }
+        if ($update && Menu::query()->where("id",request("id"))->update($update)){
+            app("MenuService")->setMenu();//重建菜单缓存
+            if ($authorityUpdate && ($mapping[request("id")] ?? null)){
+                Authority::query()->where("id",$mapping[request("id")])->update($authorityUpdate);
+                app("AuthorityService")->removeAllAuth();//移除所有用户权限缓存,这将在用户下次访问时重新建立
+            }
+        }
+        $this->success();
+    }
+
+    public function sort()
+    {
+        $this->gate("基础设置-菜单-编辑");
+        app(BatchUpdateService::class)->batchUpdate("menus",request("update"));
+        app("MenuService")->setMenu();//重建菜单缓存
+        $this->success();
+    }
+
+    //菜单更新时 刷掉全部菜单权限缓存 录入时刷掉超管权限 与 附加菜单缓存
+    public function save()
+    {
+        $id = request("id");
+        $mapping = app("MenuService")->getMenuAndAuthorityMapping();
+        if ($id){
+            $this->gate("基础设置-菜单-编辑");
+            Menu::query()->where("id",$id)->update([
+                "name" => request("name"),
+                "route" => request("route"),
+                "font" => request("font"),
+                "font_style" => request("font_style"),
+            ]);
+            if ($mapping[$id] ?? false){
+                $authority = Authority::query()->where("id",$mapping[$id])->first();
+                if ($authority->name != request("name"))$authority->update(["name"=>request("name")]);
+                app("AuthorityService")->removeAllAuth();
+            }
+            app("MenuService")->setMenu();//重建菜单缓存
+            $this->success();
+        }
+        $this->gate("基础设置-菜单-录入");
+        $menu = Menu::query()->create([
+            "name" => request("name"),
+            "route" => request("route"),
+            "font" => request("font"),
+            "font_style" => request("font_style"),
+            "parent_id" => request("parent_id"),
+            "level" => request("level"),
+        ]);
+        //暂时禁止菜单新建时补充权限 留待权限路由绑定后可开启此步骤
+        /*Authority::query()->create([
+            'name' => $menu->name,
+            'parent_id' => $mapping[$menu->parent_id] ?? null,
+            'alias_name' => $menu->name.$menu->id,
+        ]);
+        app("AuthorityService")->removeAdminAuth();//刷掉超管权限缓存*/
+        app("MenuService")->appendMenu($menu);//为菜单总缓存附加
+        $this->success($menu);
+    }
+    public function delete()
+    {
+        $this->gate("基础设置-菜单-删除");
+        $ids = request("ids");
+        $authIds = [];
+        $mapping = app("MenuService")->getMenuAndAuthorityMapping();
+        foreach ($ids as $id)if (isset($mapping[$id]))$authIds[] = $mapping[$id];
+
+        Menu::destroy($ids);
+        app("MenuService")->setMenu();//重建菜单缓存
+        if ($authIds){
+            DB::table("authority_role")->whereIn("id_authority",$authIds)->delete();
+            Authority::destroy($ids);
+            app("AuthorityService")->removeAllAuth();//移除所有用户权限缓存,这将在用户下次访问时重新建立
+        }
+        $this->success();
+    }
+
+    public function get()
+    {
+        return app("MenuService")->getVisibleFunctionList();
+    }
+}

+ 1 - 1
app/Http/Controllers/OrderCommodityAssignController.php

@@ -12,7 +12,7 @@ class OrderCommodityAssignController extends Controller
 {
     public function index()
     {
-        if(!Gate::allows('订单管理-指定分配-查询')){ return redirect(url('denied'));  }
+        if(!Gate::allows('订单管理-指定分配')){ return redirect(url('denied'));  }
         $assigns = app("OrderCommodityAssignService")->paginate();
         return view("order.index.index",compact("assigns"));
     }

+ 85 - 0
app/Http/Controllers/OwnerLogisticFeeDetailController.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\OwnerLogisticFeeDetail;
+use Illuminate\Http\Request;
+
+class OwnerLogisticFeeDetailController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\OwnerLogisticFeeDetail  $ownerLogisticFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function show(OwnerLogisticFeeDetail $ownerLogisticFeeDetail)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\OwnerLogisticFeeDetail  $ownerLogisticFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(OwnerLogisticFeeDetail $ownerLogisticFeeDetail)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\OwnerLogisticFeeDetail  $ownerLogisticFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, OwnerLogisticFeeDetail $ownerLogisticFeeDetail)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\OwnerLogisticFeeDetail  $ownerLogisticFeeDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(OwnerLogisticFeeDetail $ownerLogisticFeeDetail)
+    {
+        //
+    }
+}

+ 85 - 0
app/Http/Controllers/OwnerLogisticFeeReportController.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\OwnerLogisticFeeReport;
+use Illuminate\Http\Request;
+
+class OwnerLogisticFeeReportController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\OwnerLogisticFeeReport  $ownerLogisticFeeReport
+     * @return \Illuminate\Http\Response
+     */
+    public function show(OwnerLogisticFeeReport $ownerLogisticFeeReport)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\OwnerLogisticFeeReport  $ownerLogisticFeeReport
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(OwnerLogisticFeeReport $ownerLogisticFeeReport)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\OwnerLogisticFeeReport  $ownerLogisticFeeReport
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, OwnerLogisticFeeReport $ownerLogisticFeeReport)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\OwnerLogisticFeeReport  $ownerLogisticFeeReport
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(OwnerLogisticFeeReport $ownerLogisticFeeReport)
+    {
+        //
+    }
+}

+ 1 - 1
app/Http/Controllers/RejectedController.php

@@ -422,7 +422,7 @@ class RejectedController extends Controller
             "logistic_number"=>"原单单号","logistic_number_return"=>"退回单号","logistic_name"=>"退回公司",
             "fee_collected"=>"到付费用","loaded"=>"是否入库",
             "item_barcode"=>"商品条码","item_name"=>"商品名称",
-            "item_amount"=>"商品数量","quality_label_name"=>"商品质量","operator_name"=>"录入人"
+            "item_amount"=>"商品数量","quality_label_name"=>"商品质量","item_remark"=>"备注","operator_name"=>"录入人","remark"=>"退单备注"
         ])->direct();
     }
 

+ 64 - 130
app/Http/Controllers/RoleController.php

@@ -3,158 +3,92 @@
 namespace App\Http\Controllers;
 
 use App\Authority;
-use App\LaborCompany;
+use App\Components\AsyncResponse;
+use App\Owner;
 use App\Role;
-use Exception;
-use Illuminate\Http\Request;
-use Illuminate\Http\Response;
-use Illuminate\Support\Facades\Auth;
+use App\UserWorkgroup;
+use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
-use Illuminate\Support\Facades\Validator;
 
 class RoleController extends Controller
 {
-
-    public function index(Request $request)
+    use AsyncResponse;
+    public function index()
     {
-        if(!Gate::allows('角色-查询')){ return redirect(url('/'));  }
-        $query = Role::with('authorities');
-/*        if($request->has('user')){
-            $user = $request->input('user');
-            $query->whereHas('users',function($query) use ($user){
-                $query->where('name','like',$user);
-            });
-        }*/
-        if($request->has('role')){
-            $role=$request->input('role');
-            if (strpos($role, ',') || strpos($role, ',') || strpos($role, ' ')) {
-                $arr = array_filter(preg_split('/[,, ]+/is', $role));
-                $query->whereIn('name', $arr);
-                unset($role);
-            } else {
-                $query->where('name','like',$role.'%');
-            }
-        }
-        $roles= $query->orderBy('id','desc')->paginate(35);
-        return view('maintenance.role.index',['roles'=>$roles]);
+        if (!Gate::allows('角色-查询')){return view("exception.authority"); }
+        $roles = Role::query()->get();
+        $authorities = app("AuthorityService")->format(Authority::query()->get());
+        $owners = Owner::query()->whereNull("deleted_at")->get();
+        $userWorkGroups = UserWorkgroup::query()->get();
+        return view('maintenance.role.index',compact("roles","authorities","userWorkGroups","owners"));
     }
 
-
-    public function create()
+    /**
+     * @throws \Exception
+     */
+    public function destroy()
     {
-        if(!Gate::allows('角色-录入')){ return redirect(url('/'));  }
-        $authoritiesAll=Authority::orderBy('alias_name','desc')->get();
-        $authoritiesAll = Authority::filterRecycle($authoritiesAll);
-        $laborCompanies=LaborCompany::query()->get();
-        return view('maintenance.role.create',compact('authoritiesAll','laborCompanies'));
+        $this->gate("角色-删除");
+        /** @var Role $role */
+        $role = Role::query()->find(request("id"));
+        $role->owners()->sync([]);
+        $role->userWorkGroups()->sync([]);
+        $role->delete();
+        app("RoleService")->clearUserAuthority(request("id"),true,true,true);//清除角色下所有控制信息
+        $this->success();
     }
 
-
-    public function store(Request $request)
-    {
-        if(!Gate::allows('角色-录入')){ return redirect(url('/'));  }
-        $this->validatorCreate($request->all())->validate();
-        $role=new Role($request->all());
-        $role->save();
-        $authorityIds=$request->input('authority')??'';
-        if($authorityIds){
-            $authorityIdArr=explode(',',$authorityIds);
-            $role->authorities()->sync($authorityIdArr);
-        }
-        $laborCompanyIds=$request->input('laborCompany')??'';
-        if($laborCompanyIds){
-            $laborCompanyIdArr=explode(',',$laborCompanyIds);
-            $role->laborCompanies()->sync($laborCompanyIdArr);
-        }else{
-            $role->laborCompanies()->sync([]);
-        }
-
-        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-        return redirect('maintenance/role/create')->with('successTip',"成功录入角色“{$request->input('name')}”");
-    }
-    protected function validatorCreate(array $data)
-    {
-        return Validator::make($data, [
-            'name' => ['required', 'string', 'max:50', 'unique:roles'],
-        ]);
-    }
-    protected function validatorUpdate(array $data)
+    public function save()
     {
-        return Validator::make($data, [
-            'name' => ['required', 'string', 'max:50'],
-        ]);
+        $this->gate("角色-录入");
+        $id = request("id");
+        $name = request("name");
+        $role = null;
+        if ($id)Role::query()->where("id",$id)->update(["name"=>$name]);
+        else $role = Role::query()->create(["name"=>$name]);
+        $this->success($role);
     }
-    /**
-     * Display the specified resource.
-     *
-     * @param Role $role
-     * @return Response
-     */
-    public function show(Role $role)
+
+    public function loadRelevance()
     {
-        //
+        $this->gate("角色-编辑");
+        $authorities = array_column(DB::select(DB::raw("SELECT id_authority FROM authority_role WHERE id_role = ?"),[request("id")]),"id_authority");
+        $owners = array_column(DB::select(DB::raw("SELECT owner_id FROM owner_role WHERE role_id = ?"),[request("id")]),"owner_id");
+        $userWorkGroups = array_column(DB::select(DB::raw("SELECT user_work_group_id FROM role_user_work_group WHERE role_id = ?"),[request("id")]),"user_work_group_id");
+        $this->success(compact("authorities","owners","userWorkGroups"));
     }
 
-    /**
-     * Show the form for editing the specified resource.
-     *
-     * @param Role $role
-     * @return Response
-     */
-    public function edit(Role $role)
+    public function saveAuthority()
     {
-        if(!Gate::allows('角色-编辑')){ return redirect(url('/'));  }
-        $authoritiesAll=Authority::orderBy('alias_name','desc')->get();
-        $authoritiesAll = Authority::filterRecycle($authoritiesAll);
-        $authorities=$role->authorities()->get();
-        $laborCompanies=LaborCompany::query()->get();
-        $laborCompaniesRole=$role->laborCompanies()->get();
-        return view('maintenance.role.edit',compact('role','authorities','authoritiesAll','laborCompanies','laborCompaniesRole'));
+        $this->gate("角色-编辑");
+        /** @var Role|\stdClass $role */
+        $role = new Role();
+        $role->id = request("id");
+        $role->authorities()->sync(request("authorities"));
+        app("RoleService")->clearUserAuthority($role->id);
+        $this->success();
     }
 
-    /**
-     * Update the specified resource in storage.
-     *
-     * @param Request $request
-     * @param Role $role
-     * @return Response
-     */
-    public function update(Request $request, Role $role)
+    public function saveOwner()
     {
-        if(!Gate::allows('角色-编辑')){ return redirect(url('/'));  }
-        $this->validatorUpdate($request->all())->validate();
-        $role->fill($request->all());
-        $role->update();
-        $authorityIds=$request->input('authority')??'';
-        if($authorityIds){
-            $authorityIdArr=explode(',',$authorityIds);
-            $role->authorities()->sync($authorityIdArr);
-        }else{
-            $role->authorities()->sync([]);
-        }
-        $laborCompanyIds=$request->laborCompany??'';
-        if($laborCompanyIds){
-            $laborCompanyIdArr=explode(',',$laborCompanyIds);
-            $role->laborCompanies()->sync($laborCompanyIdArr);
-        }else{
-            $role->laborCompanies()->sync([]);
-        }
-        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-        return redirect('maintenance/role/')->with('successTip',"成功修改角色“{$role['name']}”!");
+        $this->gate("角色-编辑");
+        /** @var Role|\stdClass $role */
+        $role = new Role();
+        $role->id = request("id");
+        $role->owners()->sync(request("owners"));
+        app("RoleService")->clearUserAuthority($role->id,false,true);
+        $this->success();
     }
 
-    /**
-     * Remove the specified resource from storage.
-     *
-     * @param Role $role
-     * @return array|Response
-     * @throws Exception
-     */
-    public function destroy(Role $role)
+    public function saveUserWorkGroup()
     {
-        if(!Gate::allows('角色-删除')){ return redirect(url('/'));  }
-        app('LogService')->log(__METHOD__,__FUNCTION__,$role->toJson(),Auth::user()['id']);
-        $re=$role->delete();
-        return ['success'=>$re];
+        $this->gate("角色-编辑");
+        /** @var Role|\stdClass $role */
+        $role = new Role();
+        $role->id = request("id");
+        $role->userWorkGroups()->sync(request("userWorkGroups"));
+        app("RoleService")->clearUserAuthority($role->id,false,false,true);
+        $this->success();
     }
+
 }

+ 162 - 146
app/Http/Controllers/StorageController.php

@@ -2,14 +2,17 @@
 
 namespace App\Http\Controllers;
 
+use App\CommodityMaterialBoxModel;
 use App\Components\AsyncResponse;
 use App\MaterialBox;
-use App\Services\LogService;
 use App\Station;
 use App\StationTask;
 use App\StationTaskMaterialBox;
 use App\Storage;
-use App\ValueStore;
+use App\StoreItem;
+use App\TaskTransaction;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 
@@ -30,161 +33,80 @@ class StorageController extends Controller
         $box = MaterialBox::query()->select("id")->where("code",$ide)->first();
         if (!$box)$this->error("WAS无此料箱");
 
+        //库存相关信息
+        /** @var Station|\stdClass $station */
+        $station = Station::query()->firstOrCreate(["code"=>$fromLocation],[
+            'name' => $fromLocation, 'code' => $fromLocation, 'station_type_id' => 5
+        ]);
+        $item = StoreItem::query()->whereHas("store",function (Builder $query){
+            $query->where("asn_code",request("asn"));
+        })->whereHas("commodity",function (Builder $query)use($barCode){
+            $query->whereHas("barcodes",function (Builder $query)use($barCode){
+                $query->where("code",$barCode);
+            });
+        })->first();
         //get flux
-        $sql = <<<sql
-SELECT * FROM DOC_ASN_DETAILS LEFT JOIN BAS_SKU ON DOC_ASN_DETAILS.CUSTOMERID = BAS_SKU.CUSTOMERID AND DOC_ASN_DETAILS.SKU = BAS_SKU.SKU
-LEFT JOIN TSK_TASKLISTS ON DOC_ASN_DETAILS.ASNNO = TSK_TASKLISTS.DOCNO AND DOC_ASN_DETAILS.ASNLINENO = TSK_TASKLISTS.DOCLINENO
-WHERE ASNNO = ? AND (ALTERNATE_SKU1 = ? OR ALTERNATE_SKU2 = ? OR ALTERNATE_SKU3 = ?) AND RECEIVEDQTY >= ?
-  AND TASKPROCESS = '00' AND TASKTYPE = 'PA'
-sql;
-        $asns = DB::connection("oracle")->select(DB::raw($sql),[$asn,$barCode,$barCode,$barCode,$amount]);
+        $asns = app("StorageService")->getFluxTask($asn,$barCode,$amount);
         if (!$asns)$this->error("ASN不存在或上架数量与入库数量不符");
-        $nums = [];
-        $result = null;
-        foreach ($asns as $index=>$asn){
-            if ((int)$asn->fmqty == $amount){$result=$index;break;}
-            $nums[] = (int)$asn->fmqty;
-        }
-        //flux上架
-        if ($result!==null)$this->fluxPA($asns[$result],$ide,$amount);
-        else{
-            $result = $this->twoSum($nums,$amount);
-            if (!$result)$this->error("无法匹配入库记录,检查您的上架数量");
-            DB::connection("oracle")->transaction(function ()use($result,$asns,$ide){
-                foreach ($result as $index){
-                    $this->fluxPA($asns[$index],$ide,(int)$asns[$index]->fmqty);
-                }
+        //此处嵌套三层事务 以最高层级为准
+        DB::beginTransaction(); //总体事务 回滚WAS错误操作
+        try{
+            //建立入库任务
+            if (!app("StorageService")->putWareHousing($fromLocation,$box->id))$this->error("错误库位或库位已被下达任务");
+            //库存记录
+            app("StorageService")->enterWarehouse($station->id, $box->id, $item->commodity_id ?? null, $amount, $box->material_box_model_id);
+
+            DB::connection("oracle")->transaction(function ()use($asns,$ide){ //单体嵌套事务 回滚FLUX失败任务
+                foreach ($asns as $asn)if (!app("StorageService")->fluxPA($asn,$ide,(int)$asn->fmqty)){
+                    DB::connection("oracle")->rollBack();
+                    $this->error("FLUX上架失败");
+                };
             });
+            DB::commit();
+        }catch (\Exception $e){
+            DB::rollBack();
+            $this->error($e->getMessage());
         }
         //亮灯
         app("CacheShelfService")->_stationCacheLightOn($fromLocation,$ide);
-        //建立入库任务
-        if (!app("ForeignHaiRoboticsService")->putWareHousing($fromLocation,'',$box->id))$this->error("错误库位或库位已被下达任务");
-        //占用库位 应在任务完成后释放
-        app("StorageService")->markOccupy($fromLocation);
-        $this->success();
+
+        $maximum = app("CommodityMaterialBoxModelService")->getMaximum($box->material_box_model_id,$item->commodity_id ?? null);
+        if ($maximum && $maximum<$amount)app("CommodityMaterialBoxModelService")->setMaximum($box->material_box_model_id,$item->commodity_id ?? null,$amount);
+        $this->success(["model" => $box->material_box_model_id,"commodity" => $item->commodity_id ?? null, "maximum" => $maximum]);
     }
 
-    public function fluxPA($asn,$ide,$amount)
+    public function setMaximum()
     {
-        if (!$asn->taskid)$this->error("ASN单无此入库信息,禁止上架");
-
-        $sql = <<<sql
-SELECT * FROM inv_lot_loc_id  WHERE lotnum = ? AND traceid = ? AND customerid= ?  and sku = ?
-sql;
-        $inv = DB::connection("oracle")->select(DB::raw($sql),[$asn->fmlotnum,$asn->plantoid,$asn->customerid,$asn->sku]);
-        if (count($inv)==0)$this->error("余量与入库不符");
-        DB::connection("oracle")->transaction(function ()use($inv,$amount,$ide,$asn,&$who){
-            $db = DB::connection("oracle");
-            $qty = $amount;
-            foreach ($inv as $in){
-                if ($qty==0)break;
-                if ($in->qty > $qty){
-                    $db->update(DB::raw("update inv_lot_loc_id set qty = qty-?,qtymvout = qty-? where lotnum = ? and locationid = ? and traceid = ?"),[
-                        $qty,$qty,$in->lotnum,$in->locationid,$in->traceid
-                    ]);//TODO 遗留问题:对应生成分配库位上架数量未被变更
-                    $in->qty = $in->qty-$qty;
-                    $qty = 0;
-                }else{
-                    $db->delete(DB::raw("DELETE FROM inv_lot_loc_id WHERE lotnum = ? and locationid = ? and traceid = ?"),[
-                        $in->lotnum,$in->locationid,$in->traceid
-                    ]);
-                    $qty = $qty-$in->qty;
-                }
-            }
-            $db->delete(DB::raw("DELETE FROM inv_lot_loc_id WHERE lotnum = ? AND traceid = ? AND traceid != '*'  AND qty = 0"),[
-                $inv[0]->lotnum,$inv[0]->traceid
-            ]);
-            $invHistory = $db->selectOne(DB::raw("SELECT * FROM inv_lot_loc_id WHERE lotnum = ? AND locationid = ? AND customerid = ? AND sku = ? AND traceid = '*' FOR UPDATE"),[
-                $inv[0]->lotnum,$ide,$inv[0]->customerid,$inv[0]->sku
-            ]);
-            $who = 'WAS'.(Auth::user() ? '-'.Auth::user()["name"] : '');
-            if ($invHistory)$db->update(DB::raw("UPDATE inv_lot_loc_id SET qty = qty+? WHERE lotnum = ? AND locationid = ? AND traceid = '*'"),[
-                (int)$amount,$inv[0]->lotnum,$ide
-            ]);
-            else $db->insert(DB::raw("INSERT INTO inv_lot_loc_id VALUES(?,?,'*',?,?,?,0,0,0,0,0,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,0,0,0,0,0,'*',0,null)"),[
-                $inv[0]->lotnum,$ide,$inv[0]->customerid,$inv[0]->sku,$amount,date("Y-m-d H:i:s"),$who,
-                date("Y-m-d H:i:s"),$who
-            ]);
-            $sql = <<<sql
-INSERT INTO ACT_TRANSACTION_LOG VALUES(?,'PA',?,?,?,?,'ASN',?,?,?,?,?,?,?,?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,
-TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,0,0,0,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,?,null,null,null,'*',?,?,?,?,?,?,?,
-?,?,?,?,?,'N',null,?,?,?,?,?,?,?,null,null)
-sql;
-            $trid = $this->getTrNumber();
-            $db->insert(DB::raw($sql),[
-                $trid,$asn->customerid,$asn->sku,
-                $asn->asnno,$asn->asnlineno,$inv[0]->lotnum,$asn->fmlocation,$asn->plantoid,$asn->packid,$asn->uom,$amount,$amount,'99',date("Y-m-d H:i:s"),$who,
-                date("Y-m-d H:i:s"),$who,date("Y-m-d H:i:s"),$asn->customerid,$asn->sku,$ide,$who,$asn->packid,$asn->uom,$amount,$amount,$inv[0]->lotnum,
-                '*','0','N','*',$asn->taskid_sequence,$asn->warehouseid,$asn->userdefine1,$asn->userdefine2,
-                $asn->userdefine3,$asn->userdefine4,$asn->userdefine5,'O'
-            ]);
-            $this->setTrNumber();
-            $sql = <<<sql
-update TSK_TASKLISTS set TASKPROCESS = '99',REASONCODE = 'OK',PLANTOLOCATION = ?,PLANLOGICALTOSEQUENCE = ?,
-CREATE_TRANSACTIONID = ?,OPENWHO = ?,OPENTIME = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),
- CLOSEWHO = ?,CLOSETIME = ?,EDITTIME = ?,EDITWHO = ?
- where taskid = ? AND TASKID_SEQUENCE = ?
-sql;
-            $db->update(DB::raw($sql),[
-                $ide,$ide,$trid,$who,date("Y-m-d H:i:s"),$who,date("Y-m-d H:i:s"),date("Y-m-d H:i:s"),$who,$asn->taskid,$asn->taskid_sequence
-            ]);
-        });
-        //成功后应去修改ASN状态及数量 暂时不知上架后ASN应为状态
-        /*        $sql = <<<sql
-        UPDATE doc_asn_details SET linestatus = ?,edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ? AND asnlineno = ?
-        sql;*/
-        //if ($asn->expectedqty>$asn->receivedqty && $asn->linestatus!='30')DB::connection("oracle")->update(DB::raw($sql),['30',date("Y-m-d H:i:s"),$who,$asn->asnno,$asn->asnlineno]);
-        if ($asn->expectedqty==$asn->receivedqty && $asn->linestatus=='40'){
-            //DB::connection("oracle")->update(DB::raw($sql),['40',date("Y-m-d H:i:s"),$who,$asn->asnno,$asn->asnlineno]);
-            $check = DB::connection("oracle")->selectOne(DB::raw("SELECT 1 FROM DOC_ASN_DETAILS WHERE ASNNO = ? AND LINESTATUS != '40'"),[$asn->asnno]);
-            if (!$check){
-                $logs = DB::connection("oracle")->select(DB::raw("SELECT SUM(FMQTY) qty,TRANSACTIONTYPE FROM ACT_TRANSACTION_LOG WHERE DOCNO = ? AND TRANSACTIONTYPE IN ('PA','IN') GROUP BY TRANSACTIONTYPE"),[$asn->asnno]);
-                $paQty = 0;
-                $inQty = 0;
-                foreach ($logs as $log){
-                    if ($log->transactiontype == 'IN')$inQty = $log->qty;
-                    else $paQty = $log->qty;
-                }
-                if ($paQty == $inQty){
-                    DB::connection("oracle")->update(DB::raw("UPDATE DOC_ASN_HEADER SET asnstatus = '99',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
-                        [date("Y-m-d H:i:s"),$who,$asn->asnno]);
-                    DB::connection("oracle")->update(DB::raw("UPDATE DOC_ASN_DETAILS SET linestatus = '99',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
-                        [date("Y-m-d H:i:s"),$who,$asn->asnno]);
-                }
-            }
-        }
+        app("CommodityMaterialBoxModelService")->setMaximum(request("model"),request("commodity"),request("maximum"));
+        $this->success();
     }
 
     /**
-     * @param Integer[] $nums
-     * @param Integer $target
-     * @return Integer[]|null
+     * 检查最大限值并返回
+     *
      */
-    function twoSum($nums, $target) {
-        $map=[];
-        for($i=0;$i<count($nums);$i++){
-            $complement=$target-$nums[$i];
-            if(array_key_exists($complement,$map)){
-                return [$map[$complement],$i];
-            }
-            $map[$nums[$i]]=$i;
-        }
-        return null;
-    }
-
-    function getTrNumber()
-    {
-        $val = ValueStore::query()->select("value")->where("name","flux_tr_number")->first();
-        if (!$val)$val = ValueStore::query()->create(["name"=>"flux_tr_number","value"=>'0']);
-        $max = $val->value+1;
-        $number = sprintf("%09d", $max);
-        return 'W'.$number;
-    }
-
-    function setTrNumber()
+    public function checkMaximum()
     {
-        ValueStore::query()->select("value")->where("name","flux_tr_number")->update(["value"=>DB::raw("flux_tr_number+1")]);
+        $item = StoreItem::query()->whereHas("store",function (Builder $query){
+            $query->where("asn_code",request("asn"));
+        })->whereHas("commodity",function (Builder $query){
+            $query->whereHas("barcodes",function (Builder $query){
+                $query->where("code",request("barCode"));
+            });
+        })->first();
+        if (!$item)$this->error("WAS无此单据记录");
+        $models = CommodityMaterialBoxModel::query()->where("commodity_id",$item->commodity_id)->get();
+        if ($models->count()==0)$this->error("商品首入,请使用缓存架空箱入库");
+        foreach ($models as $model){
+            $box = Storage::query()->select(DB::raw("MAX({$model->maximum}-amount) need"),"material_box_id")
+                ->whereHas("materialBox",function (Builder $query)use($model){
+                $query->where("material_box_model_id",$model->material_box_model_id);
+            })->where("commodity_id",$model->commodity_id)->where("amount","<",$model->maximum)
+                ->where("status",0)->first();
+            $box->commodity_id = $item->commodity_id;
+            if ($box)$this->success($box);
+        }
+        $this->success(["need"=>$models[0]->maximum,"material_box_model_id"=>$models[0]->material_box_model_id,"commodity_id"=>$item->commodity_id]);
     }
 
     /**
@@ -213,12 +135,106 @@ sql;
         StationTask::query()->where("status","!=",'完成')->whereIn("station_id",$station)->update([
             "status" => "完成"
         ]);
-        //清理库存
         Storage::query()->whereIn("station_id",$station)->update([
-            "status" => 0,"material_box_id" => null, "commodity_id" => null, "amount" => 0,
+            "status" => 1,
+            "station_id" => null,
         ]);
         //重新调取料箱
-        app("StorageService")->paddingCacheShelf($station->get());
+        if (!app("ForeignHaiRoboticsService")->paddingCacheShelf(Station::query()->whereIn("code",$boxes)->get()))$this->error("已无可用料箱,部分库位填充失败");
         $this->success(["data"=>$data,"boxes"=>$boxes]);
     }
+
+    /**
+     * 取得料箱
+     */
+    public function acquireBox()
+    {
+        $boxId = request("material_box_id");
+        $modelId = request("material_box_model_id");
+        //获取目标库位
+        $station = app("StationService")->getMirrorMappingLocation(request("station"));
+        if (!$station)$this->error("未知库位");
+        //获取料箱
+        if ($boxId && !app("MaterialBoxService")->checkUsableBox($boxId)){
+            $boxId = null;
+            //料箱存在且不可用
+            $models = CommodityMaterialBoxModel::query()->where("commodity_id",request("commodity_id"))->get();
+            foreach ($models as $model){
+                Storage::query()->select("material_box_id")
+                    ->whereHas("materialBox",function (Builder $query)use($model){
+                        $query->where("material_box_model_id",$model->material_box_model_id);
+                    })->where("commodity_id",$model->commodity_id)->where("amount","<",$model->maximum)
+                    ->where("status",0)->where(DB::raw("{$model->maximum}-amount"),">=",request("amount"))->get()->each(function ($box)use(&$boxId){
+                        if (app("MaterialBoxService")->checkUsableBox($box->id)){
+                            $boxId = $box->id;
+                            return true;
+                        }
+                        return false;
+                    });
+                if ($boxId)break;
+            }
+        }
+        if (!$boxId){
+            if (!$modelId){
+                $box = null;
+                $models = CommodityMaterialBoxModel::query()->where("commodity_id",request("commodity_id"))->get();
+                foreach ($models as $model){
+                    $box = app("MaterialBoxService")->getAnEmptyBox([],$model->material_box_model_id);
+                    if($box)break;
+                }
+            }else $box = app("MaterialBoxService")->getAnEmptyBox([],$modelId);
+            if (!$box)$this->error("无可用料箱");
+            $boxId = $box->id;
+        }
+        //发起取箱任务
+        $collection = new Collection();
+        $task = StationTask::query()->create([
+            'status' => "待处理",
+            'station_id' => $station->id,
+        ]);
+        $collection->add(StationTaskMaterialBox::query()->create([
+            'station_id' => $station->id,
+            'material_box_id'=>$boxId,
+            'status'=>"待处理",
+            'type' => '取',
+            'station_task_id' => $task->id,
+        ]));
+        if (!app("ForeignHaiRoboticsService")->fetchGroup($station->code,$collection,'','立架出至缓存架'))$this->error("呼叫机器人失败");
+        //生成临时任务事务
+        TaskTransaction::query()->create([
+            "doc_code" => request("asn"),
+            "bar_code" => request("barCode"),
+            "fm_station_id" => $station->id,
+            "material_box_id" => $boxId,
+            "commodity_id" => request("commodity_id"),
+            "amount" => request("amount"),
+            "type" => "入库",
+            "user_id" => Auth::id(),
+            "mark" => 1
+        ]);
+        //亮灯
+        app("CacheShelfService")->stationLightUp($station->code,null,'2');
+        $this->success();
+    }
+
+    /**
+     * 溢出校正
+     */
+    public function overflowRevision()
+    {
+        $station = request("station");
+        $amount = request("amount");
+        //获取目标库位
+        $station = app("StationService")->getMirrorMappingLocation($station);
+        if (!$station)$this->error("未知库位");
+        $task = TaskTransaction::query()->with("materialBox")->where("fm_station_id",$station->id)->where("amount",">",$amount)
+            ->where("type","入库")->where("mark",1)->where("status",0)->first();
+        if (!$task)$this->error("无任务存在");
+        $task->update(["amount" => DB::raw("amount - {$amount}")]);
+        $storage = Storage::query()->where("material_box_id",$task->material_box_id)->first();
+        $maximum = (($storage->amount ?? 0)+$task->amount)-$amount;
+        CommodityMaterialBoxModel::query()->where("material_box_model_id",$task->materialBox->material_box_model_id)
+            ->where("commodity_id",$task->commodity_id)->update(["maximum"=>$maximum]);
+        $this->success("校正成功");
+    }
 }

+ 8 - 0
app/Http/Controllers/StoreController.php

@@ -446,4 +446,12 @@ class StoreController extends Controller
         })->get();
         return \view("store.inStorage.cacheRackStorage",compact("storages"));
     }
+
+    /**
+     * 缓存架半箱入库
+     */
+    public function halfChestStorage()
+    {
+        return \view("store.inStorage.halfChestStorage");
+    }
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 88 - 32
app/Http/Controllers/TestController.php


+ 4 - 4
app/Http/Controllers/WaybillController.php

@@ -53,7 +53,7 @@ class WaybillController extends Controller
      */
     public function index(Request $request,OwnerService $ownerService,LogisticService $logisticService)
     {
-        if(!Gate::allows('运输管理-运单-查询')){ return view("transport.waybill.authorityMenu");  }
+        if(!Gate::allows('运输管理-运单-查询')){ return view("exception.authority");  }
         $paginateParams = $request->input();
         $waybills=app('waybillService')->paginate($request->input());
         return view('transport.waybill.index', [
@@ -68,7 +68,7 @@ class WaybillController extends Controller
 
     public function create(Request $request,OwnerService $ownerService)
     {
-        if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('denied'));  }
         $type=$request->type ?? "";
         if ($type==='ZF')$type='直发车';
         if ($type==='ZX')$type='专线';
@@ -77,7 +77,7 @@ class WaybillController extends Controller
 
     public function store(Request $request)
     {
-        if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('denied'));  }
         $this->validatorWaybill($request,false)->validate();
         /** @var WaybillService */
         $waybill=app('waybillService')->store($request);
@@ -86,7 +86,7 @@ class WaybillController extends Controller
 
     public function edit($id,LogisticService $logisticService,CarTypeService $carTypeService,UnitService $unitService)
     {
-        if(!Gate::allows('运输管理-编辑')){ return redirect(url('/'));  }
+        //if(!Gate::allows('运输管理-编辑')){ return redirect(url('denied'));  }
         $waybill = app('waybillService')->find($id);
         if ($waybill->order_id){
             /** @var Waybill $waybill */

+ 1 - 1
app/Http/Controllers/WaybillFinancialExceptedController.php

@@ -25,7 +25,7 @@ class WaybillFinancialExceptedController extends Controller
     }
     public function index(Request $request)
     {
-        if(!Gate::allows('财务报表-查询')){ return redirect(url('/'));  }
+        if(!Gate::allows('财务报表')){ return redirect(url('/'));  }
         $waybillFinancialSnapshots=WaybillFinancialExcepted::query()->orderBy('id', 'DESC');
         $type='';
         if ($request->type=='ZF'){

+ 2 - 2
app/Http/Controllers/WaybillFinancialSnapshotsController.php

@@ -28,7 +28,7 @@ class WaybillFinancialSnapshotsController extends Controller
     }
     public function index(Request $request)
     {
-        if(!Gate::allows('财务报表-查询')){ return redirect(url('/'));  }
+        if(!Gate::allows('财务报表')){ return redirect(url('/'));  }
         $waybillFinancialSnapshots=WaybillFinancialSnapshot::query()->orderBy('id', 'DESC');
         $type='';
         if ($request->type=='ZF'){
@@ -43,7 +43,7 @@ class WaybillFinancialSnapshotsController extends Controller
         return view('transport.waybill.waybillFinancialSnapshot.index',['waybillFinancialSnapshots'=>$waybillFinancialSnapshots,'filterData'=>$request->input(),'type'=>$type]);
     }
     public function export(Request $request){
-        if(!Gate::allows('财务报表-查询')){ return '没有权限';  }
+        if(!Gate::allows('财务报表')){ return '没有权限';  }
         if ($request->checkAllSign){
             $param = $request->input();
             unset($param['checkAllSign']);

+ 21 - 254
app/Http/Controllers/api/thirdPart/goodscan/PackageController.php

@@ -3,95 +3,48 @@
 
 namespace App\Http\Controllers\api\thirdPart\goodscan;
 
-use App\Events\WeighedEvent;
-use App\Http\Controllers\LogisticNumberFeatureController;
-use App\Jobs\WeightUpdateInstantBill;
-use App\MeasuringMachine;
-use App\OracleDOCOrderHeader;
-use App\Order;
-use App\OrderPackage;
 use App\Services\LogService;
-use App\Services\OrderService;
-use App\Waybill;
-use Carbon\Carbon;
+use App\Services\weight\GoodScanWeightService;
 use Illuminate\Http\Request;
+use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Validator;
 
 class PackageController
 {
     public function new_(Request $request)
     {
-        app('LogService')->log(__METHOD__,'GoodScan weightApi add'.__FUNCTION__,json_encode($request->getContent()));
+        app('LogService')->log(__METHOD__, 'GoodScan weightApi add' . __FUNCTION__, json_encode($request->getContent()));
         $requestInput = [];
-        foreach ($request->input() as $key=>$item) {
+        foreach ($request->input() as $key => $item) {
             $requestInput[strtolower($key)] = $item;
         }
 
         $errors = $this->validatorWeight($requestInput)->errors(); // 参数校验
-        $weight = $requestInput['weight']??'';
-        if($weight == '-9.9'){   // 称重异常校验
-            app('LogService')->log(__METHOD__,'GoodScan weightApi (Error)'.__FUNCTION__,'异方接口称重伤上传异常[异常值为-9.9,电子秤故障或未连接]'.json_encode($request->getContent()));
-            return json_encode(['code'=>500,'error'=>'weight=-9.9']);
-        }
-        if(count($errors) > 0){
-            app('LogService')->log(__METHOD__,'error'.__FUNCTION__,json_encode($request->getContent()).'||'.json_encode($errors),null);
-            return json_encode(['code'=>500,'error'=>$errors]);
-        }
 
-        /**
-         * @var MeasuringMachine $measuringMachine
-         * @var OrderPackage $orderPackage
-         * @var OracleDOCOrderHeader $orderHeader
-         * @var Order $order
-         */
+        $weight = $requestInput['weight'] ?? '';
 
-        $measuringMachine = $this->getMeasuringMachine($requestInput['hid']); // 返回设备并启动
-        $orderPackage=$this->getOrderPackageByLogisticNumber($requestInput['code']); // 查询WAS是否有对应的包裹信息
-        if($orderPackage){
-            $result = $this->updateOrderPackage($orderPackage,$requestInput,$measuringMachine); // 更新包裹信息
-            if($result){
-                return json_encode($result);
-            }
-        }else{
-            try {
-                $orderHeader = $this->findOrderHeaderByLogisticNumber($requestInput['code']);// 查询WMS是否有对应的包裹信息
-                if (!$orderHeader) {
-                    return json_encode(['code' => 500, 'error' => '保存时发生错误(未在WMS中找到订单)!'], JSON_UNESCAPED_UNICODE);
-                }
-                $order = $this->createOrderByOrderHeader($orderHeader);
-                $orderPackage = $this->getOrderPackage($requestInput, $measuringMachine, $order);// 返回包裹对象
-                $this->syncOrderPackageLogistic($orderPackage);// 同步包裹订单的承运商
-            } catch (\Exception $e) {
-                app('LogService')->log(__METHOD__,__FUNCTION__,'GoodScan weightApi (Error)'.json_encode($request->getContent()).'||'.json_encode($orderPackage),null);
-                return json_encode(["code"=>500,"error"=>"写入WMS失败!"],JSON_UNESCAPED_UNICODE);
-            }
+        if ($weight == '-9.9') {   // 称重异常校验
+            app('LogService')->log(__METHOD__, 'GoodScan weightApi (Error)' . __FUNCTION__, '异方接口称重伤上传异常[异常值为-9.9,电子秤故障或未连接]' . json_encode($request->getContent()));
+            return json_encode(['code' => 500, 'error' => 'weight=-9.9'], JSON_UNESCAPED_UNICODE);
         }
-        if(!empty($orderPackage->order)){
-            Waybill::setWeightByOrderCode($orderPackage->order->code,$orderPackage->weight);
+
+        if (count($errors) > 0) {
+            app('LogService')->log(__METHOD__, 'error' . __FUNCTION__, json_encode($request->getContent()) . '||' . json_encode($errors), null);
+            return json_encode(['code' => 500, 'error' => $errors], JSON_UNESCAPED_UNICODE);
         }
-        $orderPackage->loadMissing('measuringMachine');
-        event(new WeighedEvent($orderPackage));
-        dispatch(new WeightUpdateInstantBill($orderPackage));
-        $response=["code"=>0,'error'=>'upload success'];
-        app('LogService')->log(__METHOD__,__FUNCTION__,"异方下发写入包裹成功:".json_encode($request->getContent()).'||'.json_encode($response),null);
 
-        return json_encode($response,JSON_UNESCAPED_UNICODE);
-    }
+        /** @var GoodScanWeightService $serivce */
+        $service = app(GoodScanWeightService::class);
+        $response = $service->new($requestInput);
+        if ($response['code'] == 500)
+            LogService::log(__CLASS__, __METHOD__, '称重失败:' . json_encode($response['error']));
+        else if ($response['code'] == 0)
+            LogService::log(__CLASS__, __METHOD__, '称重成功:' . json_encode($requestInput));
 
-    /**
-     * @param string $hid
-     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
-     */
-    public function getMeasuringMachine($hid)
-    {
-        /** @var MeasuringMachine $measuringMachine */
-        $measuringMachine = MeasuringMachine::query()->firstOrCreate(['code'=>$hid]); // 称重设备
-        $measuringMachine->turnOn();
-        $measuringMachine->turnOffInMinutes(30);
-        return $measuringMachine;
+        return json_encode($response, JSON_UNESCAPED_UNICODE);
     }
 
-    public function validatorWeight(array $request)
+    public function validatorWeight(array $request): \Illuminate\Contracts\Validation\Validator
     {
         return Validator::make($request, [
             'code' => ['required', 'max:191'],
@@ -109,190 +62,4 @@ class PackageController
             'string' => ':attribute 应为字符串',
         ], []);
     }
-
-    /**
-     * @param OrderPackage $orderPackage
-     * @param array $params
-     * @param MeasuringMachine $measuringMachine
-     * @return array
-     */
-    public function updateOrderPackage(&$orderPackage,$params,$measuringMachine) //更新包裹信息 前往处理活动波次
-    {
-        $edges=$this->getEdges($params);
-
-        $req_date=\Illuminate\Support\Carbon::now()->format(\Illuminate\Support\Carbon::DEFAULT_TO_STRING_FORMAT);
-        $orderPackage->weight=$params['weight'];
-        $orderPackage->measuring_machine_id=$measuringMachine->id;
-        $orderPackage->length=$edges[0];
-        $orderPackage->width=$edges[1];
-        $orderPackage->height=$edges[2];
-        $orderPackage->weighed_at=$req_date;
-        $orderPackage->bulk=$edges[0]*$edges[1]*$edges[2]/1000;
-        if($orderPackage->isActivityBatch()){
-            $response=$this->activityWaveNoProcessing($orderPackage);
-            if($response)return $response;
-        }
-        $orderPackage->save();
-        return[];
-    }
-
-    /**
-     * @param OrderPackage $orderPackage
-     * @return array
-     */
-    public function activityWaveNoProcessing(&$orderPackage) //处理活动波次
-    {
-        $fluxController = new \App\Http\Controllers\api\thirdPart\flux\PackageController();
-        if($orderPackage->isActivityBatch()){
-            app('LogService')->log(__METHOD__,__FUNCTION__,"依波次号同步所有包裹:".json_encode($orderPackage),null);
-            $params = [
-                'weight'=>$orderPackage['weight'] ?? null,
-                'length'=>$orderPackage['length'] ?? null,
-                'width'=>$orderPackage['width'] ?? null,
-                'height'=>$orderPackage['height'] ?? null,
-                'bulk'=>$orderPackage['bulk'] ?? null,
-                'measuring_machine_id'=>$orderPackage['measuring_machine_id'] ?? null,
-                'weighed_at'=>$orderPackage['weighed_at'] ?? null,
-                'paper_box_id'=>$orderPackage['paper_box_id'] ?? null,
-            ];
-            OrderPackage::query()->where('batch_number',$orderPackage['batch_number'])->update($params);
-            $result=$fluxController->markWMSOnBatch($orderPackage['batch_number'], $orderPackage['weight']);
-            if(!$result['result']){
-                $orderPackage->uploaded_to_wms="异常";
-            }
-        }else{
-            app('LogService')->log(__METHOD__,__FUNCTION__,"GoodScan 写入包裹至WMS:".json_encode($orderPackage),null);
-            try{
-                $result=$fluxController->accomplishToWMS($orderPackage);
-                if ($result['result'])
-                    $orderPackage->uploaded_to_wms="是";
-                else
-                    $orderPackage->uploaded_to_wms="异常";
-            }catch (\Exception $e){
-                $orderPackage->uploaded_to_wms="否";
-            }
-        }
-        $response=$this->saveOrderPackage($orderPackage);
-        return $response??[];
-    }
-
-    /**
-     * @param OrderPackage $orderPackage
-     * @return array
-     */
-    public function saveOrderPackage(&$orderPackage) //保存修改并
-    {
-        try {
-            $logisticNumberController = new LogisticNumberFeatureController();
-            if (!$orderPackage->order) {
-                $orderPackage->order = new Order();
-            }
-            if (!$orderPackage->order->logistic) {
-                $orderPackage->order->logistic = $logisticNumberController->getLogisticByFeatures($orderPackage->logistic_number);
-            }
-            $orderPackage->save();
-            return [];
-        } catch (\Exception $e) {
-            $response=["msg"=>'称重下发修改时发生错误!',json_encode($e),'code'=>500,'data'=>null];
-            app('LogService')->log(__METHOD__,'GoodScan weightApi (Error)'.__FUNCTION__,json_encode($orderPackage).'||'.json_encode($e),null);
-            return $response;
-        }
-    }
-
-    /**
-     * @param string $logisticNumber
-     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
-     */
-    public function getOrderPackageByLogisticNumber($logisticNumber)
-    {
-        return OrderPackage::query()
-            ->with(['order'=>function($query){
-                $query->with('owner','logistic');
-            }])
-            ->where('logistic_number',$logisticNumber)
-            ->first();
-    }
-
-    /**
-     * @param string $logisticNumber
-     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
-     */
-    public function findOrderHeaderByLogisticNumber($logisticNumber)
-    {
-        return OracleDOCOrderHeader::query()->with('actAllocationDetails','oracleBASCode')
-            ->whereHas('actAllocationDetails',function($query)use($logisticNumber){
-                $query->where('picktotraceid',$logisticNumber);
-            })
-//            ->orWhere('soreference5',$logisticNumber)
-            ->first();
-    }
-
-    /**
-     * @param OracleDOCOrderHeader $orderHeader
-     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
-     */
-    public function createOrderByOrderHeader($orderHeader)
-    {
-        /** @var OrderService $orderService */
-        $orderService=app(OrderService::class);
-        $order_create_params=$orderService->getParamByOrderHeader($orderHeader);
-        $order = $orderService->first(['code'=>$orderHeader->orderno]);
-        if($order)return $order;
-        $order = $orderService->createOrder($order_create_params);
-        app('LogService')->log(__METHOD__,__FUNCTION__,'GoodScan 创建Order',json_encode($order)." || ".$orderHeader);
-        return $order;
-    }
-
-    /**
-     * @param array $requestInput
-     * @param MeasuringMachine $measuringMachine
-     * @param Order $order
-     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
-     */
-    public function getOrderPackage($requestInput,$measuringMachine,$order)
-    {
-//        $weighed_at =$requestInput['time']??Carbon::now();
-        $weighed_at =Carbon::now();
-        $edges=$this->getEdges($requestInput);
-        OrderPackage::query()->create([
-            'order_id'=>$order->id,
-            'logistic_number'=>$requestInput['code'],
-            'measuring_machine_id'=>$measuringMachine->id,
-            'weight'=>$requestInput['weight'],
-            'length'=>$edges[0],
-            'width'=>$edges[1],
-            'height'=>$edges[2],
-            'bulk'=>$edges[0]*$edges[1]*$edges[2],
-            'weighed_at'=>$weighed_at,
-            'status'=>"无",
-        ]);
-        return $this->getOrderPackageByLogisticNumber($requestInput['code']);
-    }
-
-    /**
-     * @param array $requestInput
-     * @return array
-     */
-    public function getEdges($requestInput)
-    {
-        $edges = [$requestInput['l']??0,$requestInput['w']??0,$requestInput['h']??0];
-        rsort($edges);
-        return $edges;
-    }
-
-    /**
-     * @param $orderPackage
-     */
-    public function syncOrderPackageLogistic(&$orderPackage) // 同步订单承运商
-    {
-        $logisticNumberController = new LogisticNumberFeatureController();
-        if (!$orderPackage->order) {
-            $orderPackage->order = new Order();
-        }
-        if (!$orderPackage->order->logistic) {
-            $orderPackage->order->logistic = $logisticNumberController->getLogisticByFeatures($orderPackage->logistic_number);
-        }
-        $orderPackage->save();
-    }
-
 }

+ 28 - 12
app/Http/Controllers/api/thirdPart/haiq/LightController.php

@@ -9,17 +9,19 @@ namespace App\Http\Controllers\api\thirdPart\haiq;
 use App\Services\CacheShelfService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Station;
+use App\Traits\TestableInstant;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Log;
 
 class LightController
 {
     protected $request;
+    use TestableInstant;
 
     /** @var ForeignHaiRoboticsService $service */
-    private $service;
+    private $foreignHaiRoboticsService;
     public function __construct(){
-        $this->service=app('ForeignHaiRoboticsService');
+        $this->foreignHaiRoboticsService=null;
     }
 
     public function lightOn($post){
@@ -32,18 +34,32 @@ class LightController
      * @return array
      */
     public function update(Request $request){// 拍灯以后的消息发至此处
-        $station = Station::query()->with('stationType')->where('code',$request['locCode'])->first();
-        if( ($station ?? false) && ($station->stationType->name ?? false) && $station->stationType->name == '缓存架' ){  // 拍灯 推送任务
-            if($request['PTLAction'] !== 0) return ['location' => 200,'errMsg' => 'is cacheShelf','data' => $request->all()];
-            /** @var CacheShelfService $cacheShelfService */
-            $cacheShelfService = app(CacheShelfService::class);
-            $result =   $cacheShelfService->lightOffTask($request['locCode'],$request['PTLAction']);
-            return ['location'=>$result['success'] ? 200 :0,'errMsg'=>$result['errMsg'] ?? null,'data'=>$request->all()];
-        }
+        app('LogService')->log(__METHOD__,__FUNCTION__,'拍灯:'.json_encode($request->all()));
+        $this->instant($this->foreignHaiRoboticsService, 'ForeignHaiRoboticsService');
         $success = $request->input('success');
         $location = $success?200:0;
-        app('LogService')->log(__METHOD__,__FUNCTION__,'拍灯:'.json_encode($request->all()));
-        return ['location'=>$location,'errMsg'=>'','data'=>$request->all()];
+        /** @var Station $station */
+        $station = Station::query()->with('stationType')->where('code',$request['locCode'])->first();
+        $response = ['location' => $location, 'errMsg' => '', 'data' => $request->all()];
+        if(empty($station)
+            ||empty($station->stationType->name))return $response;
+
+        switch ($station->stationType->name) {
+            case '缓存架':     // 拍灯 推送任务
+                if($request['PTLAction'] !== 0){
+                    $response['errMsg']='灯条未开启';return $response;
+                }
+                /** @var CacheShelfService $cacheShelfService */
+                $cacheShelfService = app(CacheShelfService::class);
+                $result =   $cacheShelfService->lightOffTask($request['locCode'],$request['PTLAction']);
+                $response['location']=$result['success'];
+                $response['errMsg']=$result['errMsg'];
+                return $response;
+            case 'U型线拍灯':
+//                $this->foreignHaiRoboticsService->uLineLightPat($station);
+        }
+
+        return $response;
     }
 
 }

+ 24 - 21
app/Http/Controllers/api/thirdPart/hengli/PackageController.php

@@ -4,27 +4,33 @@
 namespace App\Http\Controllers\api\thirdPart\hengli;
 
 use App\Http\Controllers\api\thirdPart\weight\WeightBaseController;
+use App\Services\LogService;
+use App\Services\weight\HengLiWeightService;
 use Illuminate\Http\Request;
 
 class PackageController extends WeightBaseController
 {
-    // 参数
-    protected $weight = 'weight';     // 重量
-    protected $length = 'length';     // 长
-    protected $width = 'width';      // 宽
-    protected $height = 'height';     // 高
-    protected $code = 'code';       // 快递单号
-    protected $weight_at = 'weight_at';  // 称重时间
-    protected $hid = 'hid';        // 称重设备id
-    protected $name = 'HengLi';       // 名称
-
     public function new_(Request $request)
     {
-        app('LogService')->log(__METHOD__, $this->name, "记录上传日志:" . json_encode($request->all()) , null);
-        return $this->new($request);
+        $errors = $this->validator($request);
+        if(count($errors)>0){
+            return json_encode(['success' => false,'message' => $errors],JSON_UNESCAPED_UNICODE);
+        }
+
+        $params = $this->conversionRequest($request);
+
+        /** @var HengLiWeightService $service */
+        $service = app(HengLiWeightService::class);
+
+        $response = $service->new($params);
+        if($response['success'])
+            LogService::log(__CLASS__,$service->name,'称重成功!'.json_encode($params));
+        else
+            LogService::log(__CLASS__,$service->name,'称重失败!'.json_encode($request['']).json_encode($params));
+        return json_encode($response,JSON_UNESCAPED_UNICODE);
     }
 
-    public function conversionRequest($request)
+    public function conversionRequest($request): array
     {
         $params = [];
         $arr = $request->all();
@@ -66,27 +72,22 @@ class PackageController extends WeightBaseController
         return str_replace('_', '.', $value);
     }
 
-    // 信息返回
 
-    // 返回称重成功信息
     public function getSuccessMessage($params, $orderPackage): array
     {
         return ['success' => true, 'message' => '称重成功'];
     }
 
-    // 返回包裹未找到异常
     public function getNotFindOrderPackageMessage($params, $orderPackage): string
     {
         return json_encode(['success' => false, 'message' => '未找打包裹信息', JSON_UNESCAPED_UNICODE]);
     }
 
-    // 返回富勒信息未找到异常
     public function getNotFindOrderHeaderMessage($params, $orderPackage): string
     {
         return json_encode(['success' => false, 'message' => '富勒信息未找到'], JSON_UNESCAPED_UNICODE);
     }
 
-    // 返回称重下发错误
     public function getWeightMessage($orderPackage, $e)
     {
         return json_encode(['success' => false, 'message' => $e->getMessage], JSON_UNESCAPED_UNICODE);
@@ -94,18 +95,20 @@ class PackageController extends WeightBaseController
 
     public function validator(Request $request): array
     {
+        /** @var HengLiWeightService $service */
+        $service = app(HengLiWeightService::class);
         $params = $this->conversionRequest($request);
         $errors = [];
-        $weight = $this->getWeightValue($params);
+        $weight = $service->getWeightValue($params);
         if (empty($weight) || $weight == '') {
             $errors['weight'] = '称重重量为空';
         }
-        $code = $this->getCodeValue($params);
+        $code = $service->getCodeValue($params);
         $code = trim($code, "'");
         if (empty($code) || $code == '') {
             $errors['code'] = '快递单号为空';
         }
-        $hid = $this->getValue($this->hid, $params);
+        $hid = $service->getValue($service->hid, $params);
         if (empty($hid) || $hid == '') {
             $errors['hid'] = '称重设备号不能为空';
         }

+ 37 - 315
app/Http/Controllers/api/thirdPart/weight/PackageController.php

@@ -2,335 +2,57 @@
 
 namespace App\Http\Controllers\api\thirdPart\weight;
 
-use App\Events\WeighedEvent;
 use App\Http\Controllers\Controller;
-use App\Http\Controllers\LogisticNumberFeatureController;
-use App\Jobs\FetchPackageFromOracle;
-use App\Jobs\WeightUpdateInstantBill;
-use App\MeasuringMachine;
-use App\Order;
-use App\OrderPackage;
-use App\Services\OrderService;
-use App\Waybill;
+use App\Services\LogService;
+use App\Services\weight\HaoChuangWeightService;
 use Illuminate\Http\Request;
 use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Validator;
 
-
 class PackageController extends Controller
 {
-//    public function new_(Request $requestInitial){
-//        $request=[];
-//        foreach ($requestInitial->all() as $k=>$v){
-//            $request[strtolower($k)]=$v;
-//        }
-//        $reqDate=isset($request['time'])?$request['time']:Carbon::now();
-//        $errors=$this->validatorWeight($request)->errors();
-//
-//        if (count($errors)>0){
-//            app('LogService')->log(__METHOD__,'error'.__FUNCTION__,json_encode($request).'||'.json_encode($errors),null);
-//            $response=["msg"=>$errors,"code"=>500,"data"=>null];
-//            return json_encode($response);
-//        }
-//
-//        $measuringMachine=MeasuringMachine::where('code',$request['id'])->first();
-//        if (!$measuringMachine){
-//            $measuringMachine=new MeasuringMachine([
-//                'name'=>$request['id'],
-//                'code'=>$request['id'],
-//                'status'=>'在线'
-//            ]);
-//            $measuringMachine->save();
-//            app('LogService')->log(__METHOD__,'weightApi(new measuring machine)'.__FUNCTION__,json_encode($request),null);
-//        }else{
-//            $measuringMachineStatus=new MeasuringMachine();
-//            $measuringMachineStatus->changeStatus($measuringMachine);
-//        }
-//        MeasuringMachineQueue::dispatch($measuringMachine)->delay(Carbon::now()->addMinutes(30));
-//
-//        $package=Package::where('logistic_number',$request['barcode'])->first();
-//        if (isset($request['length'])&&isset($request['width'])&&isset($request['height'])){
-//            $length=$request['length'];
-//            $width=$request['width'];
-//            $height=$request['height'];
-//            $max=($length>=($width>=$height?$width:$height)?$length:($width>=$height?$width:$height));
-//            if ($max==$length){
-//                $centre=$width>=$height?$width:$height;
-//                $min=$width<$height?$width:$height;
-//            }elseif ($max==$width){
-//                $centre=$length>=$height?$length:$height;
-//                $min=$length<$height?$length:$height;
-//            }else{
-//                $centre=$width>=$length?$width:$length;
-//                $min=$width<$length?$width:$length;
-//            }
-//        }else{
-//            $max=0;$centre=0;$min=0;
-//        }
-//        $apiController=new \App\Http\Controllers\api\thirdPart\flux\PackageController();
-//        if ($package){
-//            $packageController=new \App\Http\Controllers\PackageController();
-//            $package->fetchPaperBox($max,$centre,$min,$package->owner_id);
-//            //处理活动波次
-//            if ($package->batch_rule&&strstr($package->batch_rule,'组合')){
-//                $packageController->syncBatch($package->batch_number,$request['weight'],$max,$centre,$min,$reqDate,$package['paper_box_id']);
-//            }else{
-//                $package->measuring_machine_id=$measuringMachine->id;
-//                $package->weight=$request['weight'];
-//                $package->length=$max;
-//                $package->width=$centre;
-//                $package->height=$min;
-//                $package->bulk=$max*$centre*$min;
-//                $package->weighed_at=$reqDate;
-//                $package->status="未上传";
-//                app('LogService')->log(__METHOD__,'Batch_'.__FUNCTION__,json_encode($package),null);
-//                $package->save();
-//                $result=$apiController->accomplishToWMS($package);
-//                if ($result['result']){
-//                    if ($package->status=="记录异常")$package->status="已上传异常";
-//                    else $package->status="已上传";
-//                }else{
-//                    $package->status="上传异常";
-//                }
-//                $package->save();
-//            }
-//            if ($package->order_code){
-//                $waybill=Waybill::where('wms_bill_number',$package->order_code)->where('status','!=','已完结')
-//                    ->where('status','!=','无模型')->first();
-//                if ($waybill){
-//                    $waybill->warehouse_weight_other=$package->weight;
-//                    $waybill->warehouse_weight_unit_id_other=1;
-//                    $waybill->update();
-//                }
-//            }
-//            event(new WeighedEvent($package));
-//            $response=["msg"=>"保存成功",
-//                        "code"=>200,
-//                        "data"=>true,
-//                        "serverMsg"=>null,
-//                        "requestor"=>[
-//                                "requestor"=>"1",
-//                                "eventCode"=>"0",
-//                                "reqDate"=>$reqDate,
-//                                "resDate"=>Carbon::now()]
-//                        ];
-//            app('LogService')->log(__METHOD__,'weightApi'.__FUNCTION__,json_encode($request).'|'.json_encode($response),null);
-//            return json_encode($response,JSON_UNESCAPED_UNICODE);
-//        }
-//        if (!$package){
-//            $logisticNumber=$request['barcode'];
-//            $createPackage=new Package([
-//                'logistic_number'=>$logisticNumber,
-//                'delivery_number'=>$logisticNumber,
-//                'measuring_machine_id'=>$measuringMachine->id,
-//                'weight'=>$request['weight'],
-//                'length'=>$max,
-//                'width'=>$centre,
-//                'height'=>$min,
-//                'bulk'=>$max*$centre*$min,
-//                'weighed_at'=>$reqDate,
-//                'status'=>"未下发",
-//            ]);
-//            $createPackage->fetchAllFromOracle();
-//            $createPackage->fetchPaperBox($max, $centre, $min);
-//            $result=$apiController->accomplishToWMS($createPackage);
-//            if(!$result['result']){
-//                app('LogService')->log(__METHOD__,'weightApi'.__FUNCTION__,json_encode($request).'||'.json_encode($createPackage),null);
-//                $response=["msg"=>"写入WMS失败!","code"=>500,"data"=>null];
-//                return json_encode($response,JSON_UNESCAPED_UNICODE);
-//            }
-//            if ($createPackage->save()){
-//                $measuringMachine->touch();
-//                MeasuringMachineQueue::dispatch($measuringMachine)->delay(Carbon::now()->addMinutes(30));
-//                MarkPackageExcepted::dispatch($createPackage)->delay(Carbon::now()->addMinutes(1440));
-//                event(new WeighedEvent($createPackage));
-//                $response=["msg"=>"保存成功",
-//                    "code"=>200,
-//                    "data"=>true,
-//                    "serverMsg"=>null,
-//                    "requestor"=>[
-//                        "requestor"=>"1",
-//                        "eventCode"=>"0",
-//                        "reqDate"=>$reqDate,
-//                        "resDate"=>Carbon::now()]
-//                ];
-//                app('LogService')->log(__METHOD__,'weightApi'.__FUNCTION__,json_encode($request).'||'.json_encode($response),null);
-//                return json_encode($response,JSON_UNESCAPED_UNICODE);
-//            }
-//
-//            $response=["msg"=>"保存时发生错误(未下发)!","code"=>500,"data"=>null];
-//            app('LogService')->log(__METHOD__,'weightApi(ERROR)'.__FUNCTION__,json_encode($request).'||'.json_encode($response),null);
-//            return json_encode($response,JSON_UNESCAPED_UNICODE);
-//        }
-//    }
-
-    public function new_(Request $requestInitial){
-        $request=[];
-        foreach ($requestInitial->all() as $k=>$v){
-            $request[strtolower($k)]=$v;
+    public function new_(Request $requestInitial)
+    {
+        $request = [];
+        foreach ($requestInitial->all() as $k => $v) {
+            $request[strtolower($k)] = $v;
         }
-//        $reqDate=isset($request['time'])?$request['time']:Carbon::now();
-        $reqDate=Carbon::now()->format(Carbon::DEFAULT_TO_STRING_FORMAT);
-        $errors=$this->validatorWeight($request)->errors();
+        $weight_at = Carbon::now()->format(Carbon::DEFAULT_TO_STRING_FORMAT);
+        $errors = $this->validatorWeight($request)->errors();
 
-        if (count($errors)>0){
-            app('LogService')->log(__METHOD__,'error'.__FUNCTION__,json_encode($request).'||'.json_encode($errors),null);
-            return json_encode(["msg"=>$errors,"code"=>500,"data"=>null]);
+        if (count($errors) > 0) {
+            app('LogService')->log(__METHOD__, 'error' . __FUNCTION__, json_encode($request) . '||' . json_encode($errors), null);
+            return json_encode(["msg" => $errors, "code" => 500, "data" => null]);
         }
 
-        $id = $request['id']??'无ID设备';
-        $measuringMachine=MeasuringMachine::query()->firstOrCreate(['code'=> $id]);
-        $measuringMachine->turnOn();
-        $measuringMachine->turnOffInMinutes(30);
+        $request['weight_at'] = $weight_at;
+        /** @var HaoChuangWeightService $service */
+        $service = app(HaoChuangWeightService::class);
+        $response = $service->new($request);
+        if ($response['code'] == 500)
+            LogService::log(__CLASS__, $service->name, '称重失败!' . json_encode($request['msg'] ?? '') . json_encode($request));
+        else
+            LogService::log(__CLASS__, $service->name, '称重成功!' . json_encode($request));
 
-        /** @var OrderPackage $package */
-        $package=OrderPackage::query()->where('logistic_number',$request['barcode'])->first();
-
-        $edges=[$request['length']??0,$request['width']??0,$request['height']??0];
-        rsort($edges);
-        $fluxController=new \App\Http\Controllers\api\thirdPart\flux\PackageController();
-        if ($package){
-            $package['measuring_machine_id']=$measuringMachine->id;
-            $package['weight']=$request['weight'];
-            $package['length']=$edges[0];
-            $package['width']=$edges[1];
-            $package['height']=$edges[2];
-            $package['weighed_at']=$reqDate;
-            $package->fetchAllFromOracle();
-            $package->fetchPaperBox();
-            $package['bulk']=$edges[0]*$edges[1]*$edges[2];
-            if ($package->isActivityBatch()){//处理活动波次
-                app('LogService')->log(__METHOD__,__FUNCTION__,"依波次号同步所有包裹:".json_encode($package),null);
-                $package->unifyThisMeasureUnderSameBatch();
-                $result=$fluxController->markWMSOnBatch($package['batch_number'], $request['weight']);
-                if(!$result['result']){
-                    $package->uploaded_to_wms="异常";
-                }
-            }else{
-                app('LogService')->log(__METHOD__,__FUNCTION__,"写入包裹至WMS:".json_encode($package),null);
-                try{
-                    $result=$fluxController->accomplishToWMS($package);
-                    if ($result['result']){
-                        $package->uploaded_to_wms="是";
-                    }else{
-                        $package->uploaded_to_wms="异常";
-                    }
-                }catch (\Exception $e){
-                    $package->uploaded_to_wms="否";
-                }
-            }
-            try{
-                $package->save();
-                $package->load(['order'=>function($query){
-                    $query->with('owner','logistic');
-                },'paperBox','measuringMachine']);
-                $logisticNumberController = new LogisticNumberFeatureController();
-                if (!$package->order){
-                    $package->order = new Order();
-                    $logistic=$logisticNumberController->getLogisticByFeatures($package->logistic_number);
-                    $package->order->logistic = $logistic;
-                }else{
-                    if(!$package->order->logistic){
-                        $logistic=$logisticNumberController->getLogisticByFeatures($package->logistic_number);
-                        $package->order->logistic_id = $logistic['id'];
-                        $package->order->save();
-                    }
-                }
-            }catch (\Exception $e){
-                $response=["msg"=>"称重下发修改时发生错误!".json_encode($e),"code"=>500,"data"=>null];
-                app('LogService')->log(__METHOD__,'weightApi(ERROR)'.__FUNCTION__,json_encode($request).'||'.json_encode($response).'||'.json_encode($e),null);
-                return json_encode($response,JSON_UNESCAPED_UNICODE);
-            }
-        }
-        if (!$package){
-            $logisticNumber=$request['barcode'];
-            /** @var $orderService OrderService */
-            $orderService = app('OrderService');
-            $order = $orderService->logisticNumberFirstOrCreateOrder($logisticNumber);
-            if (!$order) {
-                $response=["msg"=>"保存时发生错误(未在WMS找到该单)!","code"=>500,"data"=>null];
-                return json_encode($response,JSON_UNESCAPED_UNICODE);
-            }
-            $package=new OrderPackage([
-                'order_id' => $order->id,
-                'logistic_number'=>$logisticNumber,
-                'measuring_machine_id'=>$measuringMachine->id,
-                'weight'=>$request['weight'],
-                'length'=>$edges[0],
-                'width'=>$edges[1],
-                'height'=>$edges[2],
-                'bulk'=>$edges[0]*$edges[1]*$edges[2],
-                'weighed_at'=>$reqDate,
-                'status'=>"无",
-            ]);
-            $package->fetchAllFromOracle();
-            $package->fetchPaperBox();
-            try{
-                $package->save();
-                $package->load(['order'=>function($query){
-                    $query->with('owner','logistic');
-                },'paperBox','measuringMachine']);
-                $logisticNumberController = new LogisticNumberFeatureController();
-                if (!$package->order){
-                    $package->order = new Order();
-                    $logistic=$logisticNumberController->getLogisticByFeatures($package->logistic_number);
-                    $package->order->logistic = $logistic;
-                }else{
-                    if(!$package->order->logistic){
-                        $logistic=$logisticNumberController->getLogisticByFeatures($package->logistic_number);
-                        $package->order->logistic_id = $logistic['id'];
-                        $package->order->save();
-                    }
-                }
-            }catch (\Exception $e){
-                $response=["msg"=>$e->getMessage(),"code"=>500,"data"=>$e->getTraceAsString()];
-                app('LogService')->log(__METHOD__,'weightApi(ERROR)'.__FUNCTION__,json_encode($request).'||'.json_encode($response).'||'.$e->getTraceAsString(),null);
-                return json_encode($response,JSON_UNESCAPED_UNICODE);
-            }
-            $result=$fluxController->accomplishToWMS($package);
-            if(!$package['batch_number'])
-                FetchPackageFromOracle::dispatch($package)->delay(Carbon::now()->addMinutes(1440));
-            if(!$result['result']){
-                app('LogService')->log(__METHOD__,'weightApi'.__FUNCTION__,json_encode($request).'||'.json_encode($package),null);
-                $response=["msg"=>"写入WMS失败!","code"=>500,"data"=>null];
-                return json_encode($response,JSON_UNESCAPED_UNICODE);
-            }
-        }
-        if(!empty($package->order))
-            Waybill::setWeightByOrderCode($package->order->code,$package->weight);
-        if ($package){
-            event(new WeighedEvent($package));
-            dispatch(new WeightUpdateInstantBill($package));
-        }
-        $response=["msg"=>"保存成功",
-            "code"=>200,
-            "data"=>true,
-            "serverMsg"=>null,
-            "requestor"=>[
-                "requestor"=>"1",
-                "eventCode"=>"0",
-                "reqDate"=>$reqDate,
-                "resDate"=>Carbon::now()]
-        ];
-        app('LogService')->log(__METHOD__,__FUNCTION__,"下发写入包裹成功:".json_encode($request).'|'.json_encode($response),null);
-        return json_encode($response,JSON_UNESCAPED_UNICODE);
+        return json_encode($response);
     }
 
-    public function validatorWeight(array $request){
-        $validator=Validator::make($request,[
-            'id'=>['nullable','max:30'],
-            'barcode'=>['required','max:191'],
-            'weight'=>['required','numeric','min:0'],
-            'length'=>['nullable','numeric','min:0'],
-            'width'=>['nullable','numeric','min:0'],
-            'height'=>['nullable','numeric','min:0'],
-        ],[
-            'required'=>':attribute 为必填项',
-            'max'=>':attribute 字符过多或数值过大',
-            'min'=>':attribute 不得为负',
-            'numeric'=>':attribute 应为数字',
-        ],[]);
-        return $validator;
+
+    public function validatorWeight(array $request): \Illuminate\Contracts\Validation\Validator
+    {
+        return Validator::make($request, [
+            'id' => ['nullable', 'max:30'],
+            'barcode' => ['required', 'max:191'],
+            'weight' => ['required', 'numeric', 'min:0'],
+            'length' => ['nullable', 'numeric', 'min:0'],
+            'width' => ['nullable', 'numeric', 'min:0'],
+            'height' => ['nullable', 'numeric', 'min:0'],
+        ], [
+            'required' => ':attribute 为必填项',
+            'max' => ':attribute 字符过多或数值过大',
+            'min' => ':attribute 不得为负',
+            'numeric' => ':attribute 应为数字',
+        ], []);
     }
 
 }

+ 10 - 0
app/Http/Requests/DischargeTask/DischargeTaskRequest.php

@@ -69,6 +69,12 @@ class DischargeTaskRequest extends FormRequest
         'expenditure_unit.required' => '单位为必选项',
         'expenditure_unit_price.required' => '单价为必填项',
     ];
+    protected $uploadApiRule = [
+        'file' => 'required',
+    ];
+    protected $uploadApiMessage = [
+        'file' => 'required',
+    ];
 
     public function authorize(): bool
     {
@@ -88,6 +94,8 @@ class DischargeTaskRequest extends FormRequest
                 return $this->updateApiRules;
             case 'discharge.updateTaskFacilitatorApi':
                 return $this->updateTaskFacilitatorApiRules;
+            case 'discharge.importApi':
+                return $this->uploadApiRule;
             default :
                 return [];
         }
@@ -106,6 +114,8 @@ class DischargeTaskRequest extends FormRequest
                 return $this->updateApiMessage;
             case 'discharge.updateTaskFacilitatorApi':
                 return $this->updateTaskFacilitatorApiMessage;
+            case 'discharge.importApi':
+                return $this->uploadApiMessage;
             default :
                 return [];
         }

+ 83 - 0
app/Imports/DischargeTaskImport.php

@@ -0,0 +1,83 @@
+<?php
+
+namespace App\Imports;
+
+use App\DischargeTask;
+use App\Owner;
+use App\Services\DischargeTaskService;
+use App\Warehouse;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Cache;
+use Maatwebsite\Excel\Concerns\ToCollection;
+use Maatwebsite\Excel\Concerns\WithHeadingRow;
+use Maatwebsite\Excel\Imports\HeadingRowFormatter;
+
+HeadingRowFormatter::default('none');
+
+class DischargeTaskImport implements ToCollection, WithHeadingRow
+{
+    /**
+     * @param Collection $collection
+     */
+    public function collection(Collection $collection)
+    {
+        /** @var DischargeTaskService $service */
+        $service = app(DischargeTaskService::class);
+        $exception = [];
+        $numbers = [];
+        foreach ($collection as $row => $item) {
+            $index = $row + 1;
+            $message = '';
+            $owner = Owner::query()->where('name', trim($item['货主']))->first();
+            $waveHouse = Warehouse::query()->where('name', trim($item['仓库']))->first();
+            $type = array_search(trim($item['作业名称']), DischargeTask::types);
+            $unit = array_search(trim($item['单位']), DischargeTask::units);
+
+            if (array_search(trim($item['入库单']), $numbers)) $message .= '入库单号重复;';
+
+            if (!$owner) $message .= '对应货主不存在;';
+
+            if (!$waveHouse) $message .= '对应仓库不存在;';
+
+            if (!$item['入库单'] || strlen(trim('入库单')) == 0) $message .= '未输入入库单;';
+
+            if (!$item['数量'] || strlen(trim('数量')) == 0) $message .= '未输入数量;';
+
+            if (!$item['单价'] || strlen(trim('单价')) == 0) $message .= '未输入单价;';
+
+            if (!$item['单位'] || strlen(trim('单位')) == 0) $message .= '未输入单位;';
+
+            if (isset($type) && $type != 0) $message .= '指定作业类型错误;';
+
+            if (!$item['作业名称']) $message .= '未指定作业类型';
+
+            if (DischargeTask::query()->where('numbers',$item['入库单'])->exists()) $message .= '入库单号已存在;';
+
+            if (strlen($message) > 0) {
+                $exception[] = "第{$index}行卸货任务创建失败:" . $message;
+                continue;
+            }
+            $params = [
+                'owner_id' => $owner->id,
+                'warehouse_id' => $waveHouse->id,
+                'type' => $type,
+                'numbers' => trim($item['入库单']),
+                'income_amount' => $item['数量'],
+                'income_unit_price' => $item['单价'],
+                'income_unit' => $unit,
+                'income_total_cost' => $item['数量'] * $item['单价'],
+                'status' => 0,
+                'income_remark' => $item['备注'],
+                'income_at' => $item['预约日期'] ?formatExcelDateTime($item['预约日期']): Carbon::now()->format(Carbon::DEFAULT_TO_STRING_FORMAT)
+            ];
+            try {
+                $service->createTask($params, false);
+                $numbers[] = trim($item['入库单']);
+            } catch (\Exception $e) {
+                $exception[] = "第{$index}行创建失败:创建异常";
+            }
+        }
+        Cache::put('exception', $exception, 86400);
+    }
+}

+ 3 - 1
app/Imports/StoreCheckingReceiveImport.php

@@ -5,6 +5,8 @@ namespace App\Imports;
 use App\Http\Controllers\CommodityController;
 use App\Services\CommodityBarcodeService;
 use App\Services\CommodityService;
+use App\StoreCheckingReceiveItem;
+use App\StoreItem;
 use Carbon\Carbon;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
@@ -258,7 +260,7 @@ class StoreCheckingReceiveImport implements ToCollection,WithHeadingRow
         foreach ($items as &$it){
             $it["store_checking_receive_id"] = $storeCheckingReceive->id;
         }
-        app('StoreCheckingReceiveItemService')->insert($items);
+        StoreCheckingReceiveItem::query()->insert($items);
         app('LogService')->log(__METHOD__,"导入盘收任务-批量录入盘收记录",json_encode($items,JSON_UNESCAPED_UNICODE));
 
         Cache::put("storeCheckingReceive",["success"=>true,"data"=>$storeCheckingReceive,"errors"=>$errors],86400);

+ 1 - 1
app/Jobs/LogisticSFSync.php

@@ -44,7 +44,7 @@ class LogisticSFSync implements ShouldQueue
      */
     public function handle()
     {
-        LogService::log(LogisticSFSync::class, "{$this->logistic_number}-JOB-SF", '');
+        LogService::log(LogisticSFSync::class, "JOB-SF", $this->logistic_number);
         $this->logisticSFService = app('LogisticSFService');
         $formedData = $this->logisticSFService->get([$this->logistic_number]);
         $this->orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');

+ 6 - 4
app/Jobs/LogisticYDSync.php

@@ -19,14 +19,16 @@ class LogisticYDSync implements ShouldQueue
 
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
     /**
-     * @var $logisticYDService LogisticYDService
+     *
      * @var $orderPackageReceivedSyncService OrderPackageReceivedSyncService
      * @var $orderPackageReceivedSyncService OrderPackageReceivedSyncService
      * @var $logistic_number string
      */
 
     protected $logistic_number;
-
+    /**
+     * @var $logisticYDService LogisticYDService
+     */
     protected $logisticYDService;
     protected $orderPackageReceivedSyncService;
 
@@ -47,14 +49,14 @@ class LogisticYDSync implements ShouldQueue
      */
     public function handle()
     {
-        LogService::log(LogisticYDSync::class, "{$this->logistic_number}-JOB-YD", '');
+        LogService::log(LogisticYDSync::class, "JOB-YD", $this->logistic_number);
         $this->logisticYDService = app('LogisticYDService');
         //先订阅订单
         $this->logisticYDService->registerApi([$this->logistic_number]);
         //查询订单路由信息
         $nativeResponse = $this->logisticYDService->query($this->logistic_number);
         //格式化信息
-        $formattedData = $this->logisticYDService->format($nativeResponse);
+        $formattedData = $this->logisticYDService->format($nativeResponse,$this->logistic_number);
         $this->orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
         //更新数据
         $this->orderPackageReceivedSyncService->update([$formattedData]);

+ 2 - 2
app/Jobs/LogisticYTOSync.php

@@ -46,10 +46,10 @@ class LogisticYTOSync implements ShouldQueue
      */
     public function handle()
     {
-        LogService::log(LogisticYTOSync::class, "{$this->logistic_number}-JOB-YTO", '');
+        LogService::log(LogisticYTOSync::class, "JOB-YTO", $this->logistic_number);
         $this->logisticYTOService = app('LogisticYTOService');
         $nativeResponse = $this->logisticYTOService->query($this->logistic_number);
-        $formattedData = $this->logisticYTOService->format($nativeResponse);
+        $formattedData = $this->logisticYTOService->format($nativeResponse,$this->logistic_number);
         $this->orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
         if (count($formattedData)>0 && $formattedData['logistic_number']??false){
             $this->orderPackageReceivedSyncService->update([$formattedData]);

+ 1 - 2
app/Jobs/LogisticZopSync.php

@@ -51,11 +51,10 @@ class LogisticZopSync implements ShouldQueue
      */
     public function handle()
     {
-        ini_set('max_execution_time', 60);
         LogService::log(LogisticZopSync::class, "JOB-ZOP", $this->logistic_number);
         $logistic_zop_service = new LogisticZopService();
         $nativeResponse = $logistic_zop_service->query($this->logistic_number);
-        $formatted_data = $logistic_zop_service->format($nativeResponse);
+        $formatted_data = $logistic_zop_service->format($nativeResponse,$this->logistic_number);
         $this->order_package_received_sync_service->update([$formatted_data]);
     }
 }

+ 5 - 1
app/MaterialBox.php

@@ -10,7 +10,7 @@ class MaterialBox extends Model
 {
     use ModelLogChanging;
 
-    protected $fillable=['code','status'];
+    protected $fillable=['code','status',"material_box_model_id"];
 
     static public $enums=[
         'status'=>[
@@ -48,4 +48,8 @@ class MaterialBox extends Model
     {   //料箱任务
         return $this->hasMany(StationTaskMaterialBox::class,"material_box_id","id");
     }
+    public function materialBoxModel()
+    {   //料箱型号
+        return $this->belongsTo(MaterialBoxModel::class);
+    }
 }

+ 16 - 0
app/MaterialBoxModel.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class MaterialBoxModel extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable=[
+        "code"
+    ];
+}

+ 1 - 1
app/Menu.php

@@ -13,6 +13,6 @@ class Menu extends Model
 
     use ModelTimeFormat;
     protected $fillable=[
-        'name','level', 'parent_id', 'route','sequence',
+        'name','level', 'parent_id', 'route','sequence',"font","font_style"
     ];
 }

+ 8 - 0
app/Observers/OwnerObserver.php

@@ -27,4 +27,12 @@ class OwnerObserver
         }
     }
 
+    public function deleted(Owner $owner)
+    {
+        $owner->load("roles");
+        $owner->roles->each(function ($role){
+            app("RoleService")->clearUserAuthority($role->id,false,true);
+        });
+    }
+
 }

+ 16 - 0
app/Observers/UserWorkGroupObserver.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Observers;
+
+use App\UserWorkGroup;
+
+class UserWorkGroupObserver
+{
+    public function restored(UserWorkGroup $userWorkGroup)
+    {
+        $userWorkGroup->load("roles");
+        $userWorkGroup->roles->each(function ($role){
+            app("RoleService")->clearUserAuthority($role->id,false,false,true);
+        });
+    }
+}

+ 14 - 1
app/OrderCountingRecord.php

@@ -5,12 +5,25 @@ namespace App;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
 class OrderCountingRecord extends Model
 {
     use ModelLogChanging;
 
     //
-    protected $fillable = ['owner_id','shop_id' ,'warehouse_id' ,'logistic_id' ,'date_target' ,'counting_unit' ,'amount','year','month','week'];
+    protected $fillable = ['owner_id' ,'warehouse_id' ,'logistic_id' ,'date_target' ,'counting_unit' ,'amount','year','month'];
+
+    public  $timestamps = false;
+
+    public function logistic(): BelongsTo
+    {
+        return $this->belongsTo(Logistic::class);
+    }
+
+    public function warehouse(): BelongsTo
+    {
+        return $this->belongsTo(Warehouse::class);
+    }
 
 }

+ 4 - 0
app/Owner.php

@@ -215,4 +215,8 @@ class Owner extends Model
     {
         return $this->hasMany(OwnerSundryFeeDetail::class);
     }
+    public function roles()
+    {   //角色
+        return $this->belongsToMany(Role::class);
+    }
 }

+ 12 - 0
app/OwnerFeeDetail.php

@@ -6,6 +6,8 @@ use App\Services\ProcessMethodService;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 
 class OwnerFeeDetail extends Model
 {
@@ -61,4 +63,14 @@ class OwnerFeeDetail extends Model
     {   //快递费子项
         return $this->hasMany(OwnerFeeDetailLogistic::class,"owner_fee_detail_id","id");
     }
+
+    public function ownerLogisticFeeDetails(): HasMany
+    {
+        return $this->hasMany(OwnerLogisticFeeDetail::class);
+    }
+
+    public function ownerLogisticFeeDetail(): HasOne
+    {
+        return $this->hasOne(OwnerLogisticFeeDetail::class,'logistic_bill','logistic_bill');
+    }
 }

+ 6 - 0
app/OwnerFeeDetailLogistic.php

@@ -5,6 +5,7 @@ namespace App;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 
 class OwnerFeeDetailLogistic extends Model
 {
@@ -20,4 +21,9 @@ class OwnerFeeDetailLogistic extends Model
     {   //快递
         return $this->belongsTo(Logistic::class);
     }
+
+    public function ownerLogisticFeeDetail(): HasOne
+    {
+        return $this->hasOne(OwnerLogisticFeeDetail::class, 'logistic_bill', 'logistic_bill');
+    }
 }

+ 26 - 0
app/OwnerLogisticFeeDetail.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+
+class OwnerLogisticFeeDetail extends Model
+{
+    use ModelLogChanging;
+
+    public $fillable = ['owner_fee_detail_id', 'logistic_bill', 'initial_weight', 'initial_weight_price', 'additional_weight', 'additional_price'];
+
+    public function ownerFeeDetail(): HasOne
+    {
+        return $this->hasOne(OwnerFeeDetail::class);
+    }
+
+
+    public function ownerFeeDetailLogistic(): HasOne
+    {
+        return $this->hasOne(OwnerFeeDetailLogistic::class,'logistic_bill', 'logistic_bill');
+    }
+}

+ 14 - 0
app/OwnerLogisticFeeReport.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class OwnerLogisticFeeReport extends Model
+{
+    use ModelLogChanging;
+
+    //
+}

+ 31 - 8
app/Providers/AppServiceProvider.php

@@ -7,8 +7,9 @@ use App\Jobs\LogisticSFSync;
 use App\Jobs\LogisticYDSync;
 use App\Jobs\LogisticYTOSync;
 use App\Jobs\LogisticZopSync;
-use App\LaborCompany;
-use App\Observers\LaborCompanyObserver;
+use App\Observers\OwnerObserver;
+use App\Observers\UserWorkGroupObserver;
+use App\Owner;
 use App\Services\AuthorityService;
 use App\Services\BatchService;
 use App\Services\CacheService;
@@ -35,6 +36,7 @@ use App\Services\LogisticYTOService;
 use App\Services\LogisticZopService;
 use App\Services\LogService;
 use App\Services\MaterialBoxService;
+use App\Services\NewOrderCountingRecordService;
 use App\Services\OracleBasCustomerService;
 use App\Services\OracleBasSkuService;
 use App\Services\OracleDocAsnDetailService;
@@ -109,9 +111,15 @@ use App\Services\WeighExceptedService;
 use App\Services\OrderFreezeService;
 use App\Services\RegionService;
 use App\Services\UserWorkgroupService;
+use App\Services\MenuService;
 use App\Services\DischargeTaskService;
 use App\Services\DeliveryAppointmentService;
+use App\Services\RoleService;
+use App\UserWorkgroup;
 use App\Services\StationCacheShelfGridService;
+use App\Services\weight\GoodScanWeightService;
+use App\Services\weight\HaoChuangWeightService;
+use App\Services\weight\HengLiWeightService;
 use App\Services\PrintPartService;
 use App\Services\PrintTemplateService;
 use Illuminate\Queue\Events\JobFailed;
@@ -130,7 +138,9 @@ use App\Services\LogisticYDService;
 use App\Services\ForeignZhenCangService;
 use App\Services\StorageService;
 use App\Services\LogisticAliJiSuApiService;
-use App\Services\LaborCompanyService;
+use App\Services\CommodityMaterialBoxModelService;
+use App\Services\OwnerLogisticFeeDetailService;
+use App\Services\OwnerLogisticFeeReportService;
 
 class AppServiceProvider extends ServiceProvider
 {
@@ -151,6 +161,7 @@ class AppServiceProvider extends ServiceProvider
     public function boot()
     {
         $this->loadingService();
+        $this->registerObserver();
         //
         Schema::defaultStringLength(191);
         Queue::failing(function (JobFailed $event) {
@@ -195,17 +206,17 @@ class AppServiceProvider extends ServiceProvider
     private function loadingService(){
         app()->singleton('AllInventoryService',AllInventoryService::class);
         app()->singleton('AuthorityService',AuthorityService::class);
+        app()->singleton('NewOrderCountingRecordService',NewOrderCountingRecordService::class);
         app()->singleton('BatchService',BatchService::class);
         app()->singleton('BatchUpdateService', BatchUpdateService::class);
         app()->singleton('CacheService',CacheService::class);
         app()->singleton('CacheShelfService',CacheShelfService::class);
         app()->singleton('CheckActiveMenuService',CheckActiveMenuService::class);
         app()->singleton('CommodityBarcodeService',CommodityBarcodeService::class);
+        app()->singleton('CommodityMaterialBoxModelService',CommodityMaterialBoxModelService::class);
         app()->singleton('CommodityService', CommodityService::class);
         app()->singleton('ConfigurationService',ConfigurationService::class);
         app()->singleton('CustomerLogService',CustomerLogService::class);
-        app()->singleton('CustomerLogService',CustomerLogService::class);
-        app()->singleton('CustomerLogStatusService',CustomerLogStatusService::class);
         app()->singleton('CustomerLogStatusService',CustomerLogStatusService::class);
         app()->singleton('CustomerService',CustomerService::class);
         app()->singleton('DataHandlerService',DataHandlerService::class);
@@ -219,9 +230,9 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('ForeignHaiRoboticsService',ForeignHaiRoboticsService::class);
         app()->singleton('ForeignZhenCangService',ForeignZhenCangService::class);
         app()->singleton('InventoryAccountMissionService', InventoryAccountMissionService::class);
+        app()->singleton('LogisticZopService', LogisticZopService::class);
         app()->singleton('InventoryCompareService', InventoryCompareService::class);
         app()->singleton('InventoryDailyLogService', InventoryDailyLogService::class);
-        app()->singleton('LaborCompanyService',LaborCompanyService::class);
         app()->singleton('LaborReportsCountingRecordService', LaborReportsCountingRecordService::class);
         app()->singleton('LogService', LogService::class);
         app()->singleton('LogisticAliJiSuApiService',LogisticAliJiSuApiService::class);
@@ -256,6 +267,8 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerAreaReportService', OwnerAreaReportService::class);
         app()->singleton('OwnerBillReportService', OwnerBillReportService::class);
         app()->singleton('OwnerFeeDetailService', OwnerFeeDetailService::class);
+        app()->singleton('OwnerLogisticFeeDetailService',OwnerLogisticFeeDetailService::class);
+        app()->singleton('OwnerLogisticFeeReportService',OwnerLogisticFeeReportService::class);
         app()->singleton('OwnerMaterialService', OwnerMaterialService::class);
         app()->singleton('OwnerMaterialService', OwnerMaterialService::class);
         app()->singleton('OwnerPriceDirectLogisticService', OwnerPriceDirectLogisticService::class);
@@ -309,6 +322,18 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('WarehouseService', WarehouseService::class);
         app()->singleton('WaybillFinancialService', WaybillFinancialService::class);
         app()->singleton('WeighExceptedService', WeighExceptedService::class);
+        app()->singleton('GoodScanWeightService',GoodScanWeightService::class);
+        app()->singleton('HaoChuangWeightService',HaoChuangWeightService::class);
+        app()->singleton('HengLiWeightService',HengLiWeightService::class);
+        app()->singleton('InventoryAccountMissionService',InventoryAccountMissionService::class);
+        app()->singleton('MenuService',MenuService::class);
+        app()->singleton('RoleService',RoleService::class);
+    }
+
+    private function registerObserver()
+    {
+        Owner::observe(OwnerObserver::class);
+        UserWorkgroup::observe(UserWorkGroupObserver::class);
     }
 
     /**
@@ -316,8 +341,6 @@ class AppServiceProvider extends ServiceProvider
      */
     private function logisticSyncRecord($displayName, $column_name): void
     {
-
-
         /**
          * @var OrderPackageReceivedSyncRecordService $orderPackageReceivedSyncRecordService
          */

+ 1 - 0
app/Providers/AuthServiceProvider.php

@@ -38,6 +38,7 @@ class AuthServiceProvider extends ServiceProvider
     public function boot()
     {
         $this->registerPolicies();
+
         $isSuperAdmin = null;
         if(!Schema::hasTable('users')){return;}
         /** @var CacheService $cacheService */

+ 1 - 1
app/RejectedBill.php

@@ -25,7 +25,7 @@ class RejectedBill extends Model
     protected $fillable=['id_owner','order_number','sender','mobile_sender',
         'logistic_number','logistic_number_return','id_logistic_return',
         'is_loaded','fee_collected','remark','id_operator','is_checked',
-        'is_finished','checked_numbers','remark','common_01','common_02'];
+        'is_finished','checked_numbers','common_01','common_02'];
 
     /*
      *  id_owner                    货主

+ 9 - 0
app/Role.php

@@ -19,6 +19,15 @@ class Role extends Model
     function authorities(){
         return $this->belongsToMany('App\Authority','authority_role','id_role','id_authority');
     }
+
+    public function owners()
+    {   //货主
+        return $this->belongsToMany(Owner::class);
+    }
+    public function userWorkGroups()
+    {   //工作组
+        return $this->belongsToMany(UserWorkgroup::class,"role_user_work_group","role_id","user_work_group_id");
+    }
     function laborCompanies(){
         return $this->belongsToMany('App\LaborCompany','role_labor_company','role_id','labor_company_id');
     }

+ 87 - 0
app/Services/AuthorityService.php

@@ -7,8 +7,12 @@ namespace App\Services;
 use App\Authority;
 use App\Role;
 use Exception;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
 use App\Traits\ServiceAppAop;
+use Illuminate\Support\Facades\DB;
 
 
 class AuthorityService
@@ -41,4 +45,87 @@ class AuthorityService
 //        }
 //        return $roles;
 //    }
+
+    public function getUserAuthority()
+    {
+        $key = "authorities:user_".Auth::id();
+        $isAdmin = array_search(Auth::user()["name"],config("users.superAdmin"))!==false;
+        $tag = $isAdmin ? "authorities:admin" : "authorities:user";
+        if (!Cache::tags($tag)->has($key)){
+            if ($isAdmin) Cache::tags("authorities:admin")->forever($key,Authority::query()->get());
+            else Cache::tags("authorities:user")->forever($key,Authority::query()->whereHas("roles",function (Builder $query){
+                $query->whereHas("users",function (Builder $query){
+                    $query->where(DB::raw("users.id"),Auth::id());
+                });
+            })->get());
+        }
+        return Cache::tags($tag)->get($key);
+    }
+
+    public function removeAdminAuth()
+    {
+        Cache::tags("authorities:admin")->flush();
+    }
+
+    public function removeAllAuth()
+    {
+        Cache::tags("authorities:admin")->flush();
+        Cache::tags("authorities:user")->flush();
+    }
+
+    /**
+     * 格式化为树状结构
+     *
+     * @param Collection $authorities
+     * @return array
+     */
+    public function format($authorities)
+    {
+        $authMap = [];
+        foreach ($authorities as $authority){
+            $item = $authority->toArray();
+            $item["child"] = [];
+            $authMap[$authority->id] = $item;
+        }
+
+        foreach ($authorities as $authority){
+            if ($authority->parent_id){
+                if (!isset($authMap[$authority->parent_id])){
+                    $authTem = $this->formatAuthority($authMap,$authMap[$authority->id]);
+                    if ($authTem)$authMap = $authTem;
+                } else $authMap[$authority->parent_id]["child"][] = $authMap[$authority->id];
+                unset($authMap[$authority->id]);
+            }
+        }
+        return $authMap;
+    }
+
+
+    /**
+     * 递归格式化权限组
+     *
+     * @param array $authMap
+     * @param array $authorities
+     *
+     * @return array|bool
+     */
+    private function formatAuthority(array $authMap,array $authorities)
+    {
+        foreach ($authMap as $index=>$data){
+            if ($data["id"]==$authorities["parent_id"]){
+                $authMap[$index]["child"][] = $authorities;
+                unset($authMap[$authorities["id"]]);
+                return $authMap;
+            }else{
+                if ($authMap[$index]["child"]){
+                    $re = $this->formatAuthority($authMap[$index]["child"],$authorities);
+                    if ($re){
+                        $authMap[$index]["child"] = $re;
+                        return $authMap;
+                    }
+                }
+            }
+        }
+        return false;
+    }
 }

+ 19 - 10
app/Services/BatchService.php

@@ -65,6 +65,7 @@ class BatchService
      */
     public function assignTasks($batches)
     {
+        app('LogService')->log('海柔','assignTasks1',json_encode($batches));
         try{
             $batches = collect($batches);
 
@@ -76,22 +77,26 @@ class BatchService
 
             $stationTaskBatches=null;
             $stationTasks=null;
+            app('LogService')->log('海柔','assignTasks2',json_encode($batches));
             $batches_shouldProcess = $this->stationRuleBatchService->getBatches_shouldProcess($batches); //按规则过滤需要的波次
             if($batches_shouldProcess->isEmpty()) return;
-            $stationTaskMaterialBoxes_occupied = $this->stationTaskMaterialBoxService->getOccupied_byBatches($batches_shouldProcess); //按规则过滤需要的波次
-            if($stationTaskMaterialBoxes_occupied->isNotEmpty()) {
-                foreach ($batches_shouldProcess as $batch){
-                    Cache::tags(['波次防重叠'.$batch['id']])->flush();
-                }
-                BatchTaskJob::dispatch($batches_shouldProcess)
-                    ->delay(now()->addMinutes(1));    //因为料箱被占用了,所以将任务推迟1分钟后尝试
-                return;
-            }
+//            $stationTaskMaterialBoxes_occupied = $this->stationTaskMaterialBoxService->getOccupied_byBatches($batches_shouldProcess); //过滤料箱被占用的波次
+//            app('LogService')->log('海柔','assignTasks2.5',json_encode($stationTaskMaterialBoxes_occupied));
+//            if($stationTaskMaterialBoxes_occupied->isNotEmpty()) {
+//                foreach ($batches_shouldProcess as $batch){
+//                    Cache::tags(['波次防重叠'.$batch['id']])->flush();
+//                }
+//                BatchTaskJob::dispatch($batches_shouldProcess)
+//                    ->delay(now()->addMinutes(1));    //因为料箱被占用了,所以将任务推迟1分钟后尝试
+//                return;
+//            }
+            app('LogService')->log('海柔','assignTasks3',json_encode($batches_shouldProcess));
             DB::transaction(function ()use($batches,&$stationTaskBatches,&$batches_shouldProcess,&$stationTasks){
                 $stationTasks =  $this->stationTaskService->create($batches_shouldProcess->count()); //生成总任务
                 $stationTaskBatches=$this->stationTaskBatchService->createByBatches($batches_shouldProcess,$stationTasks); //注册波次任务
                 $stationTaskMaterialBoxes=$this->stationTaskMaterialBoxService->createByBatches($batches_shouldProcess,$stationTasks); //注册料箱任务
                 $stationTaskCommodities=$this->stationTaskCommodityService->createByBatches($batches_shouldProcess,$stationTasks); //注册商品任务
+                app('LogService')->log('海柔','assignTasks4',json_encode($batches_shouldProcess));
             });
             foreach ($stationTasks as &$stationTask){
                 $stationTask->loadMissing([
@@ -101,15 +106,19 @@ class BatchService
                     "stationTaskMaterialBoxes.materialBox",
                 ]);
             }
-            $jsonStationTasks=json_encode($stationTasks);
+            app('LogService')->log('海柔','assignTasks5',json_encode($stationTasks,true).json_encode($batches_shouldProcess));
+            $jsonStationTasks=json_encode($stationTasks,true);
             broadcast(new BroadcastToStation(BroadcastToStation::ALL_STATION, $jsonStationTasks));
+            app('LogService')->log('海柔','assignTasks6',$jsonStationTasks.json_encode($batches_shouldProcess));
 //            $ran=$this->stationTaskBatchService->runMany($stationTaskBatches);//执行波次任务
         }catch(Exception $e){
+            app('LogService')->log('海柔','assignTasks7',json_encode($batches));
             $batchesJson='';
             foreach ($batches as $batch){
                 $batchesJson.=json_encode($batch);
                 Cache::tags(['波次防重叠'.$batch['id']])->flush();
             }
+            app('LogService')->log('海柔','assignTasks8',json_encode($batches));
             throw new ErrorException('注册任务失败: '. $batchesJson . $e->getMessage().json_encode($e->getTrace()));
         }
     }

+ 120 - 140
app/Services/CacheShelfService.php

@@ -7,9 +7,11 @@ use App\Exceptions\ErrorException;
 use App\MaterialBox;
 use App\Station;
 use App\StationTask;
+use App\StationTaskChild;
 use App\StationTaskChildren;
 use App\StationTaskMaterialBox;
 use App\StationType;
+use App\Storage;
 use App\Traits\ServiceAppAop;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Http;
@@ -40,7 +42,7 @@ class   CacheShelfService
      */
     public function getChildStation($id)
     {
-        return Station::query()->where('parent_id',$id)->with('parent','pendingStationTask.stationTaskMaterialBoxes.materialBox')->get();
+        return Station::query()->where('parent_id', $id)->with('storage.materialBox')->get();
     }
 
 
@@ -49,134 +51,99 @@ class   CacheShelfService
      * @param $locCode
      * @param $PTLAction
      * @return array|bool[]
+     * @throws \Exception
      */
     public function lightOffTask($locCode, $PTLAction): array
     {
         $station = Station::query()->with('pendingStationTask.stationTaskMaterialBoxes.materialBox')->where('code', $locCode)->first();
+        if (!app("StorageService")->checkStorage($station)){
+            $this->stationLightUp($station->code,null,'0','1','上架任务失败');
+            return ['success' => false,'errMsg' => '上架任务失败'];
+        };
         try {
             $bool = $this->putBinToStore($station);                         // 推送任务
-            if($bool){
-                LogService::log(__CLASS__,'lightOffTask','code' .' true'. $locCode.json_encode($station));
+            if ($bool) {
+                LogService::log(__CLASS__, 'lightOffTask', 'code' . ' true' . $locCode . json_encode($station));
                 return ['success' => true];
-            }else{
-                return ['success' => false,'errMsg' => '机器人推送失败'];
+            } else {
+                return ['success' => false, 'errMsg' => '机器人推送失败'];
             }
         } catch (ErrorException $e) {
-            LogService::log(__FUNCTION__,'缓存架推送任务失败',json_encode($e->getMessage()));
-            return ['success' => false,'errMsg' => $e->getMessage()];
+            LogService::log(__FUNCTION__, '缓存架推送任务失败', json_encode($e->getMessage()));
+            return ['success' => false, 'errMsg' => $e->getMessage()];
         }
     }
 
     /**
      * 推任务至海柔机器人
      * @param  $station
-     * @return bool
+     * @return array
      * @throws ErrorException
+     * @throws \Exception
      */
-    public function putBinToStore($station): bool
+    public function putBinToStore($station): array
     {
-        $this->instant($this->stationTaskMaterialBoxService, 'StationTaskMaterialBoxService');
         $this->instant($this->foreignHaiRoboticsService, 'ForeignHaiRoboticsService');
         $this->instant($this->stationService, 'StationService');
-        $this->instant($this->stationTaskService, 'StationTaskService');
-        $this->instant($this->stationTaskChildService, 'StationTaskChildService');
 
-        /** @var StationTaskMaterialBox $takeStationTaskMaterialBox */
-        $takeStationTaskMaterialBox = $station['pendingStationTask']['stationTaskMaterialBoxes']->first();
-        $formStation = $this->stationService->getStation_byType('立库');
+        /** @var MaterialBox $materialbox */
+        $materialBox = $station->storage->materialbox;
+
+        $formStation = $this->stationService->getStation_byType('立库');          // 立库
+
+        $stationTask = StationTask::query()->create(['station_id' => $formStation['id'], 'status' => '待处理']);   // 生成任务
 
-        // 查询是否有待处理的入库任务
-        $putStationTaskMaterialBox = StationTaskMaterialBox::query()->where([
+        /** @var StationTaskMaterialBox $stationTaskMaterialBox */
+        $stationTaskMaterialBox = StationTaskMaterialBox::query()->create([
             'station_id' => $formStation['id'],
-            'material_box_id' => $takeStationTaskMaterialBox['material_box_id'],
+            'material_box_id' => $materialBox['id'],
             'status' => '待处理',
-        ])->first();
-
-        // 创建入立库任务
-        if(!$putStationTaskMaterialBox){
-            $stationTask = $this->stationTaskService->create(1);               // 生成站任务
-            $this->stationTaskService->registerStations($stationTask,[$formStation['id']]);   // 注册站任务站
-            /** @var StationTaskMaterialBox $putStationTaskMaterialBox */
-            $putStationTaskMaterialBox = $this->stationTaskMaterialBoxService->create([
-                'station_id' => $formStation['id'],
-                'material_box_id' => $takeStationTaskMaterialBox['material_box_id'],
-                'status' => '待处理',
-            ]);
-            $putStationTaskMaterialBox['station_task_id'] = $stationTask->first()['id'];
-            $putStationTaskMaterialBox['type'] = '放';
-            $putStationTaskMaterialBox->update();
-
-            $params = [[
-                'station_task_id'=>$stationTask->first()['id'],
-                'station_taskable_type'=>StationTaskMaterialBox::class,
-                'station_taskable_id'=>$putStationTaskMaterialBox['id']
-            ]];
+            'station_task_id' => $stationTask['id'],
+            'type' => '放',
+        ]);
 
-            $this->stationTaskChildService->insert($params);    // 任务任务注册
-        }
+        StationTaskChildren::query()->create([
+            'station_task_id' => $stationTask['id'],
+            'station_taskable_type' => StationTaskMaterialBox::class,
+            'station_taskable_id' => $stationTaskMaterialBox['id']
+        ]);
 
-        // 推立库任务
-        $isSuccess =  $this->foreignHaiRoboticsService->putBinToStore_fromCacheShelf($putStationTaskMaterialBox,$station['code']);
-        if($isSuccess) $this->stationTaskMaterialBoxService->set($takeStationTaskMaterialBox,['status' => '处理中']);  // 任务推送成功 标记站任务为处理中
-        else {
-            $materialBoxCode = $station['pendingStationTask']['stationTaskMaterialBoxes']->first()->code ?? '';
-            $this->_stationCacheBroadCast($station->code,0,'error');
-            $this->_stationCacheLightOn($station->code,$materialBoxCode,'拍灯重试任务');
-        }
-        return $isSuccess;
+        $bool = $this->foreignHaiRoboticsService->putBinToStore_fromCacheShelf($stationTaskMaterialBox, $station['code']);
+        return $bool ? ['success' => true] : ['success' => false];
     }
 
     /**
-     * 创建站任务和料箱任务
+     * 缓存架和料箱的绑定
      * @param $stationCode
      * @param $materialBoxCode
      * @return array
      */
-    public function createStationTask($stationCode,$materialBoxCode): array
+    public function bindMaterialBox($stationCode, $materialBoxCode): array
     {
-        $this->instant($this->stationTaskService, 'StationTaskService');
-        $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
-        $this->instant($this->stationTaskChildService,'StationTaskChildService');
+        $station = Station::query()->with('storage')->where('code', $stationCode)->first();
 
-        $station = Station::query()->where('code' , $stationCode)->first();
-        if(!$station){
+        if (!$station) {
             $arr = [];
-            preg_match('/^HAI([\w]+)/',$stationCode,$arr);
+            preg_match('/^HAI([\w]+)/', $stationCode, $arr);
             $parentCode = $arr[1] ?? '';
-            $stationType = StationType::query()->where('name','缓存架')->first();
-            $parentStation = Station::query()->firstOrCreate(['code'=>$parentCode],['station_type_id'=>$stationType['id']]);
-            $station = Station::query()->firstOrCreate(['code' => $stationCode,'parent_id'=>$parentStation['id']],['name'=>$stationCode,'station_type_id' => $stationType['id']]);
+            $stationType = StationType::query()->where('name', '缓存架')->first();
+            $parentStation = Station::query()->firstOrCreate(['code' => $parentCode], ['station_type_id' => $stationType['id']]);
+            $station = Station::query()->firstOrCreate(['code' => $stationCode, 'parent_id' => $parentStation['id']], ['name' => $stationCode, 'station_type_id' => $stationType['id']]);
         }
 
         $materialBox = MaterialBox::query()->firstOrCreate(['code' => $materialBoxCode]);
 
-        $station->load('pendingStationTask.stationTaskMaterialBoxes.materialBox');
-        if($station->pendingStationTask){
-            if($station['pendingStationTask']['stationTaskMaterialBoxes']->first()->materialBox->code == $materialBoxCode){
-                $response = $this->_stationCacheLightOn($stationCode,$materialBoxCode,'任务重试');
-                if($response->code) return ['success'=>true,'message' =>  '任务重试'];
-                return ['success'=>true,'message' =>  '任务重试失败'];
-            }
-            return ['success' => false,'message' => '当前已有进行重的任务'];
-        }
+        $storage = $station->storage ?? Storage::query()->firstOrCreate(['station_id' => $station['id']]);
 
-        $stationTask = $this->stationTaskService->create(1);                                                       // 生成站任务
-        $stationTaskMaterialBox = $this->stationTaskMaterialBoxService->createByStationAndMaterialBox($station,$materialBox);     // 创建料箱任务
-        $this->stationTaskService->registerStations($stationTask,[$station['id']]);                                               // 注册站任务站
-        $stationTaskMaterialBox['station_task_id'] = $stationTask->first()['id'];
-        $stationTaskMaterialBox->update();
-        $params = [[
-                'station_task_id'=>$stationTask->first()['id'],
-                'station_taskable_type'=>StationTaskMaterialBox::class,
-                'station_taskable_id'=>$stationTaskMaterialBox['id']
-            ]];
-        $this->stationTaskChildService->insert($params);                                                                        // 任务任务注册
-
-        $body = $this->_stationCacheLightOn($stationCode,$materialBoxCode);
-        if($body->code == 200)return ['success'=>true];
-        return ['success' => false,'message' => '机器人亮灯异常'];
+        $result = $this->_stationCacheLightOn($station['code'],$materialBoxCode);
+        if($result['code'] == 200){
+            $storage->update(['material_box_id' => $materialBox['id'],'status' => 1]);
+            return ['success' => true];
+        }
+        return ['success' => false,'message' => $result['errMsg']];
     }
 
+
     /**
      * 控制格口亮灯
      * @param $locCode
@@ -185,13 +152,47 @@ class   CacheShelfService
      * @param string $color
      * @return mixed
      */
-    public function _stationCacheLightOn($locCode,$materialCode = null,$title = 'title' ,string $color = '1')
+    public function _stationCacheLightOn($locCode, $materialCode = null, $title = 'title', string $color = '1')
     {
         $params = [
             "areaCode" => "1004",
             'locCode' => $locCode,
             'PTLAction' => 1,
-            'PTLSettings' => ['color'=> $color, 'frequency'  =>1],
+            'PTLSettings' => ['color' => $color, 'frequency' => 1],
+            "displayInfo" => [
+                "detail01" => $materialCode,
+                "detail02" => "detail02",
+                "detail03" => "detail03",
+                "qrCode" => "qrCode",
+                "qty00" => "11",
+                "qty01" => 1,
+                "qty02" => 2,
+                "title" => $title,
+                "uomDesc01" => "uo",
+                "uomDesc02" => "uo"
+            ],
+        ];
+        $response = Http::post(config('api.haiq.storage.light'), $params);
+        return json_decode($response->body());
+    }
+
+    /**
+     * 站亮灯
+     *
+     * @param string $stationCode
+     * @param string|null $materialCode
+     * @param string $color             explain: 0-red 1-green 2-blue 3-yellow
+     * @param string $frequency         explain: 0-常亮 1-一次 2-两次 3-三次 4-四次 5-五次 (均为/秒)
+     * @param string $title
+     * @return mixed
+     */
+    public function stationLightUp(string $stationCode,?string $materialCode = null, string $color = '1', string $frequency = '0', $title = '')
+    {
+        $params = [
+            "areaCode" => "1004",
+            'locCode' => $stationCode,
+            'PTLAction' => 1,
+            'PTLSettings' => ['color' => $color, 'frequency'  => $frequency],
             "displayInfo" => [
                 "detail01" => $materialCode,
                 "detail02" => "detail02",
@@ -214,8 +215,9 @@ class   CacheShelfService
      * @param $locCode
      * @return mixed
      */
-    public function _stationCacheLightOff($locCode){
-        if(!$locCode)return null;
+    public function _stationCacheLightOff($locCode)
+    {
+        if (!$locCode) return null;
         $params = [
             "areaCode" => "1004",
             'locCode' => $locCode,
@@ -231,84 +233,62 @@ class   CacheShelfService
      * @param $PTLAction
      * @param string $type
      */
-    public function _stationCacheBroadCast($locCode, $PTLAction,string $type = 'success')
+    public function _stationCacheBroadCast($locCode, $PTLAction, string $type = 'success')
     {
-        if($PTLAction == 0){
-            $station = Station::query()->with('parent')->where('code',$locCode)->first();
+        if (!$locCode) return;
+        if ($PTLAction == 0) {
+            $station = Station::query()->with('parent')->where('code', $locCode)->first();
 
-            $json = json_encode( [
+            $json = json_encode([
                 'station_id' => $station['parent']['id'],
-                'code'  => $station['parent']['code'],
+                'code' => $station['parent']['code'],
                 'gird_id' => $station['id'],
                 'grid_code' => $station['code'],
-                'type' => $type
+                'type' => $type,
+                'status' => 0
             ]);
-            broadcast(new BroadcastToStation($station['parent_id'],$json));
+            broadcast(new BroadcastToStation($station['parent_id'], $json));
         }
     }
 
     /**
-     * 根据立库任务完成 缓存架任务 和 入立架任务
-     * @param StationTaskMaterialBox $putStationTaskMaterial
+     * 根据立库任务完成对storage进行修改
+     * @param StationTaskMaterialBox $stationTaskMaterial
      */
-    public function putStationTaskMaterialBoxProcess(StationTaskMaterialBox $putStationTaskMaterial)
+    public function putStationTaskMaterialBoxProcess(StationTaskMaterialBox $stationTaskMaterial)
     {
-        $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
-
-        $takeStationTaskMaterialBox = StationTaskMaterialBox::query()->with('station','stationTask')->where('material_box_id',$putStationTaskMaterial['material_box_id'])->whereIn('station_id',function($query){
-            $query->from('stations')->selectRaw('id')->whereIn('station_type_id',function($query){
-                $query->from('station_types')->selectRaw('id')->where('name','缓存架');
-            });
-        })->where('status','处理中')->first();
-
-        if(!$takeStationTaskMaterialBox)return ;
-        $this->stationTaskMaterialBoxService->set($takeStationTaskMaterialBox, [
-            'status' => '完成'
-        ]);
+        $this->instant($this->stationTaskMaterialBoxService, 'StationTaskMaterialBoxService');
 
-        // 缓存架任务
-        if($takeStationTaskMaterialBox->stationTask)$takeStationTaskMaterialBox->stationTask->update(['status' => '完成']);
-        // 入立架任务
-        if($putStationTaskMaterial->stationTask)$putStationTaskMaterial->stationTask->update(['status' => '完成']);
+        $storage = Storage::query()->where('material_box_id', $stationTaskMaterial['material_box_id'])->where('status',1)->first();
+        if($storage)$storage->update(['status' => 0, 'material_box_id' => null]);
 
-        $this->_stationCacheLightOff($takeStationTaskMaterialBox->station->code ?? null);  //海柔格口灭灯
-        $this->_stationCacheBroadCast($takeStationTaskMaterialBox->station->code, 0);    //通知缓存架任务完成
+        $this->_stationCacheLightOff($stationTaskMaterial->station->code ?? null);  //海柔格口灭灯
+        $this->_stationCacheBroadCast($stationTaskMaterial->station->code ?? null, 0);    //通知缓存架任务完成
     }
 
     /**
      * 取消任务
      * @param $stationCode
      * @return array
+     * @throws \Exception
      */
     public function clearTask($stationCode): array
     {
-        $station = Station::query()->with(['currentStationTask.stationTaskMaterialBoxes.materialBox',
-            'pendingStationTask.stationTaskMaterialBoxes.materialBox'])
-            ->where('code',$stationCode)->first();
+        $station = Station::query()->with('storage')->where('code', $stationCode)->first();
 
-        if($station->currentStationTask)return ['success' => false,'message' => '当前任务正在执行','data'=>$stationCode];
-        if($station->pendingStationTask->stationTaskMaterialBoxes->count() == 0){
-            $station->pendingStationTask->delete();
-            return ['success' => true];
-        }
-
-        $taskStationTaskMaterialBox = $station->pendingStationTask->stationTaskMaterialBoxes->first() ?? null;
-        $stationTaskMaterialBoxes = StationTaskMaterialBox::query()->with('stationTask')
-            ->where('material_box_id',$taskStationTaskMaterialBox['material_box_id'])
-            ->where('station_id','!=',$station->pendingStationTask['id'])
-            ->get();
+        if (!$station) return ['success' => false, 'message' => '传入参数异常,找不到对应的缓存架记录'];
 
-        foreach ($stationTaskMaterialBoxes as $stationTaskMaterialBox) {
-            if($stationTaskMaterialBox->stationTask){
-                StationTaskChildren::query()->where([
-                    'station_task_id' => $stationTaskMaterialBox->stationTask['id'],
-                    'station_taskable_type'=>StationTaskMaterialBox::class,
-                    'station_taskable_id'=>$stationTaskMaterialBox['id']])->delete();
-
-                $stationTaskMaterialBox->stationTask->delete();
+        $stationTaskMaterialBox = StationTaskMaterialBox::query()->where('material_box_id',$station['storage']['material_box_id'])->first();
+        if($stationTaskMaterialBox ){
+            if($stationTaskMaterialBox->status == '处理中')
+                return ['success' => false, 'message' => '当前缓存架任务正在处理中'];
+            else{
+                $stationTaskMaterialBox->delete();
             }
-            $stationTaskMaterialBox->delete();
         }
+
+        $station->storage->update(['status' => 0,'material_box_id' => null]);
+
         return ['success' => true];
     }
 }

+ 51 - 0
app/Services/CommodityMaterialBoxModelService.php

@@ -0,0 +1,51 @@
+<?php 
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\CommodityMaterialBoxModel;
+
+class CommodityMaterialBoxModelService
+{
+    use ServiceAppAop;
+    protected $modelClass=CommodityMaterialBoxModel::class;
+
+
+    /**
+     * 获取最大限值
+     *
+     * @param integer|null $modelId
+     * @param integer|null $commodityId
+     *
+     * @return int|null
+     */
+    public function getMaximum($modelId, $commodityId):?int
+    {
+        if (!$modelId || !$commodityId)return null;
+        $model = CommodityMaterialBoxModel::query()->select("maximum")->where("commodity_id",$commodityId)
+            ->where("material_box_model_id",$modelId)->first();
+        return (int)$model->maximum ?? null;
+    }
+
+    /**
+     * 设置最大限值
+     *
+     * @param integer|null $modelId
+     * @param integer|null $commodityId
+     * @param integer $maximum
+     *
+     * @return bool
+     */
+    public function setMaximum($modelId, $commodityId, $maximum):bool
+    {
+        if (!$modelId || !$commodityId)return false;
+        $model = CommodityMaterialBoxModel::query()->select("maximum")->where("commodity_id",$commodityId)
+            ->where("material_box_model_id",$modelId)->first();
+        if (!$model)CommodityMaterialBoxModel::query()->create([
+            "maximum" => $maximum,
+            "commodity_id" => $commodityId,
+            "material_box_model_id" => $modelId,
+        ]);else $model->update(["maximum" => $maximum]);
+        return true;
+    }
+}

+ 2 - 2
app/Services/DischargeTaskService.php

@@ -72,7 +72,7 @@ class DischargeTaskService
     }
 
     // 创建卸货任务
-    public function createTask(array $param): array
+    public function createTask(array $param,bool $loadMissing = true): array
     {
         if (isset($param['id'])) unset($param['id']);
         if (empty($param['income_total_cost'])) $param['income_total_cost'] = $param['income_unit_price'] * $param['income_amount'];
@@ -80,7 +80,7 @@ class DischargeTaskService
         if (empty($param['status'])) $param['status'] = 0;
 
         $dischargeTask = DischargeTask::query()->create($param);
-        $dischargeTask->loadMissing('facilitator', 'owner','warehouse');
+        if($loadMissing)$dischargeTask->loadMissing('facilitator', 'owner','warehouse');
 
         return ['success' => true, 'data' => $dischargeTask];
     }

+ 43 - 50
app/Services/ForeignHaiRoboticsService.php

@@ -8,7 +8,6 @@ use App\Exceptions\ErrorException;
 use App\Exceptions\Exception;
 use App\MaterialBox;
 use App\Station;
-use App\StationCacheShelfGrid;
 use App\StationTask;
 use App\StationTaskMaterialBox;
 use Carbon\Carbon;
@@ -16,7 +15,6 @@ use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Http;
 use App\Traits\ServiceAppAop;
-use Illuminate\Support\Facades\Log;
 
 
 class ForeignHaiRoboticsService
@@ -116,8 +114,8 @@ class ForeignHaiRoboticsService
         switch ($modeName){
             case '输送线入立架': return 1;
             case '立架出至输送线': return 2;
-            case '立架出至缓存架':
             case '移动立架内位置': return 3;
+            case '立架出至缓存架':
             case '缓存架入立架':return 6;
             default: throw new \Exception('发至海柔的移料箱请求,模式不存在');
         }
@@ -170,7 +168,7 @@ class ForeignHaiRoboticsService
     ): bool
     {
         LogService::log('海柔请求','markBinProcessed1.1',
-            '');
+            $binCode.'|'.$success.'|'.$exception.'|'.$is_in_plan);
         $this->instant($this->stationService,'StationService');
         $this->instant($this->materialBoxService,'MaterialBoxService');
         $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
@@ -207,21 +205,21 @@ class ForeignHaiRoboticsService
                     ->first();
             })();
             LogService::log('海柔请求','markBinProcessed1.6',
-                json_encode($stationTaskMaterialBox));
+                json_encode($stationTaskMaterialBox).'|'.$binCode);
             if(!$stationTaskMaterialBox){
                 throw new ErrorException($binCode.'该料箱没有安排在处理队列中.');
             }
             LogService::log('海柔请求','markBinProcessed1.7',
-                json_encode($stationTaskMaterialBox));
+                json_encode($stationTaskMaterialBox).'|'.$binCode);
 
-            DB::transaction(function ()use($stationTaskMaterialBox){
+            DB::transaction(function ()use($stationTaskMaterialBox,$binCode){
                 $stationTaskMaterialBox_next=
                     $this->stationTaskMaterialBoxService
                         ->processNextQueued($stationTaskMaterialBox); //找到队列中下一个料箱,并标记为处理中
                 $this->stationTaskCommoditiesService
                     ->markProcessed($stationTaskMaterialBox['stationTaskCommodities']);
                 LogService::log('海柔请求','markBinProcessed1.8',
-                    json_encode($stationTaskMaterialBox));
+                    json_encode($stationTaskMaterialBox).'|'.$binCode);
                 if($stationTaskMaterialBox_next)
                     $this->stationTaskCommoditiesService
                         ->markProcessing($stationTaskMaterialBox_next['stationTaskCommodities']);//因为上边商品任务被标记完成了,所以这里要将队列中找出正在处理的料箱对应的标记为“处理中”
@@ -232,26 +230,26 @@ class ForeignHaiRoboticsService
                 if($notProcessedBoxTasks->isEmpty()){
                     $this->instant($this->stationTaskService,'StationTaskService');
                     LogService::log('海柔请求','markBinProcessed1.81',
-                        json_encode($stationTaskMaterialBox['stationTaskBatch']));
+                        json_encode($stationTaskMaterialBox['stationTaskBatch']).'|'.$binCode);
                     $stationTaskMaterialBox->loadMissing('stationTaskBatch');
                     $this->stationTaskBatchService->markProcessed($stationTaskMaterialBox['stationTaskBatch']);
                     LogService::log('海柔请求','markBinProcessed1.82',
-                        json_encode($stationTaskMaterialBox['stationTaskBatch']));
+                        json_encode($stationTaskMaterialBox['stationTaskBatch']).'|'.$binCode);
                     $this->stationTaskService->markProcessed($stationTaskMaterialBox['stationTask']);
                 }
                 $this->storeBox($stationTaskMaterialBox)
                     ?true
                     :(function(){throw new ErrorException('呼叫机器人回收U型线料箱失败');})();
                 LogService::log('海柔请求','markBinProcessed1.9',
-                    json_encode($stationTaskMaterialBox));
+                    json_encode($stationTaskMaterialBox).'|'.$binCode);
                 $this->stationService->broadcastBinMonitor($stationTaskMaterialBox['station_id'],$stationTaskMaterialBox['stationTask']);
                 LogService::log('海柔请求','markBinProcessed1.99',
-                    json_encode($stationTaskMaterialBox));
+                    json_encode($stationTaskMaterialBox).'|'.$binCode);
             });
-
             return true;
         }catch (\Exception $e){
-
+            LogService::log('海柔请求','markBinProcessed E1',
+                $binCode);
             $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
             $this->instant($this->materialBoxService,'MaterialBoxService');
             $box=$this->materialBoxService->firstOrCreate(['code'=>$binCode]);
@@ -271,6 +269,8 @@ class ForeignHaiRoboticsService
             );
             $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox_toStore]),'输送线入立架');
 
+            LogService::log('海柔请求','markBinProcessed E2',
+                $binCode);
             $stationTaskMaterialBox = $stationTaskMaterialBox_toStore??$materialBox??null;
             if($stationTaskMaterialBox && get_class($stationTaskMaterialBox)==MaterialBox::class){
                 $stationTaskMaterialBox = StationTaskMaterialBox::query()
@@ -324,26 +324,12 @@ class ForeignHaiRoboticsService
     public function putBinToStore_fromCacheShelf(?StationTaskMaterialBox $stationTaskMaterialBox,
                                                  string $formLocation): bool
     {
-        LogService::log('海柔请求','putBinToStore_fromCacheShelf1', '');
-        LogService::log('海柔请求','putBinToStore_fromCacheShelf2', json_encode($stationTaskMaterialBox));
-
-        $dataToPost=$this->makeJson_move(
-            collect([$stationTaskMaterialBox]),
-            '缓存架入立架',
-            $formLocation,
-            ''
-        );
-        LogService::log('海柔请求','putBinToStore_fromCacheShelf3', json_encode($dataToPost));
+        $dataToPost=$this->makeJson_move(collect([$stationTaskMaterialBox]), '缓存架入立架', $formLocation, '');
 
         $controlSuccess = $this->controlHaiRobot($dataToPost,collect([$stationTaskMaterialBox]),'缓存架入立架');
-        LogService::log('海柔请求','putBinToStore_fromCacheShelf4', 'controlHaiRobot '. json_encode($controlSuccess));
-
         if($controlSuccess){
             $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
-            $this->stationTaskMaterialBoxService->set($stationTaskMaterialBox,[
-                'status' => '处理中',
-            ]);
-            LogService::log('海柔请求','putBinToStore_fromCacheShelf5', 'controlHaiRobot '. json_encode($stationTaskMaterialBox));
+            $this->stationTaskMaterialBoxService->set($stationTaskMaterialBox,['status' => '处理中']);
         }
         return $controlSuccess;
     }
@@ -498,30 +484,37 @@ class ForeignHaiRoboticsService
     }
 
     /**
-     * put cache rack box to warehousing(将缓存架料箱入库)
+     * 填充缓存架
      *
-     * @param string $fromLocation
-     * @param string $toLocation
-     * @param integer $boxId
+     * @param \Illuminate\Database\Eloquent\Collection $stations
      *
      * @return bool
+     *
+     * @throws
      */
-    public function putWareHousing(string $fromLocation, string $toLocation, $boxId):bool
+    public function paddingCacheShelf($stations)
     {
-        $station = Station::query()->select("id")->where("code",$fromLocation)->first();
-        if (!$station)return false;
-        if (StationTask::query()->select("id")->where("status","!=",'完成')->where("station_id",$station->id)->first())return false;
-        /** @var \stdClass $task */
-        $task = StationTask::query()->create([
-            'status' => "待处理",
-            'station_id' => $station->id,
-        ]);
-        StationTaskMaterialBox::query()->create([
-            'station_id' => $station->id,
-            'material_box_id'=>$boxId,
-            'status'=>"待处理",
-            'type' => '放',
-            'station_task_id' => $task->id,
-        ]);
+        $collection = new Collection();
+        $stationCollection = new Collection();
+        $blacklist = [];
+        foreach ($stations as $station){
+            $box = app("MaterialBoxService")->getAnEmptyBox($blacklist);
+            if (!$box)break;
+            $task = StationTask::query()->create([
+                'status' => "待处理",
+                'station_id' => $station->id,
+            ]);
+            $collection->add(StationTaskMaterialBox::query()->create([
+                'station_id' => $station->id,
+                'material_box_id'=>$box->id,
+                'status'=>"待处理",
+                'type' => '取',
+                'station_task_id' => $task->id,
+            ]));
+            $stationCollection->add($station->code);
+            $blacklist[] = $box->id;
+        }
+        $this->fetchGroup_multiLocation($stationCollection,$collection,'','立架出至缓存架');
+        return $stations->count()==$stationCollection->count();
     }
 }

+ 11 - 9
app/Services/LaborReportsCountingRecordService.php

@@ -6,25 +6,27 @@ namespace App\Services;
 
 use App\LaborReport;
 use Carbon\Carbon;
-use DateTime;
-use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Str;
-use Ramsey\Uuid\Type\Integer;
 use App\Traits\ServiceAppAop;
 
 
 class LaborReportsCountingRecordService
 {
     use ServiceAppAop;
-    protected $modelClass=LaborReportsCountingRecord::class;
+
+    private $ttl;
+
     public function __construct(LaborReport $laborReport)
     {
+        $this->ttl = config('cache.expirations.commonFrequent');
         $laborReport::$withoutAppends = false;
     }
+
     public function userGroupsCount($start, $end)
     {
-        $resultByCache = Cache::remember('userGroupsCount_' . $start . '_' . $end, 600, function () use ($start, $end) {
+
+        $resultByCache = Cache::remember('userGroupsCount_' . $start . '_' . $end, $this->ttl, function () use ($start, $end) {
             return LaborReport::query()->selectRaw('user_workgroup_id,count(user_workgroup_id) amount')
                 ->with('userWorkgroup', 'laborReportStatus')
                 ->whereDate('created_at', '>=', $start)
@@ -103,7 +105,7 @@ class LaborReportsCountingRecordService
                 break;
             case '年';
                 foreach (Carbon::parse($start)->yearsUntil($end, 1)->toArray() as $item) {
-                    $dataArray[] = $item->year.'';
+                    $dataArray[] = $item->year . '';
                 }
                 break;
             default:
@@ -127,7 +129,7 @@ class LaborReportsCountingRecordService
                 $dataList->each(function ($item) use ($unit) {
                     $date = $item->date_target;
                     $key = 'laborReportsCountingRecords_' . $date . '_' . $unit;
-                    Cache::put($key, $item);
+                    Cache::put($key, $item, $this->ttl);
                 });
                 break;
             case '月':
@@ -143,7 +145,7 @@ class LaborReportsCountingRecordService
                 $dataList->each(function ($item) use ($unit) {
                     $date = $item->date_target;
                     $key = 'laborReportsCountingRecords_' . $date . '_' . $unit;
-                    Cache::put($key, $item);
+                    Cache::put($key, $item, $this->ttl);
                 });
                 break;
             case '年':
@@ -158,7 +160,7 @@ class LaborReportsCountingRecordService
                 $dataList->each(function ($item) use ($unit) {
                     $date = $item->date_target;
                     $key = 'laborReportsCountingRecords_' . $date . '_' . $unit;
-                    Cache::put($key, $item);
+                    Cache::put($key, $item, $this->ttl);
                 });
                 break;
             default:

+ 1 - 1
app/Services/LogisticRouteInterface.php

@@ -8,5 +8,5 @@ interface LogisticRouteInterface
 {
     public function query($logistic_number);
 
-    public function format($nativeResponse);
+    public function format($nativeResponse,$logistic_number);
 }

+ 18 - 5
app/Services/LogisticYDService.php

@@ -64,8 +64,12 @@ class LogisticYDService
             'req-time' => now()->timestamp,
             "Content-Type" => "application/json"
         ];
-        $response = Http::withHeaders($headers)->withBody($json_body, 'application/json')->post($this->url);
-        return json_decode($response);
+        try {
+            $response = Http::withHeaders($headers)->withBody($json_body, 'application/json')->post($this->url);
+            return json_decode($response);
+        } catch (\GuzzleHttp\Exception\RequestException $e) {
+            LogService::log(LogisticYDService::class, "韵达-registerApi", $logistic_numbers);
+        }
     }
 
     public function query($logistic_number)
@@ -83,14 +87,23 @@ class LogisticYDService
             'req-time' => now()->timestamp,
             "Content-Type" => "application/json"
         ];
-        $response = Http::withHeaders($headers)->withBody(json_encode($body, JSON_UNESCAPED_UNICODE), 'application/json')->post($this->url);
+        try {
+            $response = Http::withHeaders($headers)->withBody(json_encode($body, JSON_UNESCAPED_UNICODE), 'application/json')->post($this->url);
+        } catch (\GuzzleHttp\Exception\RequestException $e) {
+            LogService::log(LogisticYDService::class, "韵达-query", $logistic_number);
+            return null;
+        }
         return json_decode($response->body());
     }
 
-    public function format($nativeResponse)
+    public function format($nativeResponse, $logistic_number)
     {
         if (is_null($nativeResponse) || $nativeResponse->code != '0000' || $nativeResponse->data->result == "false") {
-            return [];
+            return [
+                'logistic_number' => $logistic_number,
+                'exception_type' => '揽件异常',
+                'exception' => '是',
+            ];
         } else {
             $nativeData = $nativeResponse->data;
             try {

+ 8 - 2
app/Services/LogisticYTOService.php

@@ -42,10 +42,16 @@ class LogisticYTOService
         return json_decode($response->body());
     }
 
-    public function format($response): array
+    public function format($response,$logistic_number): array
     {
         $result = [];
-        if (is_object($response) && $response->code=='1001') {return [];}
+        if (is_object($response) && $response->code=='1001') {
+            return [
+                'logistic_number' => $logistic_number,
+                'exception_type' => '揽件异常',
+                'exception' => '是',
+            ];
+        }
         else {
             try {
                 if (is_array($response))$result['logistic_number'] = $response[0]->waybill_No;

+ 16 - 14
app/Services/LogisticZopService.php

@@ -28,30 +28,32 @@ class LogisticZopService implements LogisticRouteInterface
         return json_decode($response->body());
     }
 
-    public function format($nativeResponse)
+    public function format($nativeResponse,$logistic_number)
     {
-        if (is_null($nativeResponse)||isEmpty($nativeResponse->result)) {//返回的结果为空,或者路由为[] 直接返回就好
-            return [];
-        }
-        $nativeRoutes = $nativeResponse->result;
-        $this->logistic_number = $nativeRoutes[0]->billCode;
-        $order_package = OrderPackage::query()->where('logistic_number', $this->logistic_number)->first();
-
-        $lastRoute = $nativeRoutes[count($nativeRoutes) - 1];
-
+        $order_package = OrderPackage::query()->where('logistic_number', $logistic_number)->first();
         $result = [
-            'logistic_number' => $this->logistic_number,
+            'logistic_number' => $logistic_number,
             'exception_type' => $order_package->exception_type,
-            'exception'=>$order_package->exception,
+            'exception' => $order_package->exception,
             'status' => $order_package->status,
             'transfer_status' => $order_package->transfer_status,
-            'received_at' =>$order_package->received_at,
+            'received_at' => $order_package->received_at,
         ];
+        $nativeRoutes = $nativeResponse->result??[];
+        if (empty($nativeRoutes)) {
+            $result['exception_type'] = '揽件异常';
+            $result['exception'] = '是';
+            return $result;
+        }
+        $lastRoute = $nativeRoutes[count($nativeRoutes) - 1]??[];
         list($status, $received_at) = $this->getNormalStatusAndReceivedAt($lastRoute);
         $result['status'] = $status;
         $result['received_at'] = $received_at;
         $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
         $result['routes_length'] = count($result['transfer_status']);
+        /**
+         * @var $orderPackageReceivedSyncService OrderPackageReceivedSyncService
+         */
         $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
         $lastRouteDate = Carbon::parse($lastRoute->scanDate / 1000)->addHours(8)->toDateTimeString();
         $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastRouteDate);
@@ -82,7 +84,7 @@ class LogisticZopService implements LogisticRouteInterface
             case 'SIGNED':
             case '签收':
                 $status = '已收件';
-                $received_at = Carbon::parse($lastRoute->scanDate / 1000)->toDateTimeString();
+                $received_at = Carbon::parse($lastRoute->scanDate / 1000)->addHours(8)->toDateTimeString();
                 break;
             default:
                 $status = '无';

+ 22 - 4
app/Services/MaterialBoxService.php

@@ -24,20 +24,22 @@ class MaterialBoxService
      * 获取一个空料箱
      *
      * @param array $blacklist
+     * @param integer|null $modelId
      *
      * @return MaterialBox|null
      */
-    public function getAnEmptyBox(array $blacklist = [])
+    public function getAnEmptyBox(array $blacklist = [], $modelId = null)
     {
         $id = 0;
         while (true){
             $boxes = MaterialBox::query()->select('id',"code")
                 ->whereNotIn("id",$blacklist)
                 ->where("id",">",$id)->where("code","like","IDE%")
-                ->where("status",4)->limit(10)->orderBy("id")
+                ->where("status",4)->limit(50)->orderBy("id")
                 ->whereNotIn("id",StationTaskMaterialBox::query()->select("material_box_id")
-                    ->where("status","!=","已完成")->groupBy("material_box_id"))
-                ->get();
+                    ->where("status","!=","完成")->groupBy("material_box_id"));
+            if ($modelId)$boxes->where("material_box_model_id",$modelId);
+            $boxes = $boxes->get();
             if ($boxes->count()==0)break;
             $haiBoxes = DB::connection("mysql_haiRobotics")->table("ks_bin")
                 ->where("status",1)->whereIn("ks_bin_code",array_column($boxes->toArray(),"code"))->get();
@@ -79,4 +81,20 @@ sql;
             ->where("ks_bin_code",$ide)->where("status",1)->first();
         return $bin->ks_bin_space_code ?? null;
     }
+
+    /**
+     * 检查可用料箱
+     *
+     * @param integer $boxId
+     *
+     * @return bool
+     */
+    public function checkUsableBox($boxId):bool
+    {
+        /** @var MaterialBox|\stdClass $box */
+        $box = MaterialBox::query()->find($boxId);
+        if (!$this->getBoxLocation($box->code))return false;
+        if (StationTaskMaterialBox::query()->select(DB::raw(1))->where("status","!=",'完成')->where("material_box_id",$boxId)->first())return false;
+        return true;
+    }
 }

+ 127 - 0
app/Services/MenuService.php

@@ -0,0 +1,127 @@
+<?php 
+
+namespace App\Services;
+
+use App\Authority;
+use App\Traits\ServiceAppAop;
+use App\Menu;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Facades\Cache;
+
+class MenuService
+{
+    use ServiceAppAop;
+    protected $modelClass=Menu::class;
+
+    public function getMenu()
+    {
+        if (!Cache::has("menus")){
+            if (Cache::lock("menus",2)){
+                $this->setMenu();
+                Cache::lock("menus")->release();
+            }else{
+                sleep(1);
+                return Cache::get("menus") ?? [];
+            }
+        }
+        return Cache::get("menus");
+    }
+
+    public function setMenu()
+    {
+        //如果需要热更新 为所有用户个人菜单锁定缓存 标记TAGS 在此清除 Cache::tag("tags")->flush()
+        Cache::forever("menus",Menu::query()
+            ->select("id","name","parent_id","route","font","font_style")
+            ->orderByRaw("level DESC,sequence")->get());
+    }
+
+    public function appendMenu(Menu $menu)
+    {
+        $menus = $this->getMenu();
+        if ($menus){
+            $menus->add($menu);
+            Cache::forever("menus",$menus);
+        }
+    }
+
+    //菜单与权限关联依据为 name与parent_id字段 当两个表中任意此字段发生变更 必须刷掉缓存
+    public function getVisibleFunctionList($authorities = null,&$mapping = [])
+    {
+        /** @var Collection $authorities */
+        if (!$authorities)$authorities = app("AuthorityService")->getUserAuthority();
+        $authMap = app("AuthorityService")->format($authorities);
+        $menus = $this->format($this->getMenu());
+        return array_values($this->formatMenu($menus,$authMap,$mapping));
+    }
+
+
+    /**
+     * 格式化为树状结构
+     *
+     * @param Collection $menus
+     * @return array
+     */
+    public function format($menus)
+    {
+        $menuMap = [];
+        foreach ($menus as $menu){
+            $menuMap[$menu->id] = [
+                "id" => $menu->id,
+                "child" => [],
+                "name"  => $menu->name,
+                "font"  => $menu->font,
+                "fontStyle"  => $menu->font_style,
+                "route" => $menu->route,
+            ];
+        }
+        foreach ($menus as $menu){
+            if ($menu->parent_id){
+                $menuMap[$menu->parent_id]["child"][] = $menuMap[$menu->id];
+                unset($menuMap[$menu->id]);
+            }
+        }
+        return $menuMap;
+    }
+    /**
+     * 递归格式化菜单组
+     *
+     * @param array $menus
+     * @param array $authorities
+     * @param array $mapping
+     *
+     * @return array|bool
+     */
+    private function formatMenu(array $menus,array $authorities,&$mapping=[])
+    {
+        foreach ($menus as $index=>$menu){
+            $mark = false;
+            foreach ($authorities as $j=>$authority){
+                if ($menu["name"] == $authority["name"]){
+                    $mapping[$menu["id"]] = $authority["id"];
+                    $mark = true;
+                    $authorities[$j]["mark"] = true;
+                    if ($authority["child"])$menus[$index]["child"] = array_values($this->formatMenu($menu["child"],$authority["child"],$mapping));
+                }
+            }
+            if (!$mark)unset($menus[$index]);
+        }
+        foreach ($authorities as $authority){
+            if (!isset($authority["mark"])){
+                $menus[] = [
+                    "name" => $authority["name"],
+                    "route" => "",
+                ];
+            }
+        }
+        return $menus;
+    }
+
+    /**
+     * 获取菜单与权限映射
+     */
+    public function getMenuAndAuthorityMapping()
+    {
+        $this->getVisibleFunctionList(Authority::query()->get(),$mapping);
+        return $mapping;
+    }
+}

+ 257 - 20
app/Services/NewOrderCountingRecordService.php

@@ -9,6 +9,7 @@ use App\Order;
 use App\OrderCountingRecord;
 use App\Warehouse;
 use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
@@ -18,7 +19,9 @@ use App\Traits\ServiceAppAop;
 class NewOrderCountingRecordService
 {
     use ServiceAppAop;
-    protected $modelClass=NewOrderCountingRecord::class;
+
+    protected $modelClass = OrderCountingRecord::class;
+
     public function orderCountingRecordsFromCache($start, $end, $unit, $ownerIds)
     {
         $dataList = collect();
@@ -86,22 +89,22 @@ class NewOrderCountingRecordService
     {
         $key = 'warehouseCountingRecords_' . $start . '_' . $end . '_' . json_encode($ownerIds);
         return Cache::remember($key, config('cache.expirations.warehouseCountingRecords'), function () use ($start, $end, $ownerIds) {
-        $dataList = collect();
-        $resultOrders = $this->get($start, $end, '日', $ownerIds);
-        $resultOrders->groupBy('warehouse_id')->each(function ($item) use (&$dataList) {
-            $counter = $item->reduce(function ($sum, $item) {
-                return $sum + $item->amount;
-            }, 0);
-            $warehouse = Warehouse::query()->find($item[0]->warehouse_id);
+            $dataList = collect();
+            $resultOrders = $this->get($start, $end, '日', $ownerIds);
+            $resultOrders->groupBy('warehouse_id')->each(function ($item) use (&$dataList) {
+                $counter = $item->reduce(function ($sum, $item) {
+                    return $sum + $item->amount;
+                }, 0);
+                $warehouse = Warehouse::query()->find($item[0]->warehouse_id);
 
-            $dataList->push([
-                'value' => $counter,
-                'warehouse_id' => $item[0]->warehouse_id,
-                'name' => $warehouse ? $warehouse->name : '仓库为空',
-                'code' => $warehouse ? $warehouse->code : 'NULL',
-            ]);
-        });
-        return $dataList;
+                $dataList->push([
+                    'value' => $counter,
+                    'warehouse_id' => $item[0]->warehouse_id,
+                    'name' => $warehouse ? $warehouse->name : '仓库为空',
+                    'code' => $warehouse ? $warehouse->code : 'NULL',
+                ]);
+            });
+            return $dataList;
         });
     }
 
@@ -285,10 +288,10 @@ class NewOrderCountingRecordService
 
     public function dataFromOrder($queryCondition)
     {
-        $orderSqlBuilder = Order::query()->selectRaw("owner_id,warehouse_id,shop_id,logistic_id,count(1) as amounts ,DATE_FORMAT(created_at,'%Y-%m-%d') as date_target");
+        $orderSqlBuilder = Order::query()->selectRaw("owner_id,warehouse_id,shop_id,logistic_id,count(1) as amounts ,DATE_FORMAT(updated_at,'%Y-%m-%d') as date_target");
         foreach ($queryCondition['data'] as $dateStr => $ownerIds) {
             $orderSqlBuilder->orWhere(function ($query) use ($ownerIds, $dateStr) {
-                $query->whereIn('owner_id', $ownerIds)->where('created_at', '>=', $dateStr)->where('created_at', '<', Carbon::parse($dateStr)->addDay()->toDateString())->where('wms_status', '订单完成');
+                $query->whereIn('owner_id', $ownerIds)->where('updated_at', '>=', $dateStr)->where('updated_at', '<', Carbon::parse($dateStr)->addDay()->toDateString())->where('wms_status', '订单完成');
             });
         }
         $dataFromOrder = $orderSqlBuilder->groupBy(['owner_id', 'warehouse_id', 'shop_id', 'logistic_id', 'date_target'])->get();
@@ -378,7 +381,7 @@ class NewOrderCountingRecordService
                 'logistic_id' => $order->logistic_id,
                 'date_target' => $order->date_target,
                 'counting_unit' => $unit,
-                'amount' => $order->amounts,
+                'amount' => $order->amounts ?? 0,
                 'week' => $year . '-' . $week,
                 'month' => $year . '-' . $month,
                 'year' => $year . '',
@@ -475,10 +478,244 @@ class NewOrderCountingRecordService
     private function getTtl($dateStr, $unit)
     {
         if ($this->isNotCurrentDate($dateStr, $unit)) {
-            $ttl = config('cache.expirations.forever');//非当前日期的缓存为永久
+            LogService::log('NewOrderCountingRecordService', '缓存设置为永久', $dateStr);
+            $ttl = config('cache.expirations.orderCountingRecord');//非当前日期的缓存为永久
         } else {
+            LogService::log('NewOrderCountingRecordService', '缓存设置为临时', $dateStr);
             $ttl = config('cache.expirations.orderCountingRecord');//当前日期缓存为1800s
         }
         return $ttl;
     }
+
+
+    //TODO 控制台重构
+
+    public function getWareHouseRecordsApi($start, $end, $ownerIds): array
+    {
+        $orderCountingRecords = OrderCountingRecord::query()
+            ->selectRaw("sum(amount) as value ,warehouse_id")
+            ->with('warehouse:id,name,code')
+            ->whereBetween('date_target', [$start, $end])
+            ->whereIn('owner_id', $ownerIds)
+            ->groupBy('warehouse_id')
+            ->get();
+        $result = [];
+        foreach ($orderCountingRecords as $orderCountingRecord) {
+            $result[] = [
+                'logistic_id' => $orderCountingRecord->warehouse_id,
+                'value' => $orderCountingRecord->value,
+                'name' => $orderCountingRecord->warehouse->name ?? '',
+                'code' => $orderCountingRecord->warehouse->code ?? '',
+            ];
+        }
+        return $result;
+    }
+
+    public function getLogisticRecordsApi($start, $end, $ownerIds): array
+    {
+        $orderCountingRecords = OrderCountingRecord::query()
+            ->selectRaw("sum(amount) as value ,logistic_id")
+            ->with('logistic:id,name')
+            ->whereBetween('date_target', [$start, $end])
+            ->whereIn('owner_id', $ownerIds)
+            ->groupBy('logistic_id')
+            ->get();
+        $result = [];
+        foreach ($orderCountingRecords as $orderCountingRecord) {
+            $result[] = [
+                'logistic_id' => $orderCountingRecord->logistic_id,
+                'value' => $orderCountingRecord->value,
+                'name' => $orderCountingRecord->logistic->name ?? '',
+            ];
+        }
+        return $result;
+    }
+
+    /**
+     * 查询订单量趋势
+     * @param $start string
+     * @param $end string
+     * @param $unit string
+     * @param $ownerIds array
+     * @return Builder[]
+     */
+    public function getOrderCountingRecordsApi(string $start, string $end, string $unit, array $ownerIds): array
+    {
+        $orderCountingRecords = OrderCountingRecord::query()
+            ->selectRaw("sum(amount) as counter ,date_target")
+            ->whereBetween('date_target', [$start, $end])
+            ->where('counting_unit', $unit)
+            ->whereIn('owner_id', $ownerIds)
+            ->groupBy('date_target')
+            ->get()->toArray();
+        if (now()->toDateString() == $end) {//查询时间包含当天
+            switch ($unit) {
+                case '日':
+                    //查询当天统计
+                    $startDateTime = Carbon::parse($end)->startOfDay()->toDateTimeString();
+                    $endDateTime = Carbon::parse($end)->endOfDay()->toDateTimeString();
+                    $date_format = "'%Y-%m-%d'";
+                    break;
+                case '月':
+                    //查询当月统计
+                    $startDateTime = Carbon::parse($end)->startOfMonth()->startOfDay()->toDateTimeString();
+                    $endDateTime = Carbon::parse($end)->endOfMonth()->endOfDay()->toDateTimeString();
+                    $date_format = "'%Y-%m'";
+                    break;
+                case '年':
+                    //查询当年统计
+                    $startDateTime = Carbon::parse($end)->startOfYear()->startOfDay()->toDateTimeString();
+                    $endDateTime = Carbon::parse($end)->endOfYear()->endOfDay()->toDateTimeString();
+                    $date_format = "'%Y'";
+                    break;
+            }
+            $order = Order::query()
+                ->selectRaw("count(1) as amounts ,DATE_FORMAT(updated_at,{$date_format}) as date_target")
+                ->whereBetween('updated_at', [$startDateTime, $endDateTime])
+                ->where('wms_status', '订单完成')
+                ->whereIn('owner_id', $ownerIds)
+                ->groupBy('date_target')
+                ->first();
+
+            $orderCountingRecords[] = [
+                "counter" => $order->amounts ?? 0,
+                "date_target" => $order->date_target ?? (function () use ($unit) {
+                        switch ($unit) {
+                            case '日':
+                                return now()->toDateString();
+                            case '月':
+                                return now()->startOfMonth()->toDateString();
+                            case '年':
+                                return now()->startOfYear()->toDateString();
+                        }
+                    })(),
+            ];
+        }
+        return $orderCountingRecords;
+    }
+
+    /**
+     * 统计订单量 从$start 开始统计 默认截止到当前日期的前一天
+     * @param $start string
+     * @param null $end string
+     * @param $unit string
+     */
+    public function recordOrder(string $start, $end = null, string $unit = '日')
+    {
+        switch ($unit) {
+            case '日':
+                $this->recordByDay($start, $end, $unit);
+                break;
+            case'月':
+                $this->recordByMonth($start, $end, $unit);
+                break;
+            case'年':
+                $this->recordByYear($start, $end, $unit);
+                break;
+            default:
+        }
+    }
+
+    /**
+     * 清空统计缓存
+     */
+    public function clearCacheOrderRecord()
+    {
+
+    }
+
+    /**
+     * 日统计
+     * @param string $start
+     * @param $end
+     * @param string $unit
+     */
+    public function recordByDay(string $start, $end = null, string $unit = '日'): void
+    {
+        $startDateTime = Carbon::parse($start)->startOfDay()->toDateTimeString();
+        if (is_null($end)) {
+            $end = now()->subDay()->endOfDay();
+        }
+        $endDateTime = Carbon::parse($end)->endOfDay()->toDateTimeString();
+        $orders = Order::query()
+            ->selectRaw("owner_id,warehouse_id,logistic_id,count(1) as amounts ,DATE_FORMAT(updated_at,'%Y-%m-%d') as date_target")
+            ->whereBetween('updated_at', [$startDateTime, $endDateTime])
+            ->where('wms_status', '订单完成')
+            ->groupBy('owner_id', 'warehouse_id', 'logistic_id', 'date_target')
+            ->get();
+        $insertData = [];
+        foreach ($orders as $order) {
+            $insertData[] = [
+                'owner_id' => $order->owner_id,
+                'warehouse_id' => $order->warehouse_id,
+                'logistic_id' => $order->logistic_id,
+                'date_target' => $order->date_target,
+                'counting_unit' => $unit,
+                'amount' => $order->amounts ?? 0,
+                'year' => Carbon::parse($order->date_target)->year,
+                'month' => Carbon::parse($order->date_target)->year . '-' . Carbon::parse($order->date_target)->month,
+            ];
+        }
+        $insertDataChunked = array_chunk($insertData, 2000);
+        foreach ($insertDataChunked as $items) {
+            OrderCountingRecord::query()->insertOrIgnore($items);
+        }
+    }
+
+
+    public function recordByMonth(string $start, $end = null, $unit = '月')
+    {
+        $startDate = Carbon::parse($start)->startOfMonth()->toDateString();
+        if (is_null($end)) {
+            $end = now()->subMonth()->endOfDay();
+        }
+        $endDate = Carbon::parse($end)->endOfDay()->toDateString();
+        $orderCountingRecords = OrderCountingRecord::query()
+            ->selectRaw("owner_id,warehouse_id,logistic_id,sum(amount) as amount_sum,month,year,date_target")
+            ->whereBetween('date_target', [$startDate, $endDate])
+            ->where('counting_unit', '日')
+            ->groupBy('owner_id', 'warehouse_id', 'logistic_id', 'month', 'date_target')
+            ->get();
+        $insertData = [];
+        foreach ($orderCountingRecords as $orderCountingRecord) {
+            $insertData[] = [
+                'owner_id' => $orderCountingRecord->owner_id,
+                'warehouse_id' => $orderCountingRecord->warehouse_id,
+                'logistic_id' => $orderCountingRecord->logistic_id,
+                'counting_unit' => $unit,
+                'date_target' => Carbon::parse($orderCountingRecord->date_target)->startOfMonth()->toDateString(),
+                'amount' => $orderCountingRecord->amount_sum,
+                'year' => $orderCountingRecord->year,
+                'month' => $orderCountingRecord->month,
+            ];
+        }
+        OrderCountingRecord::query()->insertOrIgnore($insertData);
+    }
+
+    public function recordByYear(string $start, $end = null, $unit = '年')
+    {
+        $startYear = Carbon::parse($start)->year;
+        if (is_null($end)) {
+            $end = now()->subYear()->toDateString();
+        }
+        $endYear = Carbon::parse($end)->year;
+        $orderCountingRecords = OrderCountingRecord::query()
+            ->selectRaw("owner_id,warehouse_id,logistic_id,sum(amount) as amount_sum,year,date_target")
+            ->whereBetween('year', [$startYear, $endYear])
+            ->groupBy('owner_id', 'warehouse_id', 'logistic_id', 'year')
+            ->get();
+        $insertData = [];
+        foreach ($orderCountingRecords as $orderCountingRecord) {
+            $insertData[] = [
+                'owner_id' => $orderCountingRecord->owner_id,
+                'warehouse_id' => $orderCountingRecord->warehouse_id,
+                'logistic_id' => $orderCountingRecord->logistic_id,
+                'counting_unit' => $unit,
+                'date_target' => Carbon::parse($orderCountingRecord->date_target)->startOfYear()->toDateString(),
+                'amount' => $orderCountingRecord->amount_sum,
+                'year' => $orderCountingRecord->year,
+            ];
+        }
+        OrderCountingRecord::query()->insertOrIgnore($insertData);
+    }
 }

+ 10 - 6
app/Services/OrderPackageReceivedSyncService.php

@@ -49,7 +49,7 @@ class OrderPackageReceivedSyncService
             //sf
             if (array_key_exists('SF', $logisticNumbers)) {
                 $SFLogisticNumbers = $logisticNumbers['SF'];
-                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-SF", '');
+                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-SF", $SFLogisticNumbers);
                 foreach ($SFLogisticNumbers as $logisticNumber) {
                     LogisticSFSync::dispatch($logisticNumber);
                 }
@@ -57,7 +57,7 @@ class OrderPackageReceivedSyncService
             //更新中通
             if (array_key_exists('ZTO', $logisticNumbers)) {
                 $ZTOLogisticNumbers = $logisticNumbers['ZTO'];
-                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-ZTO", '');
+                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-ZTO", $ZTOLogisticNumbers);
                 foreach ($ZTOLogisticNumbers as $logisticNumber) {
                     LogisticZopSync::dispatch($logisticNumber);
                 }
@@ -65,7 +65,7 @@ class OrderPackageReceivedSyncService
             //更新韵达
             if (array_key_exists('YUNDA', $logisticNumbers)) {
                 $YDLogisticNumbers = $logisticNumbers['YUNDA'];
-                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YUNDA", '');
+                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YUNDA", $YDLogisticNumbers);
                 foreach ($YDLogisticNumbers as $logistic_number) {
                     LogisticYDSync::dispatch($logistic_number);
                 }
@@ -73,7 +73,7 @@ class OrderPackageReceivedSyncService
             //更新圆通
             if (array_key_exists('YTO', $logisticNumbers)) {
                 $YTOLogisticNumbers = $logisticNumbers['YTO'];
-                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YTO", '');
+                LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法-YTO", $YTOLogisticNumbers);
                 foreach ($YTOLogisticNumbers as $logistic_number) {
                     LogisticYTOSync::dispatch($logistic_number);
                 }
@@ -210,6 +210,7 @@ class OrderPackageReceivedSyncService
             try {
                 $logisticCode = $orderPackage->order->logistic->code;
             } catch (Exception $e) {
+                LogService::log(OrderPackageReceivedSyncService::class, "快递同步按照承运商分组异常", $orderPackage->id);
                 continue;
             }
             $key = config('api_logistic.logistic.' . $logisticCode);
@@ -229,6 +230,9 @@ class OrderPackageReceivedSyncService
      */
     public function setExceptionType(array $data, $lastRouteDate): array
     {
+        //设置默认异常为否
+        $data['exception_type'] = '无';
+        $data['exception'] = '否';
         $logistic_number = $data['logistic_number'];
         /** @var OrderPackage $orderPackage */
         $orderPackage = OrderPackage::query()->with('order')->where('logistic_number', $logistic_number)->first();
@@ -341,7 +345,7 @@ class OrderPackageReceivedSyncService
             $conclusion |= ($last_routed_duration > $SHORT_RESPONSE_HOURS && $last_routed_duration < $LONG_RESPONSE_HOURS) ? $IS_SHORT_NO_RESPONSE : 0;
             $conclusion |= ($last_routed_duration > $LONG_RESPONSE_HOURS) ? $IS_LONG_NO_RESPONSE : 0;
             $conclusion |= ($last_routed_duration > $SENDING_RESPONSE_HOURS && $data['status'] == '派送中') ? $IS_SENDING_NO_RESPONSE : 0;
-            $conclusion |= ($delivered_duration > $HAVEN_SECOND_GOT_HOURS && $data['routes_length'] < 3) ? $IS_SECOND_ROUTE_HAVE : 0;//超过指定时间,路由信息小于两
+            $conclusion |= ($delivered_duration > $HAVEN_SECOND_GOT_HOURS && $data['routes_length'] < 3) ? $IS_SECOND_ROUTE_HAVE : 0;//和出库时间比较 超过指定时间,路由信息小于三
             return $conclusion;
         })();
         switch ($conclusion) {
@@ -368,7 +372,7 @@ class OrderPackageReceivedSyncService
         }
         if ($conclusion
             == ($conclusion | $IS_SECOND_ROUTE_HAVE)) {
-            $data['exception_type'] = '件异常';
+            $data['exception_type'] = '件异常';
             $data['exception'] = '是';
 
         }

+ 95 - 0
app/Services/OwnerLogisticFeeDetailService.php

@@ -0,0 +1,95 @@
+<?php
+
+namespace App\Services;
+
+use App\OwnerFeeDetail;
+use App\Traits\ServiceAppAop;
+use App\OwnerLogisticFeeDetail;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Collection;
+
+class OwnerLogisticFeeDetailService
+{
+    use ServiceAppAop;
+
+    /**
+     * @var $modelClass  OwnerLogisticFeeDetail
+     */
+    protected $modelClass = OwnerLogisticFeeDetail::class;
+
+    //插入数据 ServiceAppAop的 insert 方法 支持批量
+
+    /**
+     * 根据货主查询 和时间段查询
+     * @param string $owner_id
+     * @param string $start
+     * @param string $end
+     * @return array
+     */
+    public function getDetails(string $owner_id, string $start, string $end): array
+    {
+        $ownerFeeDetailIds = OwnerFeeDetail::query()->selectRaw('id')
+            ->where('type', '发货')
+            ->where('outer_table_name', 'orders')
+            ->whereHas('logistic', function (Builder $query) {
+                $query->where('type', '快递');
+            })
+            ->where('owner_id', $owner_id)
+            ->where('worked_at', '>=', Carbon::parse($start)->startOfDay())
+            ->where('worked_at', '<=', Carbon::parse($end)->endOfDay())->pluck('id');
+        $ownerLogisticFeeDetails = OwnerLogisticFeeDetail::query()->with(['ownerFeeDetail.logistic', 'ownerFeeDetailLogistic'])->whereIn('owner_fee_detail_id', $ownerFeeDetailIds)->paginate();
+        dd($ownerLogisticFeeDetails);
+
+//         $ownerFeeDetails = OwnerFeeDetail::query()
+//            ->with(['ownerLogisticFeeDetail:id,logistic_bill,initial_weight_price,additional_price', 'items.logistic:id,name','items.ownerLogisticFeeDetail:id,logistic_bill,initial_weight_price,additional_price', 'logistic:id,name,type'])
+//            ->where('type', '发货')
+//            ->where('outer_table_name', 'orders')
+//            ->whereHas('logistic', function (Builder $query) {
+//                $query->where('type', '快递');
+//            })
+//            ->where('owner_id', $owner_id)
+//            ->where('worked_at', '>=', Carbon::parse($start)->startOfDay())
+//            ->where('worked_at', '<=', Carbon::parse($end)->endOfDay())
+//            ->get();
+//        $result = [];
+//        foreach ($ownerFeeDetails as $ownerFeeDetail) {
+//            if ($ownerFeeDetail->items->count()==0) {//只有一个包裹
+//                $result[] = [
+//                    'logistic_name' => $ownerFeeDetail->logistic->name ?? '',//快递公司
+//                    'province' => $ownerFeeDetail->province,//省份
+//                    'logistic_bill' => $ownerFeeDetail->logistic_bill ?? '',//快递单号
+//                    'weight' => $ownerFeeDetail->weight,//重量
+//                    'logistic_fee' => $ownerFeeDetail->logistic_fee,//快递费
+//                    'initial_weight_price' => $ownerFeeDetail->ownerLogisticFeeDetail->initial_weight_price ?? '',//首重价格
+//                    'additional_price' => $ownerFeeDetail->ownerLogisticFeeDetail->additional_price ?? '',//续重价格
+//                ];
+//            } else {//多个包裹
+//                foreach ($ownerFeeDetail->items as $ownerFeeDetailLogistic) {
+//                    $result[] = [
+//                        'logistic_name' => $ownerFeeDetail->logistic->name ?? '',//快递公司
+//                        'province' => $ownerFeeDetail->province,//省份
+//                        'logistic_bill' => $ownerFeeDetailLogistic->logistic_bill,//快递单号
+//                        'weight' => $ownerFeeDetailLogistic->weight,//重量
+//                        'logistic_fee' => $ownerFeeDetailLogistic->logistic_fee,//快递费
+//                        'initial_weight_price' => $ownerFeeDetailLogistic->ownerLogisticFeeDetail->initial_weight_price ?? '',//首重价格
+//                        'additional_price' => $ownerFeeDetailLogistic->ownerLogisticFeeDetail->additional_price ?? '',//续重价格
+//                    ];
+//                }
+//            }
+//        }
+        $result = [];
+        foreach ($ownerLogisticFeeDetails->items() as $ownerLogisticFeeDetail) {
+                $result[] = [
+                    'logistic_name' => $ownerLogisticFeeDetail->ownerFeeDetail->logistic->name ?? '',//快递公司
+                    'province' => $ownerLogisticFeeDetail->ownerFeeDetail->province,//省份
+                    'logistic_bill' => $ownerLogisticFeeDetail->logistic_bill ?? '',//快递单号
+                    'weight' => $ownerLogisticFeeDetail->ownerFeeDetailLogistic->weight,//重量
+                    'logistic_fee' => $ownerLogisticFeeDetail->ownerFeeDetailLogistic->logistic_fee,//快递费
+                    'initial_weight_price' => $ownerLogisticFeeDetail->initial_weight_price ?? '',//首重价格
+                    'additional_price' => $ownerLogisticFeeDetail->additional_price ?? '',//续重价格
+                ];
+        }
+        return $result;
+    }
+}

+ 13 - 0
app/Services/OwnerLogisticFeeReportService.php

@@ -0,0 +1,13 @@
+<?php 
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\OwnerLogisticFeeReport;
+
+class OwnerLogisticFeeReportService
+{
+    use ServiceAppAop;
+    protected $modelClass=OwnerLogisticFeeReport::class;
+
+}

+ 5 - 1
app/Services/PackageStatisticsService.php

@@ -25,10 +25,14 @@ class PackageStatisticsService
             ->leftJoin('orders','order_packages.order_id','orders.id')
                 ->selectRaw('orders.owner_id,logistic_id');
 
+        if ($params["logistic_id"] ?? false){
+            $logistics = explode(",",$params["logistic_id"]);
+            $query->whereIn("logistic_id",$logistics);
+            unset($params["logistic_id"]);
+        }
         $columnQueryRules=[
             'created_at_start' => ['alias' => 'weighed_at','startDate' => ":00"],
             'created_at_end' => ['alias' => 'weighed_at','endDate' => ":59"],
-            'logistic_id' => ['multi' => ','],
             'owner_id' => ['multi' => ','],
         ];
         $query = $query->groupBy('order_packages.owner_id','logistic_id');

+ 1 - 0
app/Services/RejectedService.php

@@ -128,6 +128,7 @@ class RejectedService
             ->selectRaw('rejected_bill_items.created_at item_created_at,
                 rejected_bill_items.barcode_goods item_barcode,
                 rejected_bill_items.name_goods item_name,
+                rejected_bill_items.remark item_remark,
                 rejected_bill_items.amount item_amount,
                 rejected_bill_items.batch_number item_batch_number,
                 rejected_bill_items.made_at item_made_at,

+ 33 - 0
app/Services/RoleService.php

@@ -0,0 +1,33 @@
+<?php 
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\Role;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
+
+class RoleService
+{
+    use ServiceAppAop;
+    protected $modelClass=Role::class;
+
+
+    /**
+     * 清除角色对应的用户权限
+     *
+     * @param integer $roleId
+     * @param bool $isAuthority
+     * @param bool $isOwner
+     * @param bool $isUserWorkGroup
+     */
+    public function clearUserAuthority($roleId,bool $isAuthority = true,bool $isOwner = false,bool $isUserWorkGroup = false)
+    {
+        $ids = array_column(DB::select(DB::raw("SELECT id_user FROM user_role WHERE id_role = ?"),[$roleId]),"id_user");
+        foreach ($ids as $id){
+            if ($isAuthority)Cache::forget("authorities:user_".$id);
+            if ($isOwner)Cache::forget("owners:user_".$id);
+            if ($isUserWorkGroup)Cache::forget("userWorkGroups:user_".$id);
+        }
+    }
+}

+ 16 - 0
app/Services/StationService.php

@@ -9,6 +9,7 @@ use App\Station;
 use App\StationTask;
 use App\StationType;
 use Exception;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Facades\Cache;
 use App\Traits\ServiceAppAop;
 
@@ -90,4 +91,19 @@ class StationService
         $this->broadcast($station_id, $stationTask);
     }
 
+    /**
+     * 获取镜像映射库位
+     *
+     * @param string $mirrorLocation
+     *
+     * @return Model|null
+     */
+    public function getMirrorMappingLocation($mirrorLocation)
+    {
+        $station = Station::query()->select("parent_id")->where("code",$mirrorLocation)->first();
+        if (!$station)return null;
+        return Station::query()->where("station_type_id",5)
+            ->where("id",$station->parent_id)->first();
+    }
+
 }

+ 22 - 4
app/Services/StationTaskMaterialBoxService.php

@@ -41,6 +41,8 @@ class StationTaskMaterialBoxService
     private $materialBoxService;
     /** @var CacheShelfService $cacheShelfService */
     private $cacheShelfService;
+    /** @var StorageService $storageService */
+    private $storageService;
     public function __construct(){
         $this->stationService=null;
         $this->stationTypeService=null;
@@ -151,6 +153,7 @@ class StationTaskMaterialBoxService
         $this->instant($this->stationTaskService,'StationTaskService');
         $this->instant($this->stationService,'StationService');
         $this->instant($this->cacheShelfService,'CacheShelfService');
+        $this->instant($this->storageService,'StorageService');
         try{
             LogService::log('海柔请求','markHasTaken1','');
             $taskType=$this->getServingTaskType($stationTaskMaterialBox);
@@ -169,25 +172,40 @@ class StationTaskMaterialBoxService
                     $stationTaskMaterialBox->materialBox->update();
                     break;
                 case '入立库':
-                    $this->set($stationTaskMaterialBox,[
-                        'id' => $stationTaskMaterialBox['station_id'],
-                        'status' => '完成',
-                    ]);
                     $this->cacheShelfService->putStationTaskMaterialBoxProcess($stationTaskMaterialBox);
                     $stationTaskMaterialBox->materialBox['status']='在立库';
                     $stationTaskMaterialBox->materialBox->update();
+                    $stationTaskMaterialBox->loadMissing("station");    //提前加载站,后续都需要站信息来处理
+                    $this->storageService->releaseOccupation($stationTaskMaterialBox); //释放库位占用
+                    $this->storageService->checkMark($stationTaskMaterialBox); //检查标记并做一些特殊处理
                     break;
                 case '入缓存架':
                     $stationTaskMaterialBox->materialBox['status']='在缓存架';
                     $stationTaskMaterialBox->materialBox->update();
+                    $this->storageService->putCacheShelf($stationTaskMaterialBox);
                     break;
                 default:;
             }
+            $this->taskCompleted($stationTaskMaterialBox);
         }catch (\Exception $e){
             throw new ErrorException('放置料箱出错');
         }
     }
 
+    private function taskCompleted($stationTaskMaterialBox)
+    {
+        $this->set($stationTaskMaterialBox,[
+            'id' => $stationTaskMaterialBox['station_id'],
+            'status' => '完成',
+        ]);
+        if (!$stationTaskMaterialBox->station_task_id)return;
+        $task = StationTaskMaterialBox::query()->select(DB::raw(1))
+            ->where("station_task_id",$stationTaskMaterialBox->station_task_id)
+            ->where("status","!=","完成")->first();
+        if (!$task)StationTask::query()->where("id",$stationTaskMaterialBox->station_task_id)
+            ->update(["status"=>"完成"]);
+    }
+
     // TODO 料箱处理
     function markHasTaken($stationTaskMaterialBox)
     {

+ 431 - 7
app/Services/StorageService.php

@@ -2,12 +2,18 @@
 
 namespace App\Services;
 
+use App\CommodityMaterialBoxModel;
+use App\Station;
 use App\StationTask;
 use App\StationTaskMaterialBox;
+use App\TaskTransaction;
 use App\Traits\ServiceAppAop;
 use App\Storage;
-use Illuminate\Database\Eloquent\Builder;
+use App\ValueStore;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\DB;
 
 class StorageService
 {
@@ -44,18 +50,436 @@ class StorageService
         }
         app("ForeignHaiRoboticsService")->fetchGroup_multiLocation($stationCollection,$collection,'','立架出至缓存架');
     }
+
+    /**
+     * 缓存架放置记录
+     *
+     * @param StationTaskMaterialBox|\stdClass $stationTaskMaterialBox
+     */
+    public function putCacheShelf($stationTaskMaterialBox)
+    {
+        DB::beginTransaction();
+        try{
+            $storage = Storage::query()->where("material_box_id",$stationTaskMaterialBox->material_box_id)->lockForUpdate()->first();
+            if ($storage)$storage->update(["station_id"=>$stationTaskMaterialBox->station_id,'status'=>0]);
+            else Storage::query()->create([
+                "station_id" => $stationTaskMaterialBox->station_id,
+                "material_box_id" => $stationTaskMaterialBox->material_box_id,
+            ]);
+            DB::commit();
+        }catch (\Exception $e){
+            DB::rollBack();
+        }
+    }
+
+    /**
+     * 释放库位占用
+     *
+     * @param StationTaskMaterialBox|\stdClass $stationTaskMaterialBox
+     */
+    public function releaseOccupation($stationTaskMaterialBox)
+    {
+        if ($stationTaskMaterialBox->station->station_type_id != 5)return;
+        $storage = Storage::query()->where("material_box_id",$stationTaskMaterialBox->material_box_id)->first();
+        if (!$storage)return;
+        $update = [];
+        if ($storage->status == 1)$update["status"] = 0;
+        if ($storage->station_id)$update["station_id"] = null;
+        if ($update)$storage->update($update);
+    }
+
     /**
-     * 标记指定库位为占用
+     * 检查临时事务标记处理一些特殊情况
      *
-     * @param string $location
+     * @param StationTaskMaterialBox|\stdClass $stationTaskMaterialBox
+     */
+    public function checkMark($stationTaskMaterialBox)
+    {
+        $task = TaskTransaction::query()->where("material_box_id",$stationTaskMaterialBox->material_box_id)
+            ->where("status",0)->first();
+        if (!$task)return;
+        //蓝灯闪烁
+        if ($task->type == '入库' && $task->mark == 1)app("CacheShelfService")->stationLightUp($stationTaskMaterialBox->station->code,null,'2','2');
+    }
+
+    /**
+     * 检查存储 根据事务表做处理
+     *
+     * @param Station|\stdClass $station
+     *
+     * @return bool
+     *
+     * @throws
+     */
+    public function checkStorage($station)
+    {
+        $task = TaskTransaction::query()->with("materialBox")->where("fm_station_id",$station->id)
+            ->where("status",0)->first();
+        if (!$task)return true;
+        //建立入库任务,通知入库,完善库存
+        if ($task->type == '入库' && $task->mark == 1){
+            DB::beginTransaction();
+            try{
+                //get flux
+                $asns = app("StorageService")->getFluxTask($task->doc_code,$task->bar_code,$task->amount);
+                if (!$asns)return false;
+                $ide = $task->materialBox->code;
+                DB::connection("oracle")->beginTransaction();
+                try{
+                    foreach ($asns as $asn)if (!$this->fluxPA($asn,$ide,(int)$asn->fmqty)){
+                        DB::connection("oracle")->rollBack();
+                        return false;
+                    };
+                    DB::connection("oracle")->commit();
+                }catch(\Exception $e){
+                    DB::connection("oracle")->rollBack();
+                    return false;
+                }
+                $taskMaterialBox = $this->createWarehousingTask($station->id,$task->material_box_id);//建立入库任务
+                if (!$this->enterWarehouse($station->id,$task->material_box_id,$task->commodity_id,$task->amount))throw new \Exception("库存异常"); //处理库存
+                $task->update([
+                    "task_id" => $taskMaterialBox->id,
+                    "status" => 1,
+                    "user_id" => Auth::id(),
+                ]);//标记事务完成
+                $collection = new Collection([$taskMaterialBox]);
+                app("ForeignHaiRoboticsService")->fetchGroup($station->code,$collection,'','缓存架入立架'); //呼叫机器人入库
+                DB::commit();
+                return true;
+            }catch(\Exception $e){
+                DB::rollBack();
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 建立入库任务
+     *
+     * @param $stationId
+     * @param $boxId
+     *
+     * @return Model|\stdClass
+     */
+    public function createWarehousingTask($stationId,$boxId)
+    {
+        /** @var StationTask|\stdClass $task */
+        $task = StationTask::query()->create([
+            'status' => "待处理",
+            'station_id' => $stationId,
+        ]);
+        return StationTaskMaterialBox::query()->create([
+            'station_id' => $stationId,
+            'material_box_id'=>$boxId,
+            'status'=>"待处理",
+            'type' => '放',
+            'station_task_id' => $task->id,
+        ]);
+    }
+
+    /**
+     * 库存入库
+     *
+     * @param integer $stationId
+     * @param integer $boxId
+     * @param integer $commodityId
+     * @param integer $amount
+     * @param integer $modelId
+     *
+     * @return bool
+     */
+    public function enterWarehouse($stationId, $boxId, $commodityId, $amount, $modelId = null)
+    {
+        DB::beginTransaction();
+        try{
+            $storage = Storage::query()->where("material_box_id",$boxId)->lockForUpdate()->first();
+            $obj = [
+                "station_id" => $stationId,
+                "material_box_id" => $boxId,
+                "commodity_id" => $commodityId,
+                "amount" => $amount,
+                "status" => 1,
+            ];
+            if ($storage){
+                $obj["amount"] = DB::raw("amount+{$amount}");
+                $storage->update($obj);
+                $amount = (int)$storage->amount + (int)$amount;
+            } else Storage::query()->create($obj);
+            if ($commodityId && $modelId){
+                //维护料箱最大上限 用于半箱补货
+                $model = CommodityMaterialBoxModel::query()->select("maximum")->where("commodity_id",$commodityId)
+                    ->where("material_box_model_id",$modelId)->first();
+                if (!$model)CommodityMaterialBoxModel::query()->create(["commodity_id"=>$commodityId,"material_box_model_id"=>$modelId,"maximum"=>$amount]);
+                if ($model && $model->maximum < $amount)$model->update(["maximum"=>$amount]);
+            }
+            DB::commit();
+            return true;
+        }catch(\Exception $e){
+            DB::rollBack();
+            return false;
+        }
+    }
+
+    /**
+     * 获取FLUX上架任务列表
+     *
+     * @param string $asn
+     * @param string $barCode
+     * @param int $amount
+     *
+     * @return array|null
+     */
+    public function getFluxTask($asn,$barCode,$amount):?array
+    {
+        $sql = <<<sql
+SELECT * FROM DOC_ASN_DETAILS LEFT JOIN BAS_SKU ON DOC_ASN_DETAILS.CUSTOMERID = BAS_SKU.CUSTOMERID AND DOC_ASN_DETAILS.SKU = BAS_SKU.SKU
+LEFT JOIN TSK_TASKLISTS ON DOC_ASN_DETAILS.ASNNO = TSK_TASKLISTS.DOCNO AND DOC_ASN_DETAILS.ASNLINENO = TSK_TASKLISTS.DOCLINENO
+WHERE ASNNO = ? AND (ALTERNATE_SKU1 = ? OR ALTERNATE_SKU2 = ? OR ALTERNATE_SKU3 = ?) AND RECEIVEDQTY >= ?
+  AND TASKPROCESS = '00' AND TASKTYPE = 'PA'
+sql;
+        $asns = DB::connection("oracle")->select(DB::raw($sql),[$asn,$barCode,$barCode,$barCode,$amount]);
+        if (!$asns)return null;
+        $nums = [];
+        foreach ($asns as $index=>$asn){
+            if ((int)$asn->fmqty == $amount)return [$asn];
+            $nums[] = (int)$asn->fmqty;
+        }
+        $result = $this->twoSum($nums,$amount);
+        if ($result)return [$asns[$result[0]],$asns[$result[1]]];
+        return null;
+    }
+
+    /**
+     * 获取匹配数字
+     *
+     * @param Integer[] $nums
+     * @param Integer $target
+     * @return Integer[]|null
+     */
+    protected function twoSum($nums, $target) {
+        $map=[];
+        for($i=0;$i<count($nums);$i++){
+            $complement=$target-$nums[$i];
+            if(array_key_exists($complement,$map)){
+                return [$map[$complement],$i];
+            }
+            $map[$nums[$i]]=$i;
+        }
+        return null;
+    }
+
+    /**
+     * flux上架
+     *
+     * @param $asn
+     * @param $ide
+     * @param $amount
+     * @return bool
+     * @throws \Throwable
+     */
+    public function fluxPA($asn,$ide,$amount)
+    {
+        if (!$asn->taskid)return false;//ASN单无此入库信息,禁止上架
+
+        $sql = <<<sql
+SELECT * FROM inv_lot_loc_id  WHERE lotnum = ? AND traceid = ? AND customerid= ?  and sku = ?
+sql;
+        $inv = DB::connection("oracle")->select(DB::raw($sql),[$asn->fmlotnum,$asn->plantoid,$asn->customerid,$asn->sku]);
+        if (count($inv)==0)return false;//余量与入库不符
+        DB::connection("oracle")->transaction(function ()use($inv,$amount,$ide,$asn,&$who){
+            $db = DB::connection("oracle");
+            $qty = $amount;
+            foreach ($inv as $in){
+                if ($qty==0)break;
+                if ($in->qty > $qty){
+                    $db->update(DB::raw("update inv_lot_loc_id set qty = qty-?,qtymvout = qty-? where lotnum = ? and locationid = ? and traceid = ?"),[
+                        $qty,$qty,$in->lotnum,$in->locationid,$in->traceid
+                    ]);//TODO 遗留问题:对应生成分配库位上架数量未被变更
+                    $in->qty = $in->qty-$qty;
+                    $qty = 0;
+                }else{
+                    $db->delete(DB::raw("DELETE FROM inv_lot_loc_id WHERE lotnum = ? and locationid = ? and traceid = ?"),[
+                        $in->lotnum,$in->locationid,$in->traceid
+                    ]);
+                    $qty = $qty-$in->qty;
+                }
+            }
+            $db->delete(DB::raw("DELETE FROM inv_lot_loc_id WHERE lotnum = ? AND traceid = ? AND traceid != '*'  AND qty = 0"),[
+                $inv[0]->lotnum,$inv[0]->traceid
+            ]);
+            $invHistory = $db->selectOne(DB::raw("SELECT * FROM inv_lot_loc_id WHERE lotnum = ? AND locationid = ? AND customerid = ? AND sku = ? AND traceid = '*' FOR UPDATE"),[
+                $inv[0]->lotnum,$ide,$inv[0]->customerid,$inv[0]->sku
+            ]);
+            $who = 'WAS'.(Auth::user() ? '-'.Auth::user()["name"] : '');
+            if ($invHistory)$db->update(DB::raw("UPDATE inv_lot_loc_id SET qty = qty+? WHERE lotnum = ? AND locationid = ? AND traceid = '*'"),[
+                (int)$amount,$inv[0]->lotnum,$ide
+            ]);
+            else $db->insert(DB::raw("INSERT INTO inv_lot_loc_id VALUES(?,?,'*',?,?,?,0,0,0,0,0,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,0,0,0,0,0,'*',0,null)"),[
+                $inv[0]->lotnum,$ide,$inv[0]->customerid,$inv[0]->sku,$amount,date("Y-m-d H:i:s"),$who,
+                date("Y-m-d H:i:s"),$who
+            ]);
+            $sql = <<<sql
+INSERT INTO ACT_TRANSACTION_LOG VALUES(?,'PA',?,?,?,?,'ASN',?,?,?,?,?,?,?,?,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,
+TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,0,0,0,0,TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),?,?,null,null,null,'*',?,?,?,?,?,?,?,
+?,?,?,?,?,'N',null,?,?,?,?,?,?,?,null,null)
+sql;
+            list($trid,$max) = $this->getTrNumber();
+            $db->insert(DB::raw($sql),[
+                $trid,$asn->customerid,$asn->sku,
+                $asn->asnno,$asn->asnlineno,$inv[0]->lotnum,$asn->fmlocation,$asn->plantoid,$asn->packid,$asn->uom,$amount,$amount,'99',date("Y-m-d H:i:s"),$who,
+                date("Y-m-d H:i:s"),$who,date("Y-m-d H:i:s"),$asn->customerid,$asn->sku,$ide,$who,$asn->packid,$asn->uom,$amount,$amount,$inv[0]->lotnum,
+                '*','0','N','*',$asn->taskid_sequence,$asn->warehouseid,$asn->userdefine1,$asn->userdefine2,
+                $asn->userdefine3,$asn->userdefine4,$asn->userdefine5,'O'
+            ]);
+            $this->setTrNumber($max);
+            $sql = <<<sql
+update TSK_TASKLISTS set TASKPROCESS = '99',REASONCODE = 'OK',PLANTOLOCATION = ?,PLANLOGICALTOSEQUENCE = ?,
+CREATE_TRANSACTIONID = ?,OPENWHO = ?,OPENTIME = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),
+ CLOSEWHO = ?,CLOSETIME = ?,EDITTIME = ?,EDITWHO = ?
+ where taskid = ? AND TASKID_SEQUENCE = ?
+sql;
+            $db->update(DB::raw($sql),[
+                $ide,$ide,$trid,$who,date("Y-m-d H:i:s"),$who,date("Y-m-d H:i:s"),date("Y-m-d H:i:s"),$who,$asn->taskid,$asn->taskid_sequence
+            ]);
+        });
+        //成功后应去修改ASN状态及数量 暂时不知上架后ASN应为状态
+        /*        $sql = <<<sql
+        UPDATE doc_asn_details SET linestatus = ?,edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ? AND asnlineno = ?
+        sql;*/
+        //if ($asn->expectedqty>$asn->receivedqty && $asn->linestatus!='30')DB::connection("oracle")->update(DB::raw($sql),['30',date("Y-m-d H:i:s"),$who,$asn->asnno,$asn->asnlineno]);
+        if ($asn->expectedqty==$asn->receivedqty && $asn->linestatus=='40'){
+            //DB::connection("oracle")->update(DB::raw($sql),['40',date("Y-m-d H:i:s"),$who,$asn->asnno,$asn->asnlineno]);
+            $check = DB::connection("oracle")->selectOne(DB::raw("SELECT 1 FROM DOC_ASN_DETAILS WHERE ASNNO = ? AND LINESTATUS != '40'"),[$asn->asnno]);
+            if (!$check){
+                $logs = DB::connection("oracle")->select(DB::raw("SELECT SUM(FMQTY) qty,TRANSACTIONTYPE FROM ACT_TRANSACTION_LOG WHERE DOCNO = ? AND TRANSACTIONTYPE IN ('PA','IN') GROUP BY TRANSACTIONTYPE"),[$asn->asnno]);
+                $paQty = 0;
+                $inQty = 0;
+                foreach ($logs as $log){
+                    if ($log->transactiontype == 'IN')$inQty = $log->qty;
+                    else $paQty = $log->qty;
+                }
+                if ($paQty == $inQty){
+                    DB::connection("oracle")->update(DB::raw("UPDATE DOC_ASN_HEADER SET asnstatus = '99',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
+                        [date("Y-m-d H:i:s"),$who,$asn->asnno]);
+                    DB::connection("oracle")->update(DB::raw("UPDATE DOC_ASN_DETAILS SET linestatus = '99',edittime = TO_DATE(?,'yyyy-mm-dd hh24:mi:ss'),editwho = ? WHERE asnno = ?"),
+                        [date("Y-m-d H:i:s"),$who,$asn->asnno]);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * put cache rack box to warehousing(将缓存架料箱入库)
+     *
+     * @param string $fromLocation
+     * @param integer $boxId
      *
      * @return int
      */
-    public function markOccupy($location)
+    public function putWareHousing(string $fromLocation, $boxId):?int
+    {
+        $station = Station::query()->select("id")
+            ->where("station_type_id",5)->where("code",$fromLocation)->first();
+        if (!$station)return null;
+        if (StationTask::query()->select("id")->where("status","!=",'完成')->where("station_id",$station->id)->first())return null;
+        /** @var StationTaskMaterialBox|\stdClass $stmb */
+        $stmb = $this->createWarehousingTask($station->id,$boxId);
+        return $stmb->id;
+    }
+
+
+    /**
+     * 获取事务现号
+     *
+     * @return array
+     */
+    private function getTrNumber()
     {
-        return Storage::query()->whereHas("station",function (Builder $query)use($location){
-            $query->where("code",$location);
-        })->update(["status"=>1]);
+        $val = ValueStore::query()->select("value")->where("name","flux_tr_number")->first();
+        if (!$val)$val = ValueStore::query()->create(["name"=>"flux_tr_number","value"=>'0']);
+        $max = $val->value+1;
+        $number = sprintf("%09d", $max);
+        return array('W'.$number,$max);
     }
 
+    /**
+     * 设置事务现号
+     *
+     * @param integer $max
+     */
+    private function setTrNumber($max)
+    {
+        ValueStore::query()->select("value")->where("name","flux_tr_number")->update(["value"=>(string)((int)$max+1)]);
+    }
+
+    /**
+     * 入库
+     *
+     * @param integer $boxId
+     * @param integer $amount
+     * @param integer $commodityId
+     *
+     * @return bool
+     */
+    public function warehousing($boxId, $amount, $commodityId = null):bool
+    {
+        DB::beginTransaction();
+        try{
+            $storage = Storage::query()->where("material_box_id",$boxId)->lockForUpdate()->first();
+            if (!$storage && !$commodityId)return false;
+            if (!$storage){
+                Storage::query()->create([
+                    "station_id" => null,
+                    "material_box_id" => $boxId,
+                    "commodity_id" => $commodityId,
+                    "amount" => $amount,
+                ]);
+                return true;
+            }
+            if ($commodityId && $storage->commodity_id && $storage->commodity_id!=$commodityId)return false;
+            $obj = [
+                "station_id" => null,
+                "amount" => DB::raw("amount + {$amount}"),
+            ];
+            if (!$storage->commodity_id && $commodityId)$obj["commodity_id"] = $commodityId;
+            $storage->update($obj);
+            DB::commit();
+            return true;
+        }catch (\Exception $e){
+            DB::rollBack();
+            return false;
+        }
+    }
+
+    /**
+     * 出库
+     *
+     * @param integer $boxId
+     * @param integer $amount
+     * @param integer $commodityId
+     *
+     * @return bool
+     */
+    public function outWarehousing($boxId, $amount, $commodityId = null):bool
+    {
+        DB::beginTransaction();
+        try{
+            $storage = Storage::query()->where("material_box_id",$boxId)->lockForUpdate()->first();
+            if (!$storage)return false;
+            if ($commodityId && $storage->commodity_id && $storage->commodity_id!=$commodityId)return false;
+            $obj = [
+                "station_id" => null,
+                "amount" => DB::raw("amount - {$amount}"),
+            ];
+            if (!$storage->commodity_id && $commodityId)$obj["commodity_id"] = $commodityId;
+            $storage->update($obj);
+            DB::commit();
+            return true;
+        }catch (\Exception $e){
+            DB::rollBack();
+            return false;
+        }
+    }
 }

+ 71 - 0
app/Services/UserService.php

@@ -7,7 +7,10 @@ namespace App\Services;
 use App\Authority;
 use App\Owner;
 use App\User;
+use App\UserWorkgroup;
+use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use App\Traits\ServiceAppAop;
 
@@ -34,4 +37,72 @@ class UserService
             return $user->getPermittingOwnerIdsAttribute() ?? [];
         })??[];
     }
+
+
+    /**
+     * 检查用户的管理员身份
+     *
+     * @param integer $userId
+     *
+     * @return bool
+     */
+    private function checkAdminIdentity($userId):bool
+    {
+        if ($userId == Auth::id())return array_search(Auth::user()["name"],config("users.superAdmin"))!==false;
+        /** @var User|\stdClass $user */
+        $user = User::query()->select("name")->find($userId);
+        if (!$user)return false;
+        return array_search($user->name,config("users.superAdmin"))!==false;
+    }
+    /**
+     * @param integer|null $userId
+     *
+     * @return array
+     */
+    public function getUserHasOwners($userId = null)
+    {
+        if (!$userId)$userId = Auth::id();
+        $key = "owners:user_".$userId;
+        if (!Cache::has($key)){
+            if ($this->checkAdminIdentity($userId))Cache::forever($key,array_column(Owner::query()->select("id")->whereNull("deleted_at")->get()->toArray(),"id"));
+            else{
+                $owners = [];
+                /** @var User|\stdClass $user */
+                $user = new User();
+                $user->id = $userId;
+                $user->load("roles.owners");
+                $user->roles->each(function ($role)use (&$owners){
+                    $owners = array_merge($owners,array_column($role->owners->toArray(),"id"));
+                });
+                Cache::forever($key,$owners);
+            }
+        }
+        return Cache::get($key);
+    }
+
+    /**
+     * @param integer|null $userId
+     *
+     * @return array
+     */
+    public function getUserHasUserWorkGroups($userId = null)
+    {
+        if (!$userId)$userId = Auth::id();
+        $key = "userWorkGroups:user_".$userId;
+        if (!Cache::has($key)){
+            if ($this->checkAdminIdentity($userId))Cache::forever($key,array_column(UserWorkgroup::query()->select("id")->get()->toArray(),"id"));
+            else{
+                $userWorkGroups = [];
+                /** @var User|\stdClass $user */
+                $user = new User();
+                $user->id = $userId;
+                $user->load("roles.userWorkGroups");
+                $user->roles->each(function ($role)use (&$userWorkGroups){
+                    $userWorkGroups = array_merge($userWorkGroups,array_column($role->userWorkGroups->toArray(),"id"));
+                });
+                Cache::forever($key,$userWorkGroups);
+            }
+        }
+        return Cache::get($key);
+    }
 }

+ 42 - 0
app/Services/weight/GoodScanWeightService.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Services\weight;
+
+
+class GoodScanWeightService extends WeightService
+{
+    public $weight = 'weight';       // 重量
+    public $length = 'l';            // 长
+    public $width = 'w';             // 宽
+    public $height = 'h';            // 高
+    public $code = 'code';           // 快递单号
+    public $weight_at = 'time'; // 称重时间
+    public $hid = 'hid';             // 称重设备id
+    public $name = 'GoodScan';          // 名称
+
+    public function getSuccessMessage($params, $orderPackage): array
+    {
+        return ["code" => 0, 'error' => 'upload success'];
+    }
+
+    public function getNotFindOrderPackageMessage($params, $orderPackage): array
+    {
+        return ['code' => 500, 'error' => '未找打包裹信息'];
+    }
+
+    public function getNotFindOrderHeaderMessage($params, $orderPackage): array
+    {
+        return ['code' => 500, 'error' => '保存时发生错误(未在WMS中找到订单)!'];
+    }
+
+    public function getWeightMessage($orderPackage, $e): array
+    {
+        return ['code' => 500, 'error' => $e->getMessage];
+    }
+
+    public function getWriteWasFailMessage($params, $orderPackage): array
+    {
+        return ["code" => 500, "error" => "写入WMS失败!"];
+    }
+
+}

+ 49 - 0
app/Services/weight/HaoChuangWeightService.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Services\weight;
+
+
+use Illuminate\Support\Carbon;
+
+class HaoChuangWeightService extends WeightService
+{
+    public $weight = 'weight';     // 重量
+    public $length = 'length';     // 长
+    public $width = 'width';      // 宽
+    public $height = 'height';     // 高
+    public $code = 'barcode';       // 快递单号
+    public $weight_at = 'weight_at';  // 称重时间
+    public $hid = 'id';        // 称重设备id
+    public $name = 'HaoChuang';       // 名称
+
+    public function getSuccessMessage($params, $orderPackage): array
+    {
+        return ['code' => 200, 'msg' => '保存成功', 'data' => true, 'serverMsg' => null,
+            "requestor" => [
+                "requestor" => "1",
+                "eventCode" => "0",
+                "reqDate" => $orderPackage->weighed_at ?? Carbon::now()->format(Carbon::DEFAULT_TO_STRING_FORMAT),
+                "resDate" => Carbon::now()
+            ]];
+    }
+
+    public function getNotFindOrderPackageMessage($params, $orderPackage): array
+    {
+        return ['code' => 500, 'msg' => '未找打包裹信息', 'data' => null];
+    }
+
+    public function getNotFindOrderHeaderMessage($params, $orderPackage): array
+    {
+        return ['code' => 500, 'msg' => '富勒信息未找到', 'data' => null];
+    }
+
+    public function getWeightMessage($orderPackage, $e): array
+    {
+        return ['code' => 500, 'msg' => '称重下发修改时发生错误'.json_encode($e), 'data' => null];
+    }
+
+    public function getWriteWasFailMessage($params,$orderPackage): array
+    {
+        return ['code' => 500 ,'msg' => '写入Was包裹失败!', 'data' => null];
+    }
+}

+ 45 - 0
app/Services/weight/HengLiWeightService.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Services\weight;
+
+
+
+class HengLiWeightService extends WeightService
+{
+    // 参数
+    public $weight = 'weight';     // 重量
+    public $length = 'length';     // 长
+    public $width = 'width';      // 宽
+    public $height = 'height';     // 高
+    public $code = 'code';       // 快递单号
+    public $weight_at = 'weight_at';  // 称重时间
+    public $hid = 'hid';        // 称重设备id
+    public $name = 'HengLi';       // 名称
+
+    public function getWeightValue($params)
+    {
+        $value = $this->getValue($this->weight, $params);
+        return str_replace('_', '.', $value);
+    }
+
+    public function getSuccessMessage($params, $orderPackage): array
+    {
+        return ['success' => true, 'message' => '称重成功'];
+    }
+
+    public function getNotFindOrderPackageMessage($params, $orderPackage): array
+    {
+        return ['success' => false, 'message' => '未找打包裹信息'];
+    }
+
+    public function getNotFindOrderHeaderMessage($params, $orderPackage): array
+    {
+        return ['success' => false, 'message' => '富勒信息未找到'];
+    }
+
+    public function getWeightMessage($orderPackage, $e): array
+    {
+        return ['success' => false, 'message' => $e->getMessage];
+    }
+
+}

+ 503 - 0
app/Services/weight/WeightService.php

@@ -0,0 +1,503 @@
+<?php
+
+namespace App\Services\weight;
+
+
+use App\Events\WeighedEvent;
+use App\Http\Controllers\api\thirdPart\flux\PackageController;
+use App\Jobs\WeightUpdateInstantBill;
+use App\MeasuringMachine;
+use App\OracleActAllocationDetails;
+use App\OracleDOCOrderHeader;
+use App\OrderPackage;
+use App\Services\OrderService;
+use App\Waybill;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Carbon;
+
+class WeightService
+{
+    public $weight = '';     // 重量
+    public $length = '';     // 长
+    public $width = '';      // 宽
+    public $height = '';     // 高
+    public $code = '';       // 快递单号
+    public $weight_at = '';  // 称重时间
+    public $hid = '';        // 称重设备id
+    public $name = '';       // 名称
+
+    public function new(array $params): array
+    {
+        $params = $this->conversionParams($params);
+        return $this->weightOrderPackage($params);
+    }
+
+    /**
+     * 参数转换
+     * @param array $params
+     * @return array
+     */
+    public function conversionParams(array $params): array
+    {
+        return $params;
+    }
+
+    /**
+     * 包裹称重
+     * @param array $params
+     * @return array
+     */
+    public function weightOrderPackage(array $params): array
+    {
+
+        // 2.获取快递单号
+        $logistic_number = $this->getCodeValue($params);
+
+        if (!$logistic_number) return $this->getLogisticNumberIsNullMessage($params);
+        // 3、获取称重设备
+        $measuringMachine = $this->getMeasuringMachine($params);
+        /** @var OrderPackage $orderPackage */
+        $orderPackage = $this->getOrderPackageByCode($logistic_number);
+
+        // 4、快递单号对应的OrderPackage
+        if (is_null($orderPackage)) {
+            /** @var OracleDOCOrderHeader $orderHeader */
+            $orderHeader = $this->findOrderHeaderByLogisticNumber($logistic_number);
+            if (is_null($orderHeader)) {
+                return $this->getNotFindOrderHeaderMessage($params, $orderPackage);
+            }
+            try {
+                $order = $this->createOrderByOrderHeader($orderHeader);
+                $orderPackage = $this->createOrderPackage($params, $measuringMachine, $order);
+            } catch (\Exception $e) {
+                return $this->getWriteWasFailMessage($params, $orderPackage);
+            }
+        }
+
+
+        // 5、更新包裹信息
+        $bool = $this->updateOrderPackage($orderPackage, $params, $measuringMachine);
+        // 6、称重时间
+        if ($bool) $this->afterApply($orderPackage);
+        else {
+            app('LogService')->log(__METHOD__, $this->name, '写入WAS失败! (Error)', $logistic_number, null);
+            return $this->getUpdatePackageMessage($orderPackage);
+        }
+
+        // 7、处理波次信息 推送至WMS称重信息
+        try {
+            $this->activityWaveNoProcessing($orderPackage);
+        } catch (\Exception $e) {
+            return $this->getWeightMessage($orderPackage, $e);
+        }
+
+        return $this->getSuccessMessage($params, $orderPackage);
+    }
+
+
+// region ---消息返回
+
+    /**
+     * 称重成功
+     * @param $params
+     * @param $orderPackage
+     * @return array
+     */
+    public function getSuccessMessage($params, $orderPackage): array
+    {
+        return ['success' => true, 'message' => '称重成功'];
+    }
+
+    /**
+     * 没有找到对应的包裹信息
+     * @param $params
+     * @param $orderPackage
+     * @return array
+     */
+    public function getNotFindOrderPackageMessage($params, $orderPackage): array
+    {
+        return ['success' => false, 'message' => '未找打包裹信息'];
+    }
+
+    /**
+     * 富勒信息对应快递单号错误
+     * @param $params
+     * @param $orderPackage
+     * @return array
+     */
+    public function getNotFindOrderHeaderMessage($params, $orderPackage): array
+    {
+        return ['success' => false, 'message' => '富勒信息未找到'];
+    }
+
+    /**
+     * 称重下发修改错误
+     * @param $orderPackage
+     * @param $e
+     * @return array
+     */
+    public function getWeightMessage($orderPackage, $e): array
+    {
+        return ['success' => false, 'message' => $e->getMessage];
+    }
+
+    /**
+     * 更新包裹信息异常错误返回
+     * @param $orderPackage
+     * @return array
+     */
+    public function getUpdatePackageMessage($orderPackage): array
+    {
+        return ['success' => false, 'message' => '更新包裹信息出现异常'];
+    }
+
+    /**
+     * 快递单号过滤后为空
+     * @param $params
+     * @return array
+     */
+    public function getLogisticNumberIsNullMessage($params): array
+    {
+        return ['success' => false, 'message' => '快递单号过滤后为空'];
+    }
+
+    /**
+     * 写入Was失败信息
+     * @param $params
+     * @param $orderPackage
+     * @return array
+     */
+    public function getWriteWasFailMessage($params, $orderPackage): array
+    {
+        return ['success' => false, 'message' => '写入was失败!'];
+    }
+
+// endregion
+
+//  region ---称重完成之后的操作
+
+    /**
+     * 称重完成后的后续操作
+     * @param OrderPackage $orderPackage
+     */
+    public function afterApply(OrderPackage $orderPackage)
+    {
+        $orderPackage->loadMissing(['order' => function ($query) {
+            $query->with('owner', 'logistic');
+        }, 'measuringMachine', 'paperBox']);
+        event(new WeighedEvent($orderPackage));                 // 称重信息播报
+        dispatch(new WeightUpdateInstantBill($orderPackage));   // 及时订单
+        if(!empty($orderPackage->order)){
+            Waybill::setWeightByOrderCode($orderPackage->order->code,$orderPackage['weight']);
+        }
+    }
+
+// endregion
+
+// region  ---参数获取
+    /**
+     * 重量
+     * @param $params
+     * @return mixed|null
+     */
+    public function getWeightValue($params)
+    {
+        return $this->getValue($this->weight, $params);
+    }
+
+    /**
+     * 高
+     * @param $params
+     * @return mixed|null
+     */
+    public function getHeightValue($params)
+    {
+        return $this->getValue($this->height, $params);
+    }
+
+    /**
+     * 长
+     * @param $params
+     * @return mixed|null
+     */
+    public function getLengthValue($params)
+    {
+        return $this->getValue($this->length, $params);
+    }
+
+    /**
+     * 宽
+     * @param $params
+     * @return mixed|null
+     */
+    public function getWidthValue($params)
+    {
+        return $this->getValue($this->width, $params);
+    }
+
+    /**
+     * 获取快递单号
+     * @param $params
+     * @return mixed|null
+     */
+    public function getCodeValue($params)
+    {
+        return $this->getValue($this->code, $params);
+    }
+
+    /**
+     * 称重时间
+     * @param $params
+     * @return mixed|null
+     */
+    public function getWeightAtValue($params)
+    {
+        return $this->getValue($this->weight_at, $params);
+    }
+
+    /**
+     * 获取参数
+     * @param $name
+     * @param $param
+     * @return mixed|null
+     */
+    public function getValue($name, $param)
+    {
+        $names = explode(',', $name);
+        $value = array_reduce($names, function ($data, $key) {
+            if (isset($data[$key])) $data = $data[$key];
+            else $data = [];
+            return $data;
+        }, $param);
+        if (is_array($value) && count($value) == 0) return null;
+        return $value;
+    }
+
+    /**
+     * 体积参数排序
+     * @param $params
+     * @return array
+     */
+    public function getEdges($params): array
+    {
+        $length = $this->getLengthValue($params);
+        $height = $this->getHeightValue($params);
+        $width = $this->getWidthValue($params);
+        $edges = [$length ?? 0, $width ?? 0, $height ?? 0];
+        rsort($edges);
+        return $edges;
+    }
+
+// endregion
+
+//  region ---包裹
+
+    /**
+     * 获取单号对应的包裹
+     * @param $code
+     * @return Builder|Model|object|null
+     */
+    public function getOrderPackageByCode($code)
+    {
+        return OrderPackage::query()
+            ->with(['order' => function ($query) {
+                /** @var Builder $query */
+                $query->with('owner', 'logistic');
+            }])->where('logistic_number', $code)->first();
+    }
+
+    /**
+     * 更新包裹信息
+     * @param OrderPackage $orderPackage
+     * @param $params
+     * @param $measuringMachine
+     * @return bool
+     */
+    public function updateOrderPackage(OrderPackage $orderPackage, $params, $measuringMachine): bool
+    {
+        $edges = $this->getEdges($params);
+        $req_date = Carbon::now()->toDateTimeString();
+        $orderPackage['weight'] = $this->getWeightValue($params);
+        $orderPackage['measuring_machine_id'] = $measuringMachine['id'];
+        $orderPackage['length'] = $edges[0];
+        $orderPackage['width'] = $edges[1];
+        $orderPackage['height'] = $edges[2];
+        $orderPackage['weighed_at'] = $req_date;
+        $orderPackage['bulk'] = $edges[0] * $edges[1] * $edges[2];
+        return $orderPackage->save();
+    }
+
+    /**
+     * 创建包裹信息
+     * @param $params
+     * @param $measuringMachine
+     * @param $order
+     * @return Builder|Model|object|null
+     */
+    public function createOrderPackage($params, $measuringMachine, $order)
+    {
+        $weighed_at = Carbon::now()->format(Carbon::DEFAULT_TO_STRING_FORMAT);
+        $edges = $this->getEdges($params);
+        OrderPackage::query()->create([
+            'order_id' => $order->id,
+            'logistic_number' => $this->getCodeValue($params),
+            'measuring_machine_id' => $measuringMachine->id,
+            'weight' => $this->getWeightValue($params),
+            'length' => $edges[0],
+            'width' => $edges[1],
+            'height' => $edges[2],
+            'bulk' => $edges[0] * $edges[1] * $edges[2],
+            'weighed_at' => $weighed_at,
+            'status' => "无",
+        ]);
+        return $this->getOrderPackageByCode($this->getCodeValue($params));
+    }
+
+//  endregion
+
+//  region ---称重设备
+
+    /**
+     * 称重机获取
+     * @param $params
+     * @return MeasuringMachine
+     */
+    public function getMeasuringMachine($params): MeasuringMachine
+    {
+        $hid = $this->getValue($this->hid, $params);
+        /** @var MeasuringMachine $measuringMachine */
+        $measuringMachine = MeasuringMachine::query()->firstOrCreate(['code' => $hid], ['name' => $hid]); // 称重设备
+        $measuringMachine->turnOn();
+        $measuringMachine->turnOffInMinutes(30);
+        return $measuringMachine;
+    }
+//  endregion
+
+// region ---wms操作
+
+    /**
+     * 根据快递单号找到对应的WMS订单信息
+     * @param $code
+     * @return Builder|Model|object|null
+     */
+    public function findOrderHeaderByLogisticNumber($code)
+    {
+        $query = OracleActAllocationDetails::query()->select('OrderNO')->where('PickToTraceId', $code);
+        $orderHeader = OracleDOCOrderHeader::query()->with('actAllocationDetails', 'oracleBASCode')->whereIn('OrderNO', $query)->first();
+        if ($orderHeader == null) {
+            $orderHeader = OracleDOCOrderHeader::query()->with('actAllocationDetails', 'oracleBASCode')->where('SOReference5', $code)->first();
+        }
+        return $orderHeader;
+    }
+
+    /**
+     * 同步wms订单信息
+     * @param $orderHeader
+     * @return Builder|Model|object
+     */
+    public function createOrderByOrderHeader($orderHeader)
+    {
+        /** @var OrderService $orderService */
+        $orderService = app(OrderService::class);
+        $order_create_params = $orderService->getParamByOrderHeader($orderHeader);
+        $order = $orderService->first(['code' => $orderHeader->orderno]);
+        if ($order) return $order;
+        $order = $orderService->createOrder($order_create_params);
+        app('LogService')->log(__METHOD__, $this->name, ' 创建Order', json_encode($order) . " || " . $orderHeader);
+        return $order;
+    }
+
+    /**
+     * 活动波次处理
+     * @param $orderPackage
+     */
+    public function activityWaveNoProcessing(&$orderPackage)
+    {
+        $fluxController = new PackageController();
+        if ($orderPackage->isActivityBatch()) {
+            app('LogService')->log(__METHOD__, $this->name . " 依波次号同步所有包裹", json_encode($orderPackage), null);
+            OrderPackage::query()->where('batch_number', $orderPackage['batch_number'])->update([
+                'weight' => $orderPackage['weight'] ?? null,
+                'length' => $orderPackage['length'] ?? null,
+                'width' => $orderPackage['width'] ?? null,
+                'height' => $orderPackage['height'] ?? null,
+                'bulk' => $orderPackage['bulk'] ?? null,
+                'measuring_machine_id' => $orderPackage['measuring_machine_id'] ?? null,
+                'weighed_at' => $orderPackage['weighed_at'] ?? null,
+                'paper_box_id' => $orderPackage['paper_box_id'] ?? null,
+            ]);
+            $result = $fluxController->markWMSOnBatch($orderPackage['batch_number'], $orderPackage['weight']);
+            if (!$result['result']) {
+                $orderPackage->uploaded_to_wms = "异常";
+            }
+        } else {
+            app('LogService')->log(__METHOD__, $this->name . " 写入包裹至WMS异常", json_encode($orderPackage), null);
+            try {
+                $result = $fluxController->accomplishToWMS($orderPackage);
+                if ($result['result'] == 'success') $orderPackage->uploaded_to_wms = "是";
+                else $orderPackage->uploaded_to_wms = "异常";
+            } catch (\Exception $e) {
+                $orderPackage->uploaded_to_wms = "否";
+            }
+        }
+        $orderPackage->save();
+    }
+// endregion
+
+// region ---上传快递单号处理
+
+    /**
+     * 快递单号处理
+     *
+     * @param $code
+     * @return string
+     */
+    public function processCode($code): string
+    {
+
+        /** 如果是$code 是数组处理 */
+        if (is_array($code)) {
+            return $this->processCodeArr($code);
+        }
+        return $this->processCodeStr($code);
+    }
+
+    /**
+     *  快递单号 array 处理
+     *
+     * @param array $code
+     * @return mixed|string
+     */
+    public function processCodeArr(array $code): string
+    {
+        usort($code, function ($codeA, $codeB) {
+            if (strlen($codeA) == strlen($codeB)) return 0;
+            return strlen($codeA) > strlen($codeB) ? 1 : -1;
+        });
+        return $code[0];
+    }
+
+    /**
+     * 快递单号 string 处理
+     *
+     * @param $code
+     * @return string|null
+     */
+    public function processCodeStr($code): ?string
+    {
+        $codes = [];
+        preg_match_all('/[\w]+/', $code, $codes);
+        if (count($codes) == 0) return $code;
+        $codes = array_unique(array_filter(array_shift($codes), function ($item) {
+            return strlen($item) > 8;
+        }));
+        usort($codes, function ($a, $b) {
+            if (strlen($a) == strlen($b)) return 0;
+            return strlen($a) < strlen($b) ? 1 : -1;
+        });
+        return $codes[0] ?? null;
+    }
+
+// endregion
+}

+ 5 - 0
app/Station.php

@@ -49,4 +49,9 @@ class Station extends Model
             ->where('status','=','待处理');
     }
 
+    public function storage(): HasOne
+    {
+        return $this->hasOne(Storage::class);
+    }
+
 }

+ 42 - 0
app/TaskTransaction.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class TaskTransaction extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable = [
+        "doc_code",
+        "bar_code",
+        "fm_station_id",
+        "to_station_id",
+        "material_box_id",
+        "task_id",
+        "commodity_id",
+        "amount",
+        "type",
+        "status",
+        "user_id",
+        "mark"
+    ];
+
+    const STATUS = [
+        0 => "待做",
+        1 => "完成",
+        2 => "失败"
+    ];
+    const MARK = [
+        0 => "无",
+        1 => "缓存架半箱入库"
+    ];
+
+    public function materialBox()
+    {   //料箱
+        return $this->belongsTo(MaterialBox::class);
+    }
+}

+ 8 - 4
app/User.php

@@ -8,6 +8,7 @@ use Illuminate\Notifications\Notifiable;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use App\Traits\ModelTimeFormat;
 
@@ -118,11 +119,12 @@ class User extends Authenticatable
             });
             return $ownerIds;
         }
-        $this->authorities()->each(function(Authority $authority)use(&$ownerIds){
+        return array_column(DB::table("owner_role")->whereIn("role_id",array_column($this->roles->toArray(),"id"))->get()->toArray(),"owner_id");
+        /*$this->authorities()->each(function(Authority $authority)use(&$ownerIds){
             $ownerId=$authority->getOwnerIdAttribute();
             if($ownerId){array_push($ownerIds,$ownerId);}
         });
-        return array_unique($ownerIds);
+        return array_unique($ownerIds);*/
     }
     function getPermittingWorkgroupIds($allowAll=false){
         $workgroupIds=[];
@@ -132,9 +134,11 @@ class User extends Authenticatable
                 array_push($workgroupIds,$workgroup['id']);
             });
         }else{
-            $this->authorities()->each(function(Authority $authority)use(&$workgroupIds){
+            $workgroupIds = array_column(DB::table("role_user_work_group")
+                ->whereIn("role_id",array_column($this->roles->toArray(),"id"))->get()->toArray(),"user_work_group_id");
+            /*$this->authorities()->each(function(Authority $authority)use(&$workgroupIds){
                 if($authority->type=="工作组"){array_push($workgroupIds,$authority->relevance);}
-            });
+            });*/
         }
         return $workgroupIds;
     }

+ 4 - 0
app/UserWorkgroup.php

@@ -18,6 +18,10 @@ class UserWorkgroup extends Model
         'token','isNeedRemark',
     ];
 
+    public function roles()
+    {   //角色
+        return $this->belongsToMany(Role::class,"role_user_work_group","user_work_group_id","role_id");
+    }
     public function users(){
         return $this->belongsToMany('App\User','user_workgroup_user','user_workgroup_id','user_id');
     }

+ 10 - 1
app/Utils/helpers.php

@@ -3,6 +3,8 @@
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Model;
 
+const DAY_TO_MILLI_SECONDS  = 1000*60*60*24;
+
 function formatExcelDate(int $timestamp)
 {
     $diff = intval($timestamp);
@@ -11,6 +13,13 @@ function formatExcelDate(int $timestamp)
     return $day->toDateString();
 }
 
+function formatExcelDateTime(float $timestamp): string
+{
+    $today = new Carbon('1900-01-01');
+    $day = $today->addMilliseconds(intval($timestamp*DAY_TO_MILLI_SECONDS))->subDays(2);
+    return $day->toDateTimeString();
+}
+
 function diff($array1,$array2,string $identification,array $mapping,bool $intactDetached = false):array
 {
     $changes = [
@@ -48,4 +57,4 @@ function diff($array1,$array2,string $identification,array $mapping,bool $intact
         }else $changes['detached'][] = array_keys($map);
     }
     return $changes;
-}
+}

+ 2 - 2
config/cache.php

@@ -16,8 +16,8 @@ return [
 
         'owners'=>20,           //模型Owner
         'orderCountingRecord'=>1800,           //模型Owner
-        'logisticsCountingRecords'=>86400,           //快递饼图缓存时间
-        'warehouseCountingRecords'=>86400,           //仓库饼图缓存时间
+        'logisticsCountingRecords'=>1800,           //快递饼图缓存时间
+        'warehouseCountingRecords'=>1800,           //仓库饼图缓存时间
     ],
     /*
     |--------------------------------------------------------------------------

+ 0 - 1
database/factories/OrderCountingRecordFactory.php

@@ -14,7 +14,6 @@ use Illuminate\Database\Eloquent\Factory;
 $factory->define(OrderCountingRecord::class, function (Faker $faker) {
     return [
         'owner_id' => $faker->numberBetween(0, 100),
-        'shop_id' => $faker->numberBetween(0, 100),
         'warehouse_id' => $faker->numberBetween(0, 100),
         'logistic_id' => $faker->numberBetween(0, 100),
         'date_target' => Carbon::now()->toDateString(),

+ 17 - 0
database/factories/OwnerLogisticFeeDetailFactory.php

@@ -0,0 +1,17 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerLogisticFeeDetail;
+use Faker\Generator as Faker;
+
+$factory->define(OwnerLogisticFeeDetail::class, function (Faker $faker) {
+    return [
+        'owner_fee_detail_id'=>random_int(1,100),
+        'logistic_bill'=>$faker->uuid,
+        'initial_weight'=>random_int(1,100),
+        'initial_weight_price'=>random_int(1,100),
+        'additional_weight'=>random_int(1,100),
+        'additional_price' => random_int(1, 100),
+    ];
+});

+ 12 - 0
database/factories/OwnerLogisticFeeReportFactory.php

@@ -0,0 +1,12 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerLogisticFeeReport;
+use Faker\Generator as Faker;
+
+$factory->define(OwnerLogisticFeeReport::class, function (Faker $faker) {
+    return [
+        //
+    ];
+});

+ 1 - 0
database/factories/StationTaskFactory.php

@@ -9,5 +9,6 @@ $factory->define(StationTask::class, function (Faker $faker) {
     $status = ['待处理','挂起','处理中','完成','异常','取消'];
     return [
         "status"=>'待处理',
+        'station_id' => 0
     ];
 });

+ 6 - 1
database/factories/StationTaskMaterialBoxFactory.php

@@ -7,6 +7,11 @@ use Faker\Generator as Faker;
 
 $factory->define(StationTaskMaterialBox::class, function (Faker $faker) {
     return [
-        'status'=>'待处理'
+        'station_id' => 0,
+        'material_box_id' => 0,
+        'status'=>'待处理',
+        'type' => 0,
+        'station_task_batch_id' =>0 ,
+        'station_task_id' => 0
     ];
 });

+ 15 - 0
database/factories/StorageFactory.php

@@ -0,0 +1,15 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use Faker\Generator as Faker;
+
+$factory->define(\App\Storage::class, function (Faker $faker) {
+    return [
+        "station_id" => rand(0,10),
+        "material_box_id" =>  rand(0,10),
+        "commodity_id" => 0 ,
+        "amount" => 0,
+        "status" => 0,
+    ];
+});

+ 0 - 4
database/migrations/2019_12_03_174626_add_data_authorities_waybill.php

@@ -40,7 +40,6 @@ class AddDataAuthoritiesWaybill extends Migration
         (new Authority(['name'=>'省份-编辑','alias_name'=>'省份-编辑']))->save();
         (new Authority(['name'=>'省份-删除','alias_name'=>'省份-删除']))->save();
         (new Authority(['name'=>'财务报表','alias_name'=>'财务报表']))->save();
-        (new Authority(['name'=>'财务报表-查询','alias_name'=>'财务报表-查询']))->save();
         (new Authority(['name'=>'运输管理','alias_name'=>'运输管理']))->save();
         (new Authority(['name'=>'运输管理-查询','alias_name'=>'运输管理-查询']))->save();
         (new Authority(['name'=>'运输管理-录入','alias_name'=>'运输管理-录入']))->save();
@@ -48,8 +47,6 @@ class AddDataAuthoritiesWaybill extends Migration
         (new Authority(['name'=>'运输管理-调度','alias_name'=>'运输管理-调度']))->save();
         (new Authority(['name'=>'运输管理-删除','alias_name'=>'运输管理-删除']))->save();
         (new Authority(['name'=>'运输管理-运单审核','alias_name'=>'运输管理-运单审核']))->save();
-        (new Authority(['name'=>'运输管理-调度审核','alias_name'=>'运输管理-调度审核']))->save();
-        (new Authority(['name'=>'运输管理-可见费用项','alias_name'=>'运输管理-调度审核']))->save();
         (new Authority(['name'=>'计量单位','alias_name'=>'计量单位']))->save();
         (new Authority(['name'=>'计量单位-查询','alias_name'=>'计量单位-查询']))->save();
         (new Authority(['name'=>'计量单位-录入','alias_name'=>'计量单位-录入']))->save();
@@ -90,7 +87,6 @@ class AddDataAuthoritiesWaybill extends Migration
         Authority::where('name','省份-编辑')->delete();
         Authority::where('name','省份-删除')->delete();
         Authority::where('name','财务报表')->delete();
-        Authority::where('name','财务报表-查询')->delete();
         Authority::where('name','运输管理')->delete();
         Authority::where('name','运输管理-查询')->delete();
         Authority::where('name','运输管理-录入')->delete();

+ 0 - 5
database/migrations/2020_03_09_132100_add_store_transfer_authority.php

@@ -15,11 +15,6 @@ class AddStoreTransferAuthority extends Migration
         '入库管理-快速入库-录入',
         '入库管理-快速入库-编辑',
         '入库管理-快速入库-删除',
-        '仓库管理',
-        '仓库管理-查询',
-        '仓库管理-录入',
-        '仓库管理-编辑',
-        '仓库管理-删除',
     ];
 
     /**

+ 1 - 1
database/migrations/2020_11_23_143015_create_value_stores_table.php

@@ -16,7 +16,7 @@ class CreateValueStoresTable extends Migration
         Schema::create('value_stores', function (Blueprint $table) {
             $table->id();
             $table->string('name');
-            $table->timestamp('value', 0)->nullable()->index();
+            $table->string('value')->nullable()->index();
             $table->timestamps();
         });
     }

+ 0 - 1
database/migrations/2020_12_02_150054_create_order_commodity_assigns_table.php

@@ -9,7 +9,6 @@ class CreateOrderCommodityAssignsTable extends Migration
 
     protected $authorities = [
         "订单管理-指定分配",
-        "订单管理-指定分配-查询",
         "订单管理-指定分配-编辑",
     ];
     /**

+ 0 - 2
database/migrations/2020_12_12_093011_change_authorities_order_assign.php

@@ -11,10 +11,8 @@ class ChangeAuthoritiesOrderAssign extends Migration
     protected $changeNames=[
 
         ["指定分配","订单管理-指定分配"],
-        ["指定分配-查询","订单管理-指定分配-查询"],
         ["指定分配-编辑","订单管理-指定分配-编辑"],
         ["商品配置","订单管理-指定分配"],
-        ["商品配置-查询","订单管理-指定分配-查询"],
         ["商品配置-编辑","订单管理-指定分配-编辑"],
     ];
     /**

+ 34 - 0
database/migrations/2021_04_27_104357_change_menus_table_add_font_column.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangeMenusTableAddFontColumn extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('menus', function (Blueprint $table) {
+            $table->string("font")->nullable()->comment("font图标");
+            $table->string("font_style")->nullable()->comment("font图标样式");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('menus', function (Blueprint $table) {
+            $table->dropColumn("font");
+            $table->dropColumn("font_style");
+        });
+    }
+}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác