Przeglądaj źródła

Merge branch 'master' into yang

# Conflicts:
#	app/Http/Controllers/TestController.php
ANG YU 4 lat temu
rodzic
commit
60fc460deb
100 zmienionych plików z 2982 dodań i 1647 usunięć
  1. 8 7
      .gitlab-ci.yml
  2. 0 1
      app/Authority.php
  3. 19 0
      app/CommodityMaterialBoxModel.php
  4. 1 3
      app/Console/Commands/CheckCacheRackStorage.php
  5. 1 0
      app/Console/Commands/SyncOrderPackageLogisticRouteTask.php
  6. 1 1
      app/Console/Kernel.php
  7. 2 0
      app/Events/BroadcastToStation.php
  8. 12 5
      app/Http/Controllers/Auth/PasswordController.php
  9. 11 10
      app/Http/Controllers/CacheShelfController.php
  10. 2 1
      app/Http/Controllers/DeliveryAppointmentController.php
  11. 50 12
      app/Http/Controllers/DischargeTaskController.php
  12. 1 1
      app/Http/Controllers/HomeController.php
  13. 2 2
      app/Http/Controllers/InventoryController.php
  14. 5 17
      app/Http/Controllers/LaborCompanyController.php
  15. 10 1
      app/Http/Controllers/LaborReportController.php
  16. 1 1
      app/Http/Controllers/OrderCommodityAssignController.php
  17. 3 3
      app/Http/Controllers/ProcurementController.php
  18. 1 1
      app/Http/Controllers/RejectedController.php
  19. 23 18
      app/Http/Controllers/RoleController.php
  20. 162 146
      app/Http/Controllers/StorageController.php
  21. 8 0
      app/Http/Controllers/StoreController.php
  22. 38 21
      app/Http/Controllers/TestController.php
  23. 1 0
      app/Http/Controllers/WaybillController.php
  24. 1 1
      app/Http/Controllers/WaybillFinancialExceptedController.php
  25. 2 2
      app/Http/Controllers/WaybillFinancialSnapshotsController.php
  26. 21 254
      app/Http/Controllers/api/thirdPart/goodscan/PackageController.php
  27. 28 12
      app/Http/Controllers/api/thirdPart/haiq/LightController.php
  28. 24 21
      app/Http/Controllers/api/thirdPart/hengli/PackageController.php
  29. 37 315
      app/Http/Controllers/api/thirdPart/weight/PackageController.php
  30. 10 0
      app/Http/Requests/DischargeTask/DischargeTaskRequest.php
  31. 83 0
      app/Imports/DischargeTaskImport.php
  32. 3 1
      app/Imports/StoreCheckingReceiveImport.php
  33. 58 0
      app/Jobs/LogisticAliJiSuSync.php
  34. 5 3
      app/Jobs/LogisticYTOSync.php
  35. 1 1
      app/Logistic.php
  36. 5 1
      app/MaterialBox.php
  37. 16 0
      app/MaterialBoxModel.php
  38. 16 2
      app/Providers/AppServiceProvider.php
  39. 1 0
      app/Providers/AuthServiceProvider.php
  40. 1 1
      app/RejectedBill.php
  41. 3 0
      app/Role.php
  42. 19 10
      app/Services/BatchService.php
  43. 120 140
      app/Services/CacheShelfService.php
  44. 51 0
      app/Services/CommodityMaterialBoxModelService.php
  45. 2 2
      app/Services/DischargeTaskService.php
  46. 43 50
      app/Services/ForeignHaiRoboticsService.php
  47. 3 2
      app/Services/LaborReportService.php
  48. 126 0
      app/Services/LogisticAliJiSuApiService.php
  49. 22 4
      app/Services/MaterialBoxService.php
  50. 20 0
      app/Services/OrderPackageReceivedSyncService.php
  51. 5 1
      app/Services/PackageStatisticsService.php
  52. 1 0
      app/Services/RejectedService.php
  53. 16 0
      app/Services/StationService.php
  54. 22 4
      app/Services/StationTaskMaterialBoxService.php
  55. 431 7
      app/Services/StorageService.php
  56. 2 2
      app/Services/WaybillService.php
  57. 42 0
      app/Services/weight/GoodScanWeightService.php
  58. 49 0
      app/Services/weight/HaoChuangWeightService.php
  59. 45 0
      app/Services/weight/HengLiWeightService.php
  60. 503 0
      app/Services/weight/WeightService.php
  61. 5 0
      app/Station.php
  62. 42 0
      app/TaskTransaction.php
  63. 19 2
      app/User.php
  64. 10 1
      app/Utils/helpers.php
  65. 4 4
      composer.lock
  66. 13 0
      config/api_logistic.php
  67. 1 0
      database/factories/StationTaskFactory.php
  68. 6 1
      database/factories/StationTaskMaterialBoxFactory.php
  69. 15 0
      database/factories/StorageFactory.php
  70. 0 4
      database/migrations/2019_12_03_174626_add_data_authorities_waybill.php
  71. 1 1
      database/migrations/2020_11_23_143015_create_value_stores_table.php
  72. 0 1
      database/migrations/2020_12_02_150054_create_order_commodity_assigns_table.php
  73. 2 2
      database/migrations/2020_12_12_093011_change_authorities_order_assign.php
  74. 2 0
      database/migrations/2021_06_01_102357_add_authority_delivery_appointment_table_sign_id_data.php
  75. 46 0
      database/migrations/2021_06_03_171554_create_material_box_models_table.php
  76. 32 0
      database/migrations/2021_06_04_114431_add_belong_company_to_logistics.php
  77. 43 0
      database/migrations/2021_06_07_100646_create_task_transactions_table.php
  78. 29 0
      database/migrations/2021_06_07_112859_add_authority_discharge_task_owner.php
  79. 31 0
      database/migrations/2021_06_07_140812_create_role_labor_company_table.php
  80. 35 0
      database/migrations/2021_06_07_141732_add_labor_company_authoritiy.php
  81. 1 1
      resources/js/queryForm/queryForm.js
  82. 9 6
      resources/views/customer/project/create.blade.php
  83. 0 514
      resources/views/gates.blade.php
  84. 3 6
      resources/views/inventory/statement/changeInventory.blade.php
  85. 1 2
      resources/views/inventory/statement/menu.blade.php
  86. 28 0
      resources/views/layouts/app.blade.php
  87. 37 1
      resources/views/layouts/menu.blade.php
  88. 7 0
      resources/views/maintenance/logistic/create.blade.php
  89. 7 0
      resources/views/maintenance/logistic/edit.blade.php
  90. 3 1
      resources/views/maintenance/logistic/index.blade.php
  91. 1 1
      resources/views/maintenance/owner/menu.blade.php
  92. 1 1
      resources/views/maintenance/owner/recycle.blade.php
  93. 104 1
      resources/views/maintenance/role/create.blade.php
  94. 136 0
      resources/views/maintenance/role/edit.blade.php
  95. 10 2
      resources/views/maintenance/role/index.blade.php
  96. 1 1
      resources/views/maintenance/user/index.blade.php
  97. 1 2
      resources/views/package/menu.blade.php
  98. 11 3
      resources/views/personnel/discharge/statement/_table.blade.php
  99. 38 0
      resources/views/personnel/discharge/task/_import.blade.php
  100. 48 2
      resources/views/personnel/discharge/task/index.blade.php

+ 8 - 7
.gitlab-ci.yml

@@ -8,6 +8,7 @@ cache:
     - vendor/
 
 before_script:
+#配置环境
 #  - sudo cp ci/.envCi .env
 #  - sudo bash ci/installEnv.sh
 
@@ -25,8 +26,8 @@ test:
     - testwas
   script:
     - echo "run test....."
-#    - path=`pwd`
-#    - sudo bash ci/judgePush.sh $path
+    - path=`pwd`
+    - sudo bash ci/judgePush.sh $path
 #    - vendor/bin/phpunit --testsuite=Unit
 
 deploy:
@@ -35,8 +36,8 @@ deploy:
     - testwas
   script:
     - echo "deploy ...."
-#    - cd /var/www/bswas_test && sudo git config --global credential.helper store
-#    - sudo git pull
-#    - sudo bash ci/executeCommand.sh
-#  only:
-#    - master
+    - cd /var/www/bswas_test && sudo git config --global credential.helper store
+    - sudo git pull
+    - sudo bash ci/executeCommand.sh
+  only:
+    - master

+ 0 - 1
app/Authority.php

@@ -34,7 +34,6 @@ class Authority extends Model
         return '';
     }
 
-
     public  static  function  filterRecycle(Collection $authorities)
     {
         $owners = Owner::query()->whereNotNull("deleted_at")->get();

+ 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);
     }
 }

+ 1 - 0
app/Console/Commands/SyncOrderPackageLogisticRouteTask.php

@@ -46,6 +46,7 @@ class SyncOrderPackageLogisticRouteTask extends Command
         LogService::log(SyncOrderPackageLogisticRouteTask::class, "同步快递信息定时任务启动", '');
         ini_set('memory_limit', '2226M');
         $this->service = app('OrderPackageReceivedSyncService');
+        $this->service->syncLogisticRouteByAliJiSu();
         $this->service->syncLogisticRoute();
     }
 }

+ 1 - 1
app/Console/Kernel.php

@@ -80,8 +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);
     }
 }

+ 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()
     {

+ 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);
     }
 
 }

+ 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 "暂时关闭,如需开启请联系管理员";
     }

+ 5 - 17
app/Http/Controllers/LaborCompanyController.php

@@ -10,11 +10,7 @@ use Illuminate\Support\Facades\Validator;
 
 class LaborCompanyController extends Controller
 {
-    /**
-     * Display a listing of the resource.
-     *
-     * @return Response
-     */
+
     public function index()
     {
         if(!Gate::allows('劳务所-查询')){ return redirect(url('/'));  }
@@ -22,30 +18,21 @@ class LaborCompanyController extends Controller
         return view('maintenance.laborCompany.index',['laborCompanys'=>$laborCompanys]);
     }
 
-    /**
-     * Show the form for creating a new resource.
-     *
-     * @return Response
-     */
+
     public function create()
     {
         if(!Gate::allows('劳务所-录入')){ return redirect(url('/'));  }
         return view('maintenance.laborCompany.create');
     }
 
-    /**
-     * Store a newly created resource in storage.
-     *
-     * @param Request $request
-     * @return Response
-     */
+
     public function store(Request $request)
     {
         if(!Gate::allows('劳务所-录入')){ return redirect(url('/'));  }
         $this->validatorCreate($request->all())->validate();
         $laborCompany=new LaborCompany($request->all());
         $laborCompany->save();
-
+        app('LaborCompanyService')->createAuthority($laborCompany);//创建劳务所创建对应权限
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         return redirect('maintenance/laborCompany/create')->with('successTip',"成功录入劳务所“{$request->input('name')}”");
     }
@@ -97,6 +84,7 @@ class LaborCompanyController extends Controller
         $this->validatorUpdate($request->all())->validate();
         $laborCompany->fill($request->all());
         $laborCompany->update();
+        app('LaborCompanyService')->updateAuthority($laborCompany);
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         return redirect('maintenance/laborCompany/')->with('successTip',"成功修改劳务所“{$laborCompany['name']}”!");
     }

+ 10 - 1
app/Http/Controllers/LaborReportController.php

@@ -63,7 +63,16 @@ class LaborReportController extends Controller
             }
         }
         $totalWorkingHours=$this->getTotalWorkingHours($request->input());
-        $laborCompanies=LaborCompany::query()->get();
+        if($user->isSuperAdmin()|| Gate::allows('劳务所-可见全部')){
+            $laborCompanies=LaborCompany::query()->get();
+        }else{
+            $userId=$user['id'];
+            $laborCompanies=LaborCompany::query()->whereIn('id',function ($query)use($userId){
+                $query->from('role_labor_company')->selectRaw('labor_company_id')->whereIn('role_id',function ($builder)use ($userId){
+                    $builder->from('user_role')->selectRaw('id_role')->where('id_user',$userId);
+                });
+            })->get();
+        }
         $userWorkGroups=UserWorkgroup::query()->select('id','name')->get();
         return view('personnel/laborReport/index',compact('laborReports','userWorkGroups','laborCompanies','laravelEchoPrefix','permittingWorkgroups','paginateParams','tokenOfBroadcastEnterAndLeave','totalWorkingHours'));
     }

+ 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"));
     }

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

@@ -78,7 +78,7 @@ class ProcurementController extends Controller
                     $build->whereIn('id',$owner_ids);
                 });
             })
-            ->paginate($param['paginate'] ?? 50);
+            ->paginate($paginateParams['paginate'] ?? 50);
         foreach ($procurements as $procurement){
             if ($procurement->procurement_quotations_count>0 && $procurement->status==0) $procurement->status=1;
             if (empty($procurement->procurementDeliveries))continue;
@@ -287,7 +287,7 @@ class ProcurementController extends Controller
                     });
                 });
             })
-            ->paginate($param['paginate'] ?? 50);
+            ->paginate($paginateParams['paginate'] ?? 50);
         $suppliers=Supplier::query()->select('id','name')->get();
         $materials=Material::query()->select('id','name')->get();
         return view('procurement/finance/checkBill',compact('procurementCheckSheets','suppliers','paginateParams','materials'));
@@ -348,7 +348,7 @@ class ProcurementController extends Controller
                 });
             })
             ->where('type',0) //只取采购单
-            ->paginate($param['paginate'] ?? 50);
+            ->paginate($paginateParams['paginate'] ?? 50);
         foreach ($procurements as $procurement){
             if (empty($procurement->procurementDeliveries))continue;
             $procurement->receive_amount=$procurement->procurementDeliveries->sum('amount');

+ 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();
     }
 

+ 23 - 18
app/Http/Controllers/RoleController.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers;
 
 use App\Authority;
+use App\LaborCompany;
 use App\Role;
 use Exception;
 use Illuminate\Http\Request;
@@ -13,11 +14,7 @@ use Illuminate\Support\Facades\Validator;
 
 class RoleController extends Controller
 {
-    /**
-     * Display a listing of the resource.
-     *
-     * @return Response
-     */
+
     public function index(Request $request)
     {
         if(!Gate::allows('角色-查询')){ return redirect(url('/'));  }
@@ -42,25 +39,17 @@ class RoleController extends Controller
         return view('maintenance.role.index',['roles'=>$roles]);
     }
 
-    /**
-     * Show the form for creating a new resource.
-     *
-     * @return Response
-     */
+
     public function create()
     {
         if(!Gate::allows('角色-录入')){ return redirect(url('/'));  }
         $authoritiesAll=Authority::orderBy('alias_name','desc')->get();
         $authoritiesAll = Authority::filterRecycle($authoritiesAll);
-        return view('maintenance.role.create',compact('authoritiesAll'));
+        $laborCompanies=LaborCompany::query()->get();
+        return view('maintenance.role.create',compact('authoritiesAll','laborCompanies'));
     }
 
-    /**
-     * Store a newly created resource in storage.
-     *
-     * @param Request $request
-     * @return Response
-     */
+
     public function store(Request $request)
     {
         if(!Gate::allows('角色-录入')){ return redirect(url('/'));  }
@@ -72,6 +61,13 @@ class RoleController extends Controller
             $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')}”");
@@ -111,7 +107,9 @@ class RoleController extends Controller
         $authoritiesAll=Authority::orderBy('alias_name','desc')->get();
         $authoritiesAll = Authority::filterRecycle($authoritiesAll);
         $authorities=$role->authorities()->get();
-        return view('maintenance.role.edit',compact('role','authorities','authoritiesAll'));
+        $laborCompanies=LaborCompany::query()->get();
+        $laborCompaniesRole=$role->laborCompanies()->get();
+        return view('maintenance.role.edit',compact('role','authorities','authoritiesAll','laborCompanies','laborCompaniesRole'));
     }
 
     /**
@@ -134,6 +132,13 @@ class RoleController extends Controller
         }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']}”!");
     }

+ 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");
+    }
 }

Plik diff jest za duży
+ 38 - 21
app/Http/Controllers/TestController.php


+ 1 - 0
app/Http/Controllers/WaybillController.php

@@ -974,6 +974,7 @@ class WaybillController extends Controller
         $param=$request->input('param');
         $waybills=app('waybillService')->get($param);
         $total_pick_up_fee=$waybills->sum('pick_up_fee');
+        if ($total_pick_up_fee)$total_pick_up_fee=round($total_pick_up_fee);
         return ['success'=>true,'data'=>$total_pick_up_fee];
     }
 

+ 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);

+ 58 - 0
app/Jobs/LogisticAliJiSuSync.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Services\LogisticAliJiSuApiService;
+use App\Services\LogService;
+use App\Services\OrderPackageReceivedSyncService;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+class LogisticAliJiSuSync implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    /**
+     * @var $logisticAliJiSuApiService LogisticAliJiSuApiService
+     * @var $orderPackageReceivedSyncService OrderPackageReceivedSyncService
+     * @var $logistic_number string
+     */
+
+    protected $logistic_number;
+    protected $logisticAliJiSuApiService;
+    protected $orderPackageReceivedSyncService;
+
+    /**
+     * Create a new job instance.
+     *
+     * @param $logistic_number
+     */
+    public function __construct($logistic_number)
+    {
+        $this->logistic_number=$logistic_number;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        LogService::log(LogisticAliJiSuSync::class, "{$this->logistic_number}-JOB-AliJiSu", '');
+        $this->logisticAliJiSuApiService = app('LogisticAliJiSuApiService');
+        try {
+            $response = $this->logisticAliJiSuApiService->query($this->logistic_number);
+            if ($response && $response->status==0){
+                $format = $this->logisticAliJiSuApiService->format($response);
+                $this->orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
+                if (count($format)>0 && $format['logistic_number']??false) $this->orderPackageReceivedSyncService->update([$format]);
+            }
+        } catch (\Exception $e) {
+            app('LogService')->log(__METHOD__, __FUNCTION__, "阿里极速数据同步快递数据 ERROR " . ' || ' . json_encode($this->logistic_number) . ' || ' . json_encode($e->getMessage()) . ' || ' . json_encode($e->getTraceAsString()));
+        }
+    }
+}

+ 5 - 3
app/Jobs/LogisticYTOSync.php

@@ -15,7 +15,6 @@ use Illuminate\Queue\SerializesModels;
 class LogisticYTOSync implements ShouldQueue
 {
     public $tries = 2;
-
     public $timeout = 10;
 
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
@@ -27,7 +26,6 @@ class LogisticYTOSync implements ShouldQueue
      */
 
     protected $logistic_number;
-
     protected $logisticYTOService;
     protected $orderPackageReceivedSyncService;
 
@@ -53,6 +51,10 @@ class LogisticYTOSync implements ShouldQueue
         $nativeResponse = $this->logisticYTOService->query($this->logistic_number);
         $formattedData = $this->logisticYTOService->format($nativeResponse,$this->logistic_number);
         $this->orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
-        $this->orderPackageReceivedSyncService->update([$formattedData]);
+        if (count($formattedData)>0 && $formattedData['logistic_number']??false){
+            $this->orderPackageReceivedSyncService->update([$formattedData]);
+        }else{
+            LogService::log(LogisticYTOService::class, "YTO快递无快递单号异常", $formattedData);
+        }
     }
 }

+ 1 - 1
app/Logistic.php

@@ -17,7 +17,7 @@ class Logistic extends Model
     use ModelLogChanging;
     use SoftDeletes;
     use ModelTimeFormat;
-    protected $fillable = ['name','code',"type","mobile","remark","delivery_fee","is_bunched","english_name"];
+    protected $fillable = ['name','code',"type","mobile","remark","delivery_fee","is_bunched","english_name",'belong_company'];
 
 
     static function nameById($id){

+ 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"
+    ];
+}

+ 16 - 2
app/Providers/AppServiceProvider.php

@@ -7,6 +7,8 @@ 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\Services\AuthorityService;
 use App\Services\BatchService;
 use App\Services\CacheService;
@@ -111,6 +113,9 @@ use App\Services\UserWorkgroupService;
 use App\Services\DischargeTaskService;
 use App\Services\DeliveryAppointmentService;
 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;
@@ -128,8 +133,11 @@ use App\Services\OrderPackageExceptionTypeCountingRecordService;
 use App\Services\LogisticYDService;
 use App\Services\ForeignZhenCangService;
 use App\Services\StorageService;
+use App\Services\LogisticAliJiSuApiService;
+use App\Services\CommodityMaterialBoxModelService;
 use App\Services\OwnerLogisticFeeDetailService;
 use App\Services\OwnerLogisticFeeReportService;
+use App\Services\LaborCompanyService;
 
 class AppServiceProvider extends ServiceProvider
 {
@@ -201,11 +209,10 @@ class AppServiceProvider extends ServiceProvider
         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,10 +226,13 @@ 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);
         app()->singleton('LogisticSFService', LogisticSFService::class);
         app()->singleton('LogisticService', LogisticService::class);
         app()->singleton('LogisticYDService', LogisticYDService::class);
@@ -309,6 +319,10 @@ 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);
     }
 
     /**

+ 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                    货主

+ 3 - 0
app/Role.php

@@ -19,4 +19,7 @@ class Role extends Model
     function authorities(){
         return $this->belongsToMany('App\Authority','authority_role','id_role','id_authority');
     }
+    function laborCompanies(){
+        return $this->belongsToMany('App\LaborCompany','role_labor_company','role_id','labor_company_id');
+    }
 }

+ 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();
     }
 }

+ 3 - 2
app/Services/LaborReportService.php

@@ -55,11 +55,12 @@ class LaborReportService
         if((Gate::allows('人事管理-临时工报表-可见全部组')||Gate::allows('人事管理-门卫审核')) && !($params["user_workgroup_id"] ?? false)){
             $laborReports->where(function ($query)use($user){
                 $query->whereIn('labor_reports.user_workgroup_id',$user?$user->getPermittingWorkgroupIds(Gate::allows('人事管理-临时工报表-可见全部组')):[])
+                    ->whereIn('labor_reports.labor_company_id',$user?$user->getPermittingLaborCompanyIdsAttribute():[])
                     ->orWhereNull('labor_reports.user_workgroup_id');
             });
         }else{
-            $laborReports->whereIn('labor_reports.user_workgroup_id',
-                $user?$user->getPermittingWorkgroupIds(Gate::allows('人事管理-临时工报表-可见全部组')):[]);
+            $laborReports->whereIn('labor_reports.user_workgroup_id',$user?$user->getPermittingWorkgroupIds(Gate::allows('人事管理-临时工报表-可见全部组')):[])
+                ->whereIn('labor_reports.labor_company_id',$user?$user->getPermittingLaborCompanyIdsAttribute():[]);
         }
         $laborReports = app(QueryService::class)->query($params,$laborReports,$columnQueryRules,'labor_reports');
         return $laborReports;

+ 126 - 0
app/Services/LogisticAliJiSuApiService.php

@@ -0,0 +1,126 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+
+class LogisticAliJiSuApiService
+{
+    use ServiceAppAop;
+
+    public function query($logistic_number)
+    {
+        $app_code = config('api_logistic.AliJiSu.prod.app-code');
+        $type = config('api_logistic.AliJiSu.prod.type');
+        $host = config('api_logistic.AliJiSu.prod.search.host');
+        $path = config('api_logistic.AliJiSu.prod.search.path');
+        $method = config('api_logistic.AliJiSu.prod.method');
+        $headers = array();
+        array_push($headers, "Authorization:APPCODE " . $app_code);
+        array_push($headers, "Content-Type".":"."application/json; charset=UTF-8");
+        $query='number='.$logistic_number.'&type='.$type;
+        $bodys = "null";
+        $url = $host . $path . "?" . $query;
+//        $response = Http::withHeaders($headers)->get($url);
+//        return json_decode($response->body());
+
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
+        curl_setopt($curl, CURLOPT_URL, $url);
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+        curl_setopt($curl, CURLOPT_FAILONERROR, false);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+//        curl_setopt($curl, CURLOPT_HEADER, true);
+        if (1 == strpos("$".$host, "https://"))
+        {
+            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+        }
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $bodys);
+        return json_decode(curl_exec($curl));
+    }
+
+    public function format($response): array
+    {
+        $result = [];
+        if (!isset($response)) {return [];}
+        else {
+            try {
+                if ($response->result->number??false)$result['logistic_number'] = $response->result->number;
+            } catch (\Exception $e) {
+                LogService::log(LogisticYTOService::class, "AliJiSu快递信息异常", $response);
+            }
+            $list=$response->result->list;
+            if (!empty($list) && is_array($list)) {
+                $lastNativeRoute = $list[0];
+                $result['status'] = $this->getStatus($response);
+                if ($result['status'] == '已收件') $result['received_at'] = $lastNativeRoute->time;
+                $result['transfer_status'] = $this->getTransferStatus($list);
+                $result['routes_length'] = array_key_exists('transfer_status', $result) ? count($result['transfer_status']) : 0;
+                $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
+                $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastNativeRoute ? $lastNativeRoute->time : null);
+                $result['exception_type'] = $exceptionData['exception_type'];
+                $result['exception'] = $exceptionData['exception'];
+
+            } else {
+                $result['status'] = null;
+                $result['transfer_status'] = [];
+            }
+            if (!array_key_exists('exception', $result)
+                && !array_key_exists('exception_type', $result)
+                && array_key_exists('transfer_status', $result)
+            ) {
+                $result['exception_type'] = '无';
+                $result['exception'] = '否';
+            }
+            if (!array_key_exists('status', $result)) {
+                $result['status'] = null;
+                $result['transfer_status'] = [];
+            }
+            return $result;
+        }
+    }
+    /**
+     * @param $nativeData
+     * @return string
+     */
+    private function getStatus($nativeData): string
+    {
+        $status = null;
+        switch ($nativeData->result->deliverystatus) {
+            case '1':
+                $status = '在途';
+                break;
+            case '2':
+                $status = '派送中';
+                break;
+            case '3':
+                $status = '已收件';
+                break;
+            case '4':
+                $status = '派送异常';
+                break;
+            default:
+                $status = '无';
+        }
+        return $status;
+    }
+    /**
+     * @param $nativeRoutes
+     * @return array
+     */
+    private function getTransferStatus($nativeRoutes): array
+    {
+        $transferStatus = [];
+        foreach ($nativeRoutes as $nativeRoute) {
+            $item = [];
+            $item['accept_time'] = $nativeRoute->time;
+            $item['accept_address'] = $nativeRoute->status;
+            $item['remark'] = "";
+            $transferStatus[] = $item;
+        }
+        return $transferStatus;
+    }
+
+
+}

+ 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;
+    }
 }

+ 20 - 0
app/Services/OrderPackageReceivedSyncService.php

@@ -4,6 +4,7 @@
 namespace App\Services;
 
 
+use App\Jobs\LogisticAliJiSuSync;
 use App\Jobs\LogisticSFSync;
 use App\Jobs\LogisticYDSync;
 use App\Jobs\LogisticYTOSync;
@@ -80,6 +81,25 @@ class OrderPackageReceivedSyncService
         });
     }
 
+    public function syncLogisticRouteByAliJiSu()
+    {
+        ini_set('max_execution_time', 60);
+        LogService::log(OrderPackageReceivedSyncService::class, "阿里同步快递信息定时方法", '');
+        $query = OrderPackage::query()
+            ->select(['logistic_number', 'order_id'])
+            ->whereIn('order_id',function ($query){
+                $query->from('orders')->selectRaw('id')->whereIn('logistic_id',function ($builder){
+                    $builder->from('logistics')->selectRaw('id')->where('type','!=','物流')->whereNotIn('belong_company',['顺丰','中通','韵达','圆通']);
+                });
+            });
+        $query = $query->where('sent_at', '>=', now()->subDays(20))
+            ->whereNull('received_at');
+        $query->chunk(200, function ($orderPackages) {
+            foreach ($orderPackages as $orderPackage){
+                if ($orderPackage && $orderPackage->logistic_number)LogisticAliJiSuSync::dispatch($orderPackage->logistic_number);
+            }
+        });
+    }
     /**
      * 根据传递的承运商与快递单号更新快递信息
      * @param array $logisticNumbers 快递单号

+ 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,

+ 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;
+        }
+    }
 }

+ 2 - 2
app/Services/WaybillService.php

@@ -177,7 +177,7 @@ class WaybillService
         if ($waybills->isEmpty()) return '无数据';
         foreach ($waybills as $waybill){
             if (!$waybill['carrier_weight_other'] && !$waybill['carrier_weight']) return null;
-            if (!$waybill['carrier_weight_other']) $waybill['carrier_weight_other']=($waybill['carrier_weight']/0.004);
+            if (!$waybill['carrier_weight_other'] || $waybill['carrier_weight_other']<=0) $waybill['carrier_weight_other']=($waybill['carrier_weight']/0.25*100);
         }
         $daily_total_weight=$waybills->sum('carrier_weight_other');
         $updateParams = [['id','pick_up_fee','updated_at']];
@@ -185,7 +185,7 @@ class WaybillService
             $waybill['pick_up_fee']=round(($waybill->carrier_weight_other/$daily_total_weight)*$param['billing']);
             $updateParams[] = [
                 'id' => $waybill->id,
-                'pick_up_fee' => (($waybill->carrier_weight_other/$daily_total_weight)*$param['billing']),
+                'pick_up_fee' =>(($waybill->carrier_weight_other/$daily_total_weight)*$param['billing']),
                 'updated_at' => Carbon::now()->toDateTimeString(),
             ];
         }

+ 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);
+    }
+}

+ 19 - 2
app/User.php

@@ -98,8 +98,7 @@ class User extends Authenticatable
 
     function authorities(){
         $authorities = new Collection([]);
-        $user=User::query()->where('id',$this['id'])->with('roles.authorities')->first();
-        $user->roles->each(function ($role)use(&$authorities){
+        $this->roles->each(function ($role)use(&$authorities){
             if($role->authorities){
                 if(!$authorities){
                     $authorities=$role->authorities;
@@ -139,4 +138,22 @@ class User extends Authenticatable
         }
         return $workgroupIds;
     }
+    function getPermittingLaborCompanyIdsAttribute(): array
+    {
+        $labor_company_ids=array();
+        if($this->isSuperAdmin()||Gate::allows('劳务所-可见全部')){
+            $laborCompanies=LaborCompany::all();
+        }else{
+           $userId=$this['id'];
+           $laborCompanies=LaborCompany::query()->whereIn('id',function ($query)use($userId){
+               $query->from('role_labor_company')->selectRaw('labor_company_id')->whereIn('role_id',function ($builder)use ($userId){
+                   $builder->from('user_role')->selectRaw('id_role')->where('id_user',$userId);
+               });
+           })->get();
+        }
+        $laborCompanies->each(function (LaborCompany $laborCompany) use (&$labor_company_ids) {
+            array_push($labor_company_ids, $laborCompany['id']);
+        });
+        return array_unique($labor_company_ids);
+    }
 }

+ 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;
-}
+}

+ 4 - 4
composer.lock

@@ -3318,12 +3318,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/oursdreams/export.git",
-                "reference": "507ed53371d4ecc4f4350a9066422621ac2fae1c"
+                "reference": "ef7694ac342ff18742c17ddbce3a85076cac17e3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/oursdreams/export/zipball/507ed53371d4ecc4f4350a9066422621ac2fae1c",
-                "reference": "507ed53371d4ecc4f4350a9066422621ac2fae1c",
+                "url": "https://api.github.com/repos/oursdreams/export/zipball/ef7694ac342ff18742c17ddbce3a85076cac17e3",
+                "reference": "ef7694ac342ff18742c17ddbce3a85076cac17e3",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -3360,7 +3360,7 @@
                 "issues": "https://github.com/oursdreams/export/issues",
                 "source": "https://github.com/oursdreams/export/tree/0.0.7"
             },
-            "time": "2021-05-28T02:57:41+00:00"
+            "time": "2021-06-01T03:01:13+00:00"
         },
         {
             "name": "overtrue/laravel-pinyin",

+ 13 - 0
config/api_logistic.php

@@ -152,6 +152,19 @@ return [
             ],
         ],
     ],
+    'AliJiSu' => [
+        'prod' => [
+            'app-key' => '203946797',
+            'app-secret' => '5jlb4OfKkVFAbEXa7ebvnSQt5wCLQqWb',
+            'app-code' => '531dca65c4df41bfaa0c58cb52f444db',
+            'type' => 'auto',
+            'method' => 'GET',
+            'search' => [
+                'host' => 'https://jisukdcx.market.alicloudapi.com',
+                'path' => '/express/query',
+            ],
+        ],
+    ],
     'init_date' => '2021-05-17 23:59:59',
     'days' => 2,
 ];

+ 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();

+ 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 = [
         "订单管理-指定分配",
-        "订单管理-指定分配-查询",
         "订单管理-指定分配-编辑",
     ];
     /**

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

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

+ 2 - 0
database/migrations/2021_06_01_102357_add_authority_delivery_appointment_table_sign_id_data.php

@@ -14,6 +14,7 @@ class AddAuthorityDeliveryAppointmentTableSignIdData extends Migration
     public function up()
     {
         \App\Authority::query()->firstOrCreate(["name" => "入库管理-入库预约-预约管理-签到"],["name" => "入库管理-入库预约-预约管理-签到","alias_name"=>"入库管理-入库预约-预约管理-签到"]);
+        \App\Authority::query()->firstOrCreate(["name" => "入库管理-入库预约-预约管理-卸货完成"],["name" => "入库管理-入库预约-预约管理-卸货完成","alias_name"=>"入库管理-入库预约-预约管理-卸货完成"]);
     }
 
     /**
@@ -24,5 +25,6 @@ class AddAuthorityDeliveryAppointmentTableSignIdData extends Migration
     public function down()
     {
         \App\Authority::query()->where('name', '入库管理-入库预约-预约管理-签到')->delete();
+        \App\Authority::query()->where('name', '入库管理-入库预约-预约管理-卸货完成')->delete();
     }
 }

+ 46 - 0
database/migrations/2021_06_03_171554_create_material_box_models_table.php

@@ -0,0 +1,46 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateMaterialBoxModelsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('material_box_models', function (Blueprint $table) {
+            $table->id();
+            $table->string("code")->comment("型号");
+            $table->timestamps();
+        });
+        Schema::table('material_boxes', function (Blueprint $table) {
+            $table->bigInteger("material_box_model_id")->nullable()->index()->comment("型号");
+        });
+        Schema::create('commodity_material_box_model', function (Blueprint $table) {
+            $table->bigInteger("commodity_id")->comment("商品ID");
+            $table->bigInteger("material_box_model_id")->comment("料箱模型ID");
+            $table->integer("maximum")->default(0)->comment("存储最大限值");
+        });
+        \App\StationType::query()->create(["name"=>"镜像架"]);
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('material_box_models');
+        Schema::table('material_boxes', function (Blueprint $table) {
+            $table->dropColumn("material_box_model_id");
+        });
+        Schema::dropIfExists('commodity_material_box_model');
+        \App\StationType::query()->where("name","镜像架")->delete();
+    }
+}

+ 32 - 0
database/migrations/2021_06_04_114431_add_belong_company_to_logistics.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddBelongCompanyToLogistics extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('logistics', function (Blueprint $table) {
+            $table->string('belong_company')->nullable()->comment('隶属公司');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('logistics', function (Blueprint $table) {
+            $table->dropColumn('belong_company');
+        });
+    }
+}

+ 43 - 0
database/migrations/2021_06_07_100646_create_task_transactions_table.php

@@ -0,0 +1,43 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateTaskTransactionsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('task_transactions', function (Blueprint $table) {
+            $table->id();
+            $table->string("doc_code")->nullable()->comment("文档代码");
+            $table->string("bar_code")->nullable()->comment("商品条码");
+            $table->string("fm_station_id")->nullable()->comment("来源库位");
+            $table->string("to_station_id")->nullable()->comment("目标库位");
+            $table->string("material_box_id")->nullable()->comment("料箱ID");
+            $table->bigInteger("task_id")->nullable()->index()->comment("任务ID");
+            $table->bigInteger("commodity_id")->nullable()->comment("商品ID");
+            $table->integer("amount")->default(0)->comment("数量");
+            $table->enum("type",["出库","入库","移库"])->comment("操作类型");
+            $table->tinyInteger("status")->default(0)->comment("事务状态");
+            $table->bigInteger("user_id")->nullable()->comment("操作人");
+            $table->tinyInteger("mark")->default(0)->comment("标记类型");
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('task_transactions');
+    }
+}

+ 29 - 0
database/migrations/2021_06_07_112859_add_authority_discharge_task_owner.php

@@ -0,0 +1,29 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddAuthorityDischargeTaskOwner extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        \App\Authority::query()->firstOrCreate(['name' =>  '人事管理-卸货-货主可见全部'],['alias_name' => '人事管理-卸货-货主可见全部']);
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        \App\Authority::query()->where(['name' =>  '人事管理-卸货-货主可见全部'])->delete();
+
+    }
+}

+ 31 - 0
database/migrations/2021_06_07_140812_create_role_labor_company_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateRoleLaborCompanyTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('role_labor_company', function (Blueprint $table) {
+            $table->bigInteger("role_id")->comment("外键角色");
+            $table->bigInteger("labor_company_id")->comment("外键劳务所");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('role_labor_company');
+    }
+}

+ 35 - 0
database/migrations/2021_06_07_141732_add_labor_company_authoritiy.php

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddLaborCompanyAuthoritiy extends Migration
+{
+    protected $authorities = [
+        "劳务所-可见全部",
+    ];
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        foreach ($this->authorities as $authority){
+            \App\Authority::query()->firstOrCreate(["alias_name"=>$authority],["name"=>$authority,"alias_name"=>$authority]);
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        foreach ($this->authorities as $authority){
+            \App\Authority::query()->where("alias_name",$authority)->delete();
+        }
+    }
+}

+ 1 - 1
resources/js/queryForm/queryForm.js

@@ -615,7 +615,7 @@ const query = function getQueryForm(data) {
         let placeholder = controlJsType(condition.placeholder[0], 'undefined') ? '' : condition.placeholder[0];
 
         fillSelectOption(select, condition.data, placeholder);
-        let input = $("<input name='" + condition.name + "_tip' class='form-control form-control-sm ml-2' style='max-width: 150px' data-toggle='tooltip' data-placement='top'>");
+        let input = $("<input name='" + condition.name + "_tip' class='form-control form-control-sm ml-2' style='max-width: 150px' data-toggle='tooltip' data-placement='top' autocomplete='off'>");
 
         input.attr('title', controlJsType(condition.tip[1], 'undefined') ? '' : condition.tip[1]);
         input.attr('placeholder', controlJsType(condition.placeholder[1], 'undefined') ? '' : condition.placeholder[1])

+ 9 - 6
resources/views/customer/project/create.blade.php

@@ -97,13 +97,13 @@
                     owner_group_id : "{{$owner->user_owner_group_id ?? ''}}",
                     user_workgroup_id : "{{$owner->user_workgroup_id ?? ''}}",
                     warehouse_id : "{{ $owner->warehouse_id ?? ''}}",
-                    tax_rate_id : "{{$owner->is_tax_exist}}"==='Y' ? '0' : "{{$owner->tax_rate_id ?? ''}}",
+                    tax_rate_id : "{{$owner->is_tax_exist ?? ''}}"==='Y' ? '0' : "{{$owner->tax_rate_id ?? ''}}",
                     linkman : "{{$owner->linkman ?? ''}}",
                     phone_number : "{{$owner->phone_number ?? ''}}",
                     description : "{{$owner->description ?? ''}}",
                     waring_line_on : "{{$owner->waring_line_on ?? ''}}",
                     subjection : "{{$owner->subjection ?? ''}}",
-                    is_tax_exist : "{{$owner->is_tax_exist}}"==='Y',
+                    is_tax_exist : "{{$owner->is_tax_exist ?? ''}}"==='Y',
                 },
                 ownerTemp : {},
                 customers : [
@@ -892,11 +892,14 @@
                         this.$set(this.errors,"surcharge_unit_id",["耗材附加费未填写"]);
                         return;
                     }
-                    let unit = this.model.operation.items[0].unit_id;
+                    let unit = null;
                     for (let i=1;i<this.model.operation.items.length;i++){
-                        if (this.model.operation.items[i]!==unit){
-                            this.$set(this.errors,'items.'+i+'.unit_id',["所有子项单位必须一致"]);
-                            return;
+                        if (this.model.operation.items[i].amount){
+                            if(!unit)unit = this.model.operation.items[i].unit_id;
+                            else if(unit !== this.model.operation.items[i].unit_id){
+                                this.$set(this.errors,'items.'+i+'.unit_id',["所有子项单位必须一致"]);
+                                return;
+                            }
                         }
                     }
                     if (!this.model.operation.isSingle){

+ 0 - 514
resources/views/gates.blade.php

@@ -1,514 +0,0 @@
-<html>
-<head>
-</head>
-
-<body>
-@php
-    $startAt=microtime(true);
-@endphp
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@can('库存管理-盘点-结束初盘') 1 @endcan
-@php
-    $result=microtime(true)-$startAt;
-    echo "<h1>$result</h1>"
-@endphp
-</body>
-</html>

+ 3 - 6
resources/views/inventory/statement/changeInventory.blade.php

@@ -9,16 +9,12 @@
                 data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">
             导出Excel
         </button>
-        <div class="dropdown-menu">
-            <a class="dropdown-item" @click="processExport(false)" href="javascript:">导出勾选内容</a>
+        <span class="dropdown-menu">
             <a class="dropdown-item" @click="processExport(true)" href="javascript:">导出所有页</a>
-        </div>
+        </span>
     </span>
     <table class="table table-sm table-striped table-bordered table-hover text-nowrap card-body mt-2 td-min-width-80" id="table">
         <tr v-for="(oracleActTransactingLog,i) in oracleActTransactingLogs" @click="selectedColor(oracleActTransactingLog.id,$event)">
-            <td>
-                <input class="checkItem" type="checkbox" :value="oracleActTransactingLog">
-            </td>
             <td><span>@{{ i+1 }}</span></td>
             <td class="text-primary"><span>@{{ oracleActTransactingLog.货主 }}</span></td>
             <td class="text-muted"><span>@{{ oracleActTransactingLog.库位 }}</span></td>
@@ -141,6 +137,7 @@
                     restorationColumn: 'rn',
                     isRestorationColumnAsc:true,
                     fixedTop:($('#form_div').height())+2,
+                    isCheckAllBox:false,
                 }).init();
 
             },

+ 1 - 2
resources/views/inventory/statement/menu.blade.php

@@ -7,8 +7,7 @@
                 @can('库存管理-库存')
                     <li class="nav-item">
                         <a target="inventory/statement/changeInventory" class="nav-link" href="{{url('inventory/statement/changeInventory?range=1')}}" :class="{active:isActive('changeInventory',3)}">动库报表</a>
-                    </li> @endcan
-                @can('库存管理-库存')
+                    </li>
                     <li class="nav-item">
                         <a target="inventory/statement/allInventory" class="nav-link" href="{{url('inventory/statement/allInventory')}}" :class="{active:isActive('allInventory',3)}">全部库存</a>
                     </li> @endcan

+ 28 - 0
resources/views/layouts/app.blade.php

@@ -97,6 +97,34 @@
             location.reload();
         }
     });
+    function resetPwd(){
+        let old = document.getElementById("old_password").value;
+        let pwd = document.getElementById("password").value;
+        let pwdConfirmation = document.getElementById("password-confirm").value;
+        window.tempTip.setDuration("3000");
+        window.tempTip.setIndex(1099);
+        if (!old || !pwd || !pwdConfirmation){
+            window.tempTip.show("密码不得为空");
+            return;
+        }
+        if (old.length<6 || pwd.length<6 || pwdConfirmation.length<6){
+            window.tempTip.show("密码最低为6位");
+            return;
+        }
+        if (old === pwd){
+            window.tempTip.show("新密码不得与旧密码相同");
+            return;
+        }
+        if (pwd !== pwdConfirmation){
+            window.tempTip.show("新密码与确认密码不同");
+            return;
+        }
+        window.tempTip.postBasicRequest("{{url('password/update')}}",{old:old,pwd:pwd,pwdConfirmation:pwdConfirmation},()=>{
+            $("#resetPwd").modal('hide');
+            return "密码已成功修改";
+        },true)
+
+    }
 </script>
 @component('demand._createjs')@endcomponent
 @yield('lastScript')

+ 37 - 1
resources/views/layouts/menu.blade.php

@@ -92,7 +92,7 @@
                 </a>
 
                 <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
-                    <a class="dropdown-item" href="{{ url('password/change') }}">修改密码</a>
+                    <a class="dropdown-item" {{--href="{{ url('password/change') }}"--}} data-toggle="modal" data-target="#resetPwd">修改密码</a>
                     <a class="dropdown-item" href="{{ route('logout') }}"
                        onclick="event.preventDefault();
                                                      document.getElementById('logout-form').submit();">登出
@@ -105,4 +105,40 @@
             </li>
         @endguest
     </ul>
+    <div class="modal fade" id="resetPwd">
+        <div class="modal-dialog modal-dialog-centered">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal">&times;</button>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group row">
+                        <label for="old_password" class="col-md-4 col-form-label text-md-right">旧密码</label>
+
+                        <div class="col-md-6">
+                            <input id="old_password" type="password" class="form-control">
+                        </div>
+                    </div>
+                    <div class="form-group row">
+                        <label for="password" class="col-md-4 col-form-label text-md-right">输入新密码</label>
+
+                        <div class="col-md-6">
+                            <input type="password"  id="password" class="form-control"/>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="password-confirm" class="col-md-4 col-form-label text-md-right">重输密码</label>
+
+                        <div class="col-md-6">
+                            <input id="password-confirm" type="password" class="form-control" autocomplete="new-password">
+                        </div>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-success" onclick="resetPwd()">确认修改</button>
+                </div>
+            </div>
+        </div>
+    </div>
 </div>

+ 7 - 0
resources/views/maintenance/logistic/create.blade.php

@@ -90,6 +90,13 @@
                             @enderror
                         </div>
                     </div>
+                    <div class="form-group row">
+                        <label for="belong_company" class="col-2 col-form-label text-right">隶属公司</label>
+                        <div class="col-8">
+                            <input id="belong_company" type="text" class="form-control"
+                                   name="belong_company" autocomplete="off" value="{{ old('belong_company') }}" >
+                        </div>
+                    </div>
                     <div class="form-group row">
                         <label for="remark" class="col-2 col-form-label text-right">备注</label>
                         <div class="col-8">

+ 7 - 0
resources/views/maintenance/logistic/edit.blade.php

@@ -96,6 +96,13 @@
                             @enderror
                         </div>
                     </div>
+                    <div class="form-group row">
+                        <label for="belong_company" class="col-2 col-form-label text-right">隶属公司</label>
+                        <div class="col-8">
+                            <input id="belong_company" type="text" class="form-control "
+                                   name="belong_company" autocomplete="off" value="@if(old('belong_company')){{old('belong_company')}}@else{{$logistic->belong_company}}@endif" >
+                        </div>
+                    </div>
                     <div class="form-group row">
                         <label for="remark" class="col-2 col-form-label text-right">备注</label>
                         <div class="col-8">

+ 3 - 1
resources/views/maintenance/logistic/index.blade.php

@@ -21,6 +21,7 @@
                         <th>承运商联系方式</th>
                         <th>承运商类型</th>
                         <th>承运商送货费</th>
+                        <th>隶属公司</th>
                         <th>备注</th>
                         <th>创建时间</th>
                         <th>操作</th>
@@ -33,6 +34,7 @@
                         <td>@{{logistic.mobile}}</td>
                         <td>@{{logistic.type}}</td>
                         <td>@{{logistic.delivery_fee}}</td>
+                        <td>@{{logistic.belong_company}}</td>
                         <td>@{{logistic.remark}}</td>
                         <td class="text-muted">@{{logistic.created_at}}</td>
                         <td>
@@ -58,7 +60,7 @@
                     @foreach( $logistics as $logistic )
                     {id:'{{$logistic->id}}',name:'{{$logistic->name}}',code:'{{$logistic->code}}',
                         mobile:"{{$logistic->mobile}}",type:"{{$logistic->type}}",delivery_fee:"{{$logistic->delivery_fee}}",
-                        remark:"{{$logistic->remark}}",created_at:'{{$logistic->created_at}}',is_bunched:"{{$logistic->is_bunched}}"},
+                        remark:"{{$logistic->remark}}",belong_company:"{{$logistic->belong_company}}",created_at:'{{$logistic->created_at}}',is_bunched:"{{$logistic->is_bunched}}"},
                     @endforeach
                 ],
                 selectTr:0

+ 1 - 1
resources/views/maintenance/owner/menu.blade.php

@@ -12,7 +12,7 @@
                 </li> @endcan
             @can('货主-删除')
                 <li class="nav-item">
-                    <a target="maintenance/owners/recycle" class="nav-link" href="{{url('maintenance/owners/recycle')}}" :class="{active:isActive('recycle',3)}">停用</a>
+                    <a target="maintenance/owner/recycle" class="nav-link" href="{{url('maintenance/owners/recycle')}}" :class="{active:isActive('recycle',3)}">停用</a>
                 </li> @endcan
         </ul>
     </div>

+ 1 - 1
resources/views/maintenance/owner/recycle.blade.php

@@ -53,7 +53,7 @@
                 restoreSelected:function(owner){
                     let _this=this;
                     confirm('确定要恢复停用货主“' + owner.name + '”吗?');
-                    let ajaxUrl='{{url("maintenance/owners/restoreSelected")}}';
+                    let ajaxUrl='{{url("maintenance/owner/restoreSelected")}}';
                     axios.post(ajaxUrl,{id:owner.id}).then(function(response){
                         if(response.data.success){
                             tempTip.setDuration(1000);

+ 104 - 1
resources/views/maintenance/role/create.blade.php

@@ -81,6 +81,44 @@
                             </div>
                         </div>
                     </div>
+
+                    <div class="form-group row">
+                        <label for="laborCompany" class="col-2 col-form-label text-md-right">可见劳务所</label>
+                        <div class="col-8">
+                            <input type="text" class="form-control tooltipTarget" placeholder="定位劳务所"
+                                   @input="seekLaborCompany($event)" title="输入关键词快速定位"></div>
+                    </div>
+                    <div class="form-group row">
+                        <label class="col-2"></label>
+                        <div class="col-5">
+                            <div class="input-group"
+                                 style="max-height: 150px; overflow-y: scroll;border-radius:5px;opacity:0.5;text-align: center;">
+                                <ul class="list-group" style="width: 100%"
+                                    onselectstart="return false;">
+                                    <li :data-original-title="laborCompany.style ? '双击删除劳务所' : '双击添加劳务所'"
+                                        v-for="laborCompany in laborCompaniesFilter" :id="laborCompany.name"
+                                        class="tooltipTarget list-group-item list-group-item-action pt-0 pb-0"
+                                        @dblclick="selectedLaborCompany(laborCompany)"
+                                        :class="laborCompany.style ? 'active' :''"><span style="cursor: default;"> @{{ laborCompany.name }}  </span>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-3">
+                            <input name="laborCompany" hidden v-model="laborCompany">
+                            <div class="input-group"
+                                 style="max-height: 150px; overflow-y: scroll;border-radius:5px;text-align: center;">
+                                <ul class="list-group" style="width: 100%" onselectstart="return false;">
+                                    <li :data-original-title="laborCompaniesList ? '双击删除劳务所' : ''"
+                                        v-for="laborCompany in laborCompaniesList"
+                                        class="tooltipTarget list-group-item list-group-item-action pt-0 pb-0"
+                                        @dblclick="selectedLaborCompany(laborCompany)"><span style="cursor: default;"> @{{ laborCompany.name }}  </span>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+
                     <div class="form-group row">
                         <div class="col-8 offset-2">
                             <input type="submit" class="btn btn-success form-control">
@@ -106,6 +144,23 @@
                 authoritiesFilter:[],
                 authorities:[{{old('authority')}}],
                 authoritiesList:[],
+
+                laborCompaniesAll: [
+                        @foreach($laborCompanies as $laborCompany)
+                    {
+                        id: '{{$laborCompany->id}}', name: '{{$laborCompany->name}}', style: false
+                    },
+                    @endforeach
+                ],
+                laborCompaniesFilter: [
+                        @foreach($laborCompanies as $laborCompany)
+                    {
+                        id: '{{$laborCompany->id}}', name: '{{$laborCompany->name}}', style: false
+                    },
+                    @endforeach
+                ],
+                laborCompany: [{{old('laborCompany')}}],
+                laborCompaniesList: [],
             },
             mounted:function(){
                 $(".tooltipTarget").tooltip({'trigger':'hover'});
@@ -189,6 +244,49 @@
                         if(bool){ $(e.target).focus();}
                     },10)
                 },
+                selectedLaborCompany: function (e) {
+                    let laborCompany = this.laborCompany;
+                    let laborCompaniesAll = this.laborCompaniesAll;
+                    let laborCompaniesList = this.laborCompaniesList;
+                    let isLaborCompany = true;
+                    if (laborCompany && laborCompaniesAll) {
+                        for (let i = 0; i < laborCompany.length; i++) {
+                            if (laborCompany[i] == e.id) {
+                                laborCompany.splice(i, 1);
+                                laborCompaniesAll.every(function (laborCompaniesAll) {
+                                    if (laborCompaniesAll.id == e.id) {
+                                        laborCompaniesAll.style = false;
+                                        return false;
+                                    }
+                                    return true;
+                                });
+                                laborCompaniesList.every(function (laborCompany, i) {
+                                    if (laborCompany.id == e.id) {
+                                        laborCompaniesList.splice(i, 1);
+                                        $(".tooltipTarget").tooltip('hide');
+                                        return false;
+                                    }
+                                    return true;
+                                });
+                                isLaborCompany = false;
+                                break;
+                            }
+                            isLaborCompany = true;
+                        }
+                    }
+                    if (isLaborCompany || !laborCompany) {
+                        laborCompany.push(e.id);
+                        laborCompaniesAll.every(function (laborCompaniesAll) {
+                            if (laborCompaniesAll.id == e.id) {
+                                laborCompaniesAll.style = true;
+                                laborCompaniesList.push({'id': laborCompaniesAll.id, 'name': laborCompaniesAll.name});
+                                return false;
+                            }
+                            return true;
+                        });
+                    }
+                    this.resetTooltip();
+                },
                 filterAuthority(e){
                     let _arr = [];
                     let value = $(e.target).val();
@@ -208,7 +306,12 @@
                         }
                     })
                     this.authoritiesFilter = _arr
-                }
+                },
+                resetTooltip(){
+                    setTimeout(function () {
+                        $(".tooltipTarget").tooltip({ boundary: 'window' });
+                    }, 10 )
+                },
             },
         });
 

+ 136 - 0
resources/views/maintenance/role/edit.blade.php

@@ -94,6 +94,34 @@
                             </div>
                         </div>
                     </div>
+
+                    <div class="form-group row">
+                        <label for="laborCompany" class="col-2 col-form-label text-md-right">劳务所</label>
+                        <div class="col-8">
+                            <input type="text"  class="form-control tooltipTarget" placeholder="定位劳务所"
+                                   @input="seekLaborCompany($event)" title="输入关键词快速定位"></div>
+                    </div>
+                    <div class="form-group row">
+                        <label class="col-2"></label>
+                        <div class="col-5">
+                            <input name="laborCompany" hidden v-model="laborCompanies" >
+                            <div class="input-group" style="max-height: 190px; overflow-y: scroll;border-radius:5px;opacity:0.5;text-align: center;">
+                                <ul class="list-group tooltipTarget" style="width: 100%" onselectstart="return false;">
+                                    <li  :data-original-title="laborCompany.style ? '双击删除劳务所' :'双击添加劳务所'"    v-for="laborCompany in laborCompaniesFilter" :id="laborCompany.name" class="list-group-item list-group-item-action pt-0 pb-0"
+                                         @dblclick="selectedLaborCompany(laborCompany)" :class="laborCompany.style ? 'active' :''"><span style="cursor: default;" :id="laborCompany.name"> @{{ laborCompany.name }}  </span></li>
+                                </ul>
+                            </div>
+                        </div>
+                        <div class="col-3">
+                            <div class="input-group" style="max-height: 190px; overflow-y: scroll;border-radius:5px;text-align: center;">
+                                <ul class="list-group" style="width: 100%" onselectstart="return false;">
+                                    <li  title="双击删除劳务所"    v-for="laborCompany in laborCompaniesList" :id="laborCompany.name" class="list-group-item list-group-item-action pt-0 pb-0"
+                                         @dblclick="selectedLaborCompany(laborCompany)" ><span style="cursor: default;" > @{{ laborCompany.name }}  </span></li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+
                     <div class="form-group row">
                         <div class="col-8 offset-2">
                             <input type="submit" class="btn btn-outline-dark form-control">
@@ -131,6 +159,31 @@
                     @endif
                 ],
                 authoritiesList:[],
+
+                laborCompaniesAll: [
+                        @foreach($laborCompanies as $laborCompany)
+                    {
+                        id: '{{$laborCompany->id}}', name: '{{$laborCompany->name}}', style: false
+                    },
+                    @endforeach
+                ],
+                laborCompaniesFilter: [
+                        @foreach($laborCompanies as $laborCompany)
+                    {
+                        id: '{{$laborCompany->id}}', name: '{{$laborCompany->name}}', style: false
+                    },
+                    @endforeach
+                ],
+                laborCompanies: [
+                    @if(old('laborCompany'))
+                    {{ old('laborCompany') }}
+                    @else
+                    @foreach( $laborCompaniesRole as $laborCompany )
+                    {{$laborCompany->id}},
+                    @endforeach
+                    @endif
+                ],
+                laborCompaniesList: [],
             },
             mounted:function(){
                 $(".tooltipTarget").tooltip({'trigger':'hover'});
@@ -149,6 +202,21 @@
                         });
                     }
                 }
+                if (this.laborCompanies.length>0){
+                    let laborCompaniesAll=this.laborCompaniesAll;
+                    let laborCompanies=this.laborCompanies;
+                    let laborCompaniesList=this.laborCompaniesList;
+                    for (let i = 0; i < laborCompanies.length; i++) {
+                        laborCompaniesAll.every(function (laborCompanyAll) {
+                            if (laborCompanyAll.id == laborCompanies[i]) {
+                                laborCompanyAll.style = true;
+                                laborCompaniesList.push({'id':laborCompanyAll.id,'name':laborCompanyAll.name});
+                                return false;
+                            }
+                            return true;
+                        });
+                    }
+                }
             },
             methods:{
                 selectedAuthority:function (e) {
@@ -195,6 +263,74 @@
                         $(".tooltipTarget").tooltip({'trigger':'hover'});
                     },10)
                 },
+                selectedLaborCompany:function (e) {
+                    let laborCompanies=this.laborCompanies;
+                    let laborCompaniesAll=this.laborCompaniesAll;
+                    let laborCompaniesList=this.laborCompaniesList;
+                    let isLaborCompany=true;
+                    if (laborCompanies&&laborCompaniesAll) {
+                        for (let i = 0; i < laborCompanies.length; i++) {
+                            if (laborCompanies[i] == e.id) {
+                                laborCompanies.splice(i,1);
+                                laborCompaniesAll.every(function (laborCompanyAll) {
+                                    if (laborCompanyAll.id == e.id) {
+                                        laborCompanyAll.style = false;
+                                        return false;
+                                    }
+                                    return true;
+                                });
+                                laborCompaniesList.every(function (laborCompany,i) {
+                                    if (laborCompany.id==e.id){
+                                        laborCompaniesList.splice(i,1);
+                                        return false;
+                                    }
+                                    return true;
+                                });
+                                isLaborCompany= false;
+                                break;
+                            }
+                            isLaborCompany= true;
+                        }
+                    }
+                    if (isLaborCompany || !laborCompanies){
+                        laborCompanies.push(e.id);
+                        laborCompaniesAll.every(function (laborCompanyAll) {
+                            if (laborCompanyAll.id==e.id){
+                                laborCompanyAll.style=true;
+                                laborCompaniesList.push({'id':laborCompanyAll.id,'name':laborCompanyAll.name});
+                                return false;
+                            }
+                            return  true;
+                        });
+                    }
+                    setTimeout(function(){
+                        $(".tooltipTarget").tooltip({'trigger':'hover'});
+                    },10)
+                },
+                seekLaborCompany:function (e) {
+                    let $val=e.target.value;
+                    let laborCompaniesAll=this.laborCompaniesAll;
+                    let bool = false;
+                    laborCompaniesAll.every(function (laborCompanyAll) {
+                        let name=laborCompanyAll.name;
+                        if (name.includes($val)){
+                            bool = true;
+                            return false;
+                        }
+                        return  true;
+                    });
+                    if($val === '' ){
+                        this.laborCompaniesFilter = this.laborCompaniesAll;
+                    }else if(bool){
+                        this.laborCompaniesFilter = [];
+                        for (let i = 0; i <laborCompaniesAll.length ; i++) {
+                            let laborCompany = laborCompaniesAll[i];
+                            if(laborCompany.name.includes($val)){
+                                this.laborCompaniesFilter.push(laborCompany);
+                            }
+                        }
+                    }
+                },
                 seekAuthority:function (e) {
                     let $val=e.target.value;
                     let authoritiesAll=this.authoritiesAll;

+ 10 - 2
resources/views/maintenance/role/index.blade.php

@@ -15,7 +15,7 @@
                 @endif
                 <table class="table table-striped table-sm td-min-width-80" id="table">
                     <tr v-for="(role,i) in roles"  @click="selectTr===i+1?selectTr=0:selectTr=i+1" :class="selectTr===i+1?'focusing' : ''">
-                        <td><input class="checkItem" type="checkbox" :value="role.id"></td>
+{{--                        <td><input class="checkItem" type="checkbox" :value="role.id"></td>--}}
                         <td class="text-muted"><span>@{{role.id}}</span></td>
                         <td><span>@{{role.name}}</span></td>
                         <td>
@@ -32,6 +32,13 @@
                                 </ul>
                             </div>
                         </td>
+                        <td>
+                            <div style="max-height: 130px;overflow-y: scroll;border: solid 1px #ddd;" v-if="role.laborCompanies.length>0">
+                                <ul class="list-group">
+                                    <li v-for="laborCompany in role.laborCompanies"   style="list-style: none">@{{ laborCompany.name }}</li>
+                                </ul>
+                            </div>
+                        </td>
                         <td class="text-muted"><span>@{{role.created_at}}</span></td>
                         <td>
                             @can('角色-编辑')
@@ -57,7 +64,7 @@
                 roles:[
                         @foreach( $roles as $role )
                     {id:'{{$role->id}}',name:'{{$role->name}}',
-                        authorities:{!! $role->authorities !!},created_at:'{{$role->created_at}}',
+                        authorities:{!! $role->authorities !!},laborCompanies:{!! $role->laborCompanies !!},created_at:'{{$role->created_at}}',
                     },
                     @endforeach
                 ],
@@ -77,6 +84,7 @@
                     {name:'name',value: '角色'},
                     {name:'alias_name',value: '允许权限', neglect: true},
                     {name:'alias_name_false',value: '禁止权限', neglect: true},
+                    {name:'laborCompanyName',value: '可见劳务所', neglect: true},
                     {name:'created_at',value: '创建时间'},
                     {name:'operation',value: '操作', neglect: true},
                 ];

+ 1 - 1
resources/views/maintenance/user/index.blade.php

@@ -16,7 +16,7 @@
                 <div id="list">
                     <table class="table table-striped table-sm td-min-width-80" id="table">
                         <tr v-for="(user,i) in users"  @click="selectTr===i+1?selectTr=0:selectTr=i+1" :class="selectTr===i+1?'focusing' : ''">
-                            <td><input class="checkItem" type="checkbox" :value="user.id"></td>
+{{--                            <td><input class="checkItem" type="checkbox" :value="user.id"></td>--}}
                             <td class="text-muted"><span>@{{user.id}}</span></td>
                             <td><span>@{{user.name}}</span></td>
                             <td>

+ 1 - 2
resources/views/package/menu.blade.php

@@ -10,10 +10,9 @@
                 <li class="nav-item">
                     <a target="package/logistic" class="nav-link" href="{{url('package/logistic?is_exception=%25E6%2598%25AF&default_date=ture')}}" :class="{active:isActive('logistic',2)}">快递</a>
                 </li>@endcan
-            @can('称重管理-查看异常')
             <li class="nav-item">
                 <a target="package/relating" class="nav-link text-dark" href="{{url('package/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
-            </li>@endcan
+            </li>
         </ul>
     </div>
 </div>

+ 11 - 3
resources/views/personnel/discharge/statement/_table.blade.php

@@ -7,7 +7,11 @@
         <th class="td-yellow" colspan="3">其他信息</th>
     </tr>
     <tr class="text-center" >
-        <th><input type="checkbox" class="form-check" name="selectAll" id="selectAll" @click="checkAll"/></th>
+        <th>
+            <label>
+                <input type="checkbox" class="form-check" name="selectAll" id="selectAll" @click="checkAll">
+            </label>
+        </th>
         <th class="td-helpful">序号</th>
         <th class="td-helpful">日期</th>
         <th class="td-helpful">作业名称</th>
@@ -27,9 +31,13 @@
     </tr>
     <template v-if="dischargeStatements.length > 0">
         <tr v-for="(dischargeTask,index) in dischargeStatements" class="text-center"  @click="selectTr===index+1?selectTr=0:selectTr=index+1" :class="selectTr===index+1?'focusing' : ''">
-            <td ><input type="checkbox" class="form-check" :value="dischargeTask.id" v-model="checkData"></td>
+            <td >
+                <label>
+                    <input type="checkbox" class="form-check" :value="dischargeTask.id" v-model="checkData">
+                </label>
+            </td>
             <td class="td-helpful">@{{ index+1 }}</td>
-            <td class="td-helpful">@{{ dischargeTask.created_at }}</td>
+            <td class="td-helpful">@{{ dischargeTask.income_at }}</td>
             <td class="td-helpful">@{{ dischargeTask.type }}</td>
             <td class="td-helpful">@{{ dischargeTask.numbers }}</td>
             <td class="td-cool">@{{ dischargeTask.income_amount }}</td>

+ 38 - 0
resources/views/personnel/discharge/task/_import.blade.php

@@ -0,0 +1,38 @@
+<div class="modal fade" id="importModal">
+    <div class="modal-dialog modal-dialog-centered modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">
+                    卸货任务导入
+                </h5>
+                <button type="button" class="close" data-dismiss="modal">
+                    <span>&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <label for="importFile">导入文件</label>
+                        <input type="file" ref="file" name="file"  id="importFile"  class="form-control-file">
+                    </div>
+                    <div class="form-group">
+                        <small>文件类型:xlsx ,xlsm ,xls</small>
+                    </div>
+                    <div class="form-group">
+                        <small>字段:*货主,*预约日期,*作业名称,*仓库,*入库单,*数量,*单位,*单价,备注(非必填)</small>
+                    </div>
+                    <div class="form-group" v-if="uploadErrors.length > 0">
+                        <p class="text-danger">导入异常明细</p>
+                        <ul class="list-group" v-if="uploadErrors">
+                            <li class="list-group-item" v-for="error in uploadErrors">@{{ error }}</li>
+                        </ul>
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button class="btn btn-success" @click="cancelImport">关闭</button>
+                <button class="btn btn-success" @click="importDischarge">导入</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 48 - 2
resources/views/personnel/discharge/task/index.blade.php

@@ -22,12 +22,21 @@
                     <a class="dropdown-item" @click="dischargeTaskExport(true)" href="javascript:">导出所有页</a>
                 </div>
             </span>
+
             <span class="ml-1">
                 @can('人事管理-卸货-创建')
                 <button type="button" class="btn btn-outline-dark btn-sm form-control-sm tooltipTarget" @click="showCreateTaskModal(true)" style="background: #dad7e8;">创建任务</button>
                 @endcan
             </span>
+            @can('人事管理-卸货-创建')
+            <span class="ml-1">
+                  <button type="button" class="btn btn-outline-primary btn-sm form-control-sm tooltipTarget"
+                          @click="importModal"
+                  >批量导入</button>
+            </span>
+            @endcan
         </div>
+        @include('personnel.discharge.task._import')
         @include('personnel.discharge.task._table')
         @can('人事管理-卸货-创建')
         @include('personnel.discharge.task._createTask')
@@ -54,6 +63,7 @@
                 addTask: {income_at:null},
                 executingTack: {},
                 taskError:{},
+                uploadErrors:[],
                 taskTypes: [
                     {name: 0, value: "装车"},
                     {name: 1, value: "卸车"},
@@ -63,8 +73,8 @@
                 units: [
                     {name: 0, value: 'm3'},
                     {name: 1, value: '吨'},
-                    {name: 2, value: ''},
-                    {name: 3, value: ''},
+                    {name: 2, value: ''},
+                    {name: 3, value: ''},
                 ],
                 status: [
                     {name: 0, value: '创建'},
@@ -353,6 +363,42 @@
                 },
                 showReceipt(task){
                     window.open(this.getReceiptUrl(task.id));
+                },
+                // 批量导入
+                importDischarge(){
+                    window.tempTip.setIndex(1999);
+
+                    let formData = new FormData();
+                    let file = document.querySelector('#importFile').files[0];
+                    if(file==null){
+                        window.tempTip.show('请选择上传文件');
+                    }
+                    formData.append('file',file);
+                    let url = '{{url('apiLocal/personnel/discharge/task/import')}}';
+                    window.axios.post(url,formData,{
+                        'Content-Type': 'multipart/form-data'
+                    }).then(res=>{
+                        if(res.data.success){
+                            window.tempTip.showSuccess(res.data.message ? res.data.message : '导入成功!刷新页面显示');
+                            return ;
+                        }else if(res.data.errors){
+                            window.tempTip.show('导入创建卸货任务失败!,详情请看列表')
+                            this.uploadErrors = res.data.errors;
+                            return ;
+                        }
+                        window.tempTip.show('导入失败!'+(res.data.message ? res.data.message : ''));
+                    }).catch(err=>{
+                        window.tempTip.show(err);
+                    });
+                },
+                importModal(){
+                    document.querySelector('#importFile').file = [];
+                    $('#importModal').modal('show');
+                },
+                cancelImport(){
+                    this.uploadErrors = [];
+                    $('#importModal').modal('hide');
+                    document.querySelector('#importFile').value = null;
                 }
 
 

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików