Эх сурвалжийг харах

Merge branch 'master' into Haozi

hu hao 5 жил өмнө
parent
commit
59eccbebf1
100 өөрчлөгдсөн 2202 нэмэгдсэн , 1219 устгасан
  1. 1 21
      app/Console/Commands/CheckCacheRackStorage.php
  2. 45 0
      app/Filters/OrderPackageReceivedSyncRecordFilters.php
  3. 46 0
      app/Filters/OwnerSundryFeeDetailFilters.php
  4. 30 0
      app/Http/Controllers/ControlPanelController.php
  5. 11 7
      app/Http/Controllers/CustomerController.php
  6. 16 0
      app/Http/Controllers/DeliveryAppointmentController.php
  7. 1 9
      app/Http/Controllers/OrderController.php
  8. 82 0
      app/Http/Controllers/OwnerSundryFeeDetailsController.php
  9. 20 51
      app/Http/Controllers/PriceModelController.php
  10. 4 2
      app/Http/Controllers/RejectedController.php
  11. 43 2
      app/Http/Controllers/StorageController.php
  12. 7 1
      app/Http/Controllers/StoreController.php
  13. 20 291
      app/Http/Controllers/TestController.php
  14. 52 57
      app/Http/Controllers/WaybillController.php
  15. 6 8
      app/Http/Controllers/WeighController.php
  16. 41 0
      app/Http/Requests/OwnerSundryFeeDetailRequest.php
  17. 14 0
      app/Http/Requests/Request.php
  18. 4 1
      app/Jobs/LogisticSFSync.php
  19. 4 1
      app/Jobs/LogisticYDSync.php
  20. 5 1
      app/Jobs/LogisticYTOSync.php
  21. 23 150
      app/Jobs/LogisticZopSync.php
  22. 21 0
      app/Observers/OwnerSundryFeeDetailObserver.php
  23. 22 0
      app/OrderPackageReceivedSyncRecord.php
  24. 6 0
      app/Owner.php
  25. 70 0
      app/OwnerSundryFeeDetail.php
  26. 20 0
      app/Policies/OwnerSundryFeeDetailPolicy.php
  27. 22 0
      app/Policies/Policy.php
  28. 156 85
      app/Providers/AppServiceProvider.php
  29. 1 0
      app/Providers/AuthServiceProvider.php
  30. 1 0
      app/Services/ForeignHaiRoboticsService.php
  31. 12 0
      app/Services/LogisticRouteInterface.php
  32. 1 1
      app/Services/LogisticYDService.php
  33. 87 77
      app/Services/LogisticZopService.php
  34. 5 0
      app/Services/MaterialBoxService.php
  35. 33 0
      app/Services/OrderPackageReceivedSyncRecordService.php
  36. 4 4
      app/Services/OrderPackageReceivedSyncService.php
  37. 2 5
      app/Services/OrderService.php
  38. 2 2
      app/Services/OwnerAreaReportService.php
  39. 0 7
      app/Services/OwnerPriceDirectLogisticService.php
  40. 0 8
      app/Services/OwnerPriceExpressService.php
  41. 0 7
      app/Services/OwnerPriceLogisticService.php
  42. 26 18
      app/Services/OwnerPriceOperationService.php
  43. 46 53
      app/Services/OwnerService.php
  44. 0 4
      app/Services/OwnerStoragePriceModelService.php
  45. 2 1
      app/Services/RejectedService.php
  46. 7 1
      app/Services/StationService.php
  47. 61 0
      app/Services/StorageService.php
  48. 4 4
      app/Services/WaybillService.php
  49. 14 3
      app/Storage.php
  50. 2 2
      app/Waybill.php
  51. 0 23
      app/library/zop/README.md
  52. 0 60
      app/library/zop/ZopClient.php
  53. 0 20
      app/library/zop/ZopHttpUtil.php
  54. 0 46
      app/library/zop/ZopProperties.php
  55. 0 59
      app/library/zop/ZopRequest.php
  56. 1 5
      composer.json
  57. 16 0
      database/factories/OrderPackageReceivedSyncRecordFactory.php
  58. 11 0
      database/factories/OwnerSundryFeeDetailFactory.php
  59. 4 3
      database/migrations/2020_11_30_140957_create_station_types_table.php
  60. 8 8
      database/migrations/2021_05_21_131520_add_order_packages_logistic_number_unique.php
  61. 27 0
      database/migrations/2021_05_27_103720_create_ownersundryfeedetails_table.php
  62. 39 0
      database/migrations/2021_05_27_105155_add_authority_settlement_bills.php
  63. 0 2
      database/migrations/2021_05_31_140957_create_station_types2_table.php
  64. 28 0
      database/migrations/2021_06_01_102357_add_authority_delivery_appointment_table_sign_id_data.php
  65. 34 0
      database/migrations/2021_06_01_103343_create_order_package_received_sync_records_table.php
  66. 44 0
      database/migrations/2021_06_02_114506_change_storages_table.php
  67. 24 0
      database/seeds/OrderPackageReceivedSyncRecordSeeder.php
  68. 20 0
      database/seeds/OwnerSundryFeeDetailsTableSeeder.php
  69. 23 0
      package-lock.json
  70. 1 1
      public/t.php
  71. 1 1
      resources/js/utilities/html2canvas.js
  72. 4 2
      resources/js/utilities/tempTip.js
  73. 90 1
      resources/views/control/panel.blade.php
  74. 4 0
      resources/views/customer/menu.blade.php
  75. 67 0
      resources/views/customer/ownerSundryFee/create_and_edit.blade.php
  76. 117 0
      resources/views/customer/ownerSundryFee/index.blade.php
  77. 30 0
      resources/views/customer/ownerSundryFee/menu.blade.php
  78. 44 0
      resources/views/customer/ownerSundryFee/show.blade.php
  79. 9 1
      resources/views/customer/project/create.blade.php
  80. 4 1
      resources/views/customer/project/part/_auditComparison.blade.php
  81. 6 6
      resources/views/customer/project/part/_operation.blade.php
  82. 4 0
      resources/views/finance/menu.blade.php
  83. 14 0
      resources/views/finance/settlementBills/menu.blade.php
  84. 65 0
      resources/views/finance/settlementBills/ownerSundryFee/create_and_edit.blade.php
  85. 105 0
      resources/views/finance/settlementBills/ownerSundryFee/index.blade.php
  86. 26 0
      resources/views/finance/settlementBills/ownerSundryFee/menu.blade.php
  87. 44 0
      resources/views/finance/settlementBills/ownerSundryFee/show.blade.php
  88. 2 1
      resources/views/order/index/delivering.blade.php
  89. 4 3
      resources/views/package/logistic/index.blade.php
  90. 4 4
      resources/views/package/measureMonitor/index.blade.php
  91. 7 1
      resources/views/package/weigh/index.blade.php
  92. 10 0
      resources/views/shared/_error.blade.php
  93. 9 0
      resources/views/shared/_messages.blade.php
  94. 7 4
      resources/views/station/monitor/show.blade.php
  95. 10 0
      resources/views/store/deliveryAppointment/list.blade.php
  96. 63 1
      resources/views/store/inStorage/cacheRackStorage.blade.php
  97. 61 81
      resources/views/transport/waybill/index.blade.php
  98. 1 0
      routes/apiLocal.php
  99. 7 0
      routes/web.php
  100. 1 1
      tests/Feature/LogisticZopSyncTest.php

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

@@ -46,26 +46,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();
-        $collection = new Collection();
-        $stationCollection = new Collection();
-        $blacklist = [];
-        foreach ($stations as $station){
-            $box = app("MaterialBoxService")->getAnEmptyBox($blacklist);
-            if (!$box)continue;
-            $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;
-        }
-        app("ForeignHaiRoboticsService")->fetchGroup_multiLocation($stationCollection,$collection,'','立架出至缓存架');
+        app("StorageService")->paddingCacheShelf($stations);
     }
 }

+ 45 - 0
app/Filters/OrderPackageReceivedSyncRecordFilters.php

@@ -0,0 +1,45 @@
+<?php
+
+
+namespace App\Filters;
+
+
+use Illuminate\Http\Request;
+use Illuminate\Database\Query\Builder;
+
+class OrderPackageReceivedSyncRecordFilters
+{
+    protected $request;
+    /**
+     * @var $queryBuilder Builder
+     */
+    protected $queryBuilder;
+    protected $filters = ['start', 'end', 'logistic_name'];
+
+    public function __construct(Request $request)
+    {
+        $this->request = $request;
+    }
+
+    public function apply($builder)
+    {
+        $this->queryBuilder = $builder;
+        $filters = array_filter($this->request->only($this->filters));
+        foreach ($filters as $filter => $value) {
+            if (method_exists($this, $filter)) {
+                $this->$filter($value, $this->queryBuilder);
+            }
+        }
+        return $this->queryBuilder;
+    }
+
+    public function start($start)
+    {
+        $this->queryBuilder->whereDate('recorded_at', '>=', $start);
+    }
+
+    public function end($end)
+    {
+        $this->queryBuilder->whereDate('recorded_at', '<=', $end);
+    }
+}

+ 46 - 0
app/Filters/OwnerSundryFeeDetailFilters.php

@@ -0,0 +1,46 @@
+<?php
+
+
+namespace App\Filters;
+
+use App\Order;
+use App\Services\UserService;
+use Illuminate\Http\Request;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Str;
+use phpDocumentor\Reflection\Types\Boolean;
+
+class OwnerSundryFeeDetailFilters
+{
+    protected $request;
+    protected $queryBuilder;
+    protected $filters = ['owner_id'];
+
+    public function __construct(Request $request)
+    {
+        $this->request = $request;
+    }
+
+    public function apply($builder)
+    {
+        $this->queryBuilder = $builder;
+        $filters = array_filter($this->request->only($this->filters));
+        foreach ($filters as $filter => $value) {
+            if (method_exists($this, $filter)) {
+                $this->$filter($value, $this->queryBuilder);
+            }
+        }
+        return $this->queryBuilder;
+    }
+
+
+    private function owner_id($owner_id)
+    {
+        if (strpos($owner_id, ',') || strpos($owner_id, ',') || strpos($owner_id, ' ')) {
+            $arr = array_filter(preg_split('/[,, ]+/is', $owner_id));
+            $this->queryBuilder->whereIn('owner_id',$arr);
+        } else {
+            $this->queryBuilder->where('owner_id','like',$owner_id."%");
+        }
+    }
+}

+ 30 - 0
app/Http/Controllers/ControlPanelController.php

@@ -3,7 +3,9 @@
 namespace App\Http\Controllers;
 
 use App\Components\AsyncResponse;
+use App\Filters\OrderPackageReceivedSyncRecordFilters;
 use App\OrderPackageCountingRecord;
+use App\OrderPackageReceivedSyncRecord;
 use App\Owner;
 use App\Services\CacheService;
 use App\Services\CheckActiveMenuService;
@@ -160,6 +162,34 @@ class ControlPanelController extends Controller
         $this->success(["title"=>$title,"data"=>$data]);
     }
 
+
+    /**
+     * 快递信息同步失败成功占比
+     * @param OrderPackageReceivedSyncRecordFilters $filters
+     * @param Request $request
+     * @return array
+     */
+    public function orderPackageReceivedSyncRecordApi(OrderPackageReceivedSyncRecordFilters $filters, Request $request)
+    {
+        $orderPackageReceivedSyncRecords = OrderPackageReceivedSyncRecord::query()->filter($filters)->get();
+        $data = [];
+        foreach ($orderPackageReceivedSyncRecords as $orderPackageReceivedSyncRecord) {
+            $total = $orderPackageReceivedSyncRecord->succeed_count + $orderPackageReceivedSyncRecord->failed_count;
+            $data[] = [
+                'date' => $orderPackageReceivedSyncRecord->recorded_at,
+                'total'=> $total,
+                'count'=>$orderPackageReceivedSyncRecord->succeed_count,
+                'value' => (int)($orderPackageReceivedSyncRecord->succeed_count / $total*100),
+                'logistic_name' =>$orderPackageReceivedSyncRecord->logistic_name
+            ];
+        }
+        $title = [];
+        foreach ($data as $data_item) {
+            $title[] = $data_item['date'];
+        }
+        return ['success' =>true, 'data' =>['data'=>$data,'title'=>$title]];
+    }
+
     public function exceptionTypeApi(Request $request)
     {
         $ownerIds=$request->owner_ids;

+ 11 - 7
app/Http/Controllers/CustomerController.php

@@ -552,27 +552,31 @@ class CustomerController extends Controller
         $owner = request("owner");
         $sql = <<<sql
 SELECT owner_id,SUM(IFNULL(work_fee,0)) AS work_fee,SUM(IFNULL(logistic_fee,0)) AS logistic_fee 
-FROM owner_fee_details WHERE worked_at LIKE ? 
+FROM owner_fee_details WHERE worked_at LIKE ? AND ((type = '发货' AND logistic_fee IS NOT NULL AND work_fee IS NOT NULL) OR (type <> '发货' AND work_fee IS NOT NULL))
 sql;
         if ($owner && count($owner)>0){
             $sql.=" AND owner_id IN (''";
             foreach ($owner as $o)$sql .=",'{$o}'";
             $sql.=")";
         }
-        $sql .= " AND ((type = '发货' AND logistic_fee IS NOT NULL AND work_fee IS NOT NULL) OR (type <> '发货' AND work_fee IS NOT NULL))  GROUP BY owner_id";
+        $sql .= " GROUP BY owner_id";
 
         $billDetails = DB::select(DB::raw($sql),[$month."%"]);
 
-        $areas = OwnerAreaReport::query()->with("ownerStoragePriceModel")->where("counting_month","like",$month."%")->get();
+        $areas = OwnerAreaReport::query()->with(["ownerStoragePriceModel.timeUnit","ownerStoragePriceModel.taxRate"])->where("counting_month","like",$month."%")->get();
         $map = [];
+        $mapTax = [];
         foreach($areas as $area){
-            if (isset($map[$area->owner_id."_".$area->counting_month])){
+            $key = $area->owner_id."_".$area->counting_month;
+            if (isset($map[$key])){
                 if (!$area->ownerStoragePriceModel)continue;
-                $map[$area->owner_id."_".$area->counting_month] += app('OwnerStoragePriceModelService')
+                list($money,$taxFee) = app('OwnerStoragePriceModelService')
                     ->calculationAmount($area->ownerStoragePriceModel,$area->accounting_area,$area->owner_id,$area->counting_month);
+                $map[$key] += $money;
+                $mapTax[$key] += $taxFee;
             }else{
                 if (!$area->ownerStoragePriceModel)continue;
-                $map[$area->owner_id."_".$area->counting_month] = app('OwnerStoragePriceModelService')
+                list($map[$key],$mapTax[$key]) = app('OwnerStoragePriceModelService')
                     ->calculationAmount($area->ownerStoragePriceModel,$area->accounting_area,$area->owner_id,$area->counting_month);
             }
         }
@@ -583,7 +587,7 @@ sql;
                 $key = $bill->owner_id."_".$month;
                 OwnerBillReport::query()->where("owner_id",$bill->owner_id)
                     ->where("counting_month",$month."-01")
-                    ->update(["work_fee"=>$bill->work_fee,"logistic_fee"=>$bill->logistic_fee,"storage_fee"=>$map[$key] ?? 0]);
+                    ->update(["work_fee"=>$bill->work_fee,"logistic_fee"=>$bill->logistic_fee,"storage_fee"=>$map[$key] ?? 0,"storage_tax_fee"   => $mapTax[$key] ?? 0]);
             }
         }
         $this->success();

+ 16 - 0
app/Http/Controllers/DeliveryAppointmentController.php

@@ -562,6 +562,7 @@ html;
      */
     public function unloading()
     {
+        $this->gate("入库管理-入库预约-预约管理-卸货完成");
         if (!request("id"))$this->error("非法参数");
         /** @var DeliveryAppointmentCar|\stdClass $car */
         $car = DeliveryAppointmentCar::query()->find(request("id"));
@@ -572,6 +573,21 @@ html;
         $this->success();
     }
 
+    /**
+     * 管理员代替签到
+     */
+    public function signIn()
+    {
+        $this->gate("入库管理-入库预约-预约管理-签到");
+        if (!request("id"))$this->error("非法参数");
+        /** @var DeliveryAppointmentCar|\stdClass $car */
+        $car = DeliveryAppointmentCar::query()->find(request("id"));
+        if (!$car || !$car->deliveryAppointment)$this->error("单据不存在");
+        $car->update(["status"=>1]);
+        event(new DeliveryAppointmentEvent($car));
+        $this->success();
+    }
+
     /**
      * 产能维护
      * */

+ 1 - 9
app/Http/Controllers/OrderController.php

@@ -86,15 +86,7 @@ class OrderController extends Controller
             "SKU"=>"产品代码","ALTERNATE_SKU1"=>"产品条码","ORDERDETAILCODENAME"=>"明细状态","DESCR_C"=> "产品名称",
             "QTYORDERED"=>"订单数量","CHECKTIME"=>"复核时间","ERPCANCELFLAG"=>"接口取消标记",
             "PICKING_PRINT_FLAG"=>"拣货单打印标记","EDISENDFLAG"=>"接口回传标记","EDIREMARKS2"=>"接口回传异常备注",
-            "RELEASESTATUS"=>"订单冻结"])->direct();
-        /*$post = Http::post(config('go.export.url'),$req);
-        if ($post->status() == 500){
-            throw new Exception($post->header("Msg"));
-        }
-        return response($post,200, [
-            "Content-type"=>"application/octet-stream",
-            "Content-Disposition"=>"attachment; filename=订单记录-".date('ymdHis').'.xlsx',
-        ]);*/
+            "RELEASESTATUS"=>"订单冻结"],["ADDTIME"=>"date","EDISENDTIME2"=>"date"])->direct();
     }
 
     public function createRejectedBill(Request $request){

+ 82 - 0
app/Http/Controllers/OwnerSundryFeeDetailsController.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Filters\OwnerSundryFeeDetailFilters;
+use App\Owner;
+use App\OwnerSundryFeeDetail;
+use Illuminate\Http\Request;
+use App\Http\Requests\OwnerSundryFeeDetailRequest;
+
+class OwnerSundryFeeDetailsController extends Controller
+{
+    public function __construct()
+    {
+        $this->middleware('auth');
+    }
+
+    public function index(Request $request, OwnerSundryFeeDetailFilters $filters)
+    {
+        $paginateParams = $request->input();
+        $owner_sundry_fee_details = OwnerSundryFeeDetail::query()->filter($filters)->with('owner')->orderByDesc('updated_at')->paginate($request->paginate ?? 50);
+        $owners = Owner::all();
+        return view('customer.ownerSundryFee.index', compact('owner_sundry_fee_details', 'paginateParams','owners'));
+    }
+
+    public function show($owner_sundry_fee_detail)
+    {
+        $owner_sundry_fee_detail = OwnerSundryFeeDetail::find($owner_sundry_fee_detail);
+        $owner_sundry_fee_detail->loadMissing('owner');
+        return view('customer.ownerSundryFee.show', compact('owner_sundry_fee_detail'));
+    }
+
+    public function create(OwnerSundryFeeDetail $owner_sundry_fee_detail)
+    {
+        $types = [
+            '材料',
+            '垫付',
+            '人工',
+            '其他',
+        ];
+        $owners = Owner::all();
+        return view('customer.ownerSundryFee.create_and_edit', compact('owner_sundry_fee_detail', 'types','owners'));
+    }
+
+    public function store(OwnerSundryFeeDetailRequest $request)
+    {
+        $owner_sundry_fee_detail = OwnerSundryFeeDetail::create($request->all());
+        return redirect()->route('ownerSundryFeeDetails.index', $owner_sundry_fee_detail->id)->with('success', '创建成功');
+    }
+
+    public function edit($owner_sundry_fee_detail)
+    {
+        $owner_sundry_fee_detail = OwnerSundryFeeDetail::find($owner_sundry_fee_detail);
+        $owner_sundry_fee_detail->loadMissing('owner');
+        $this->authorize('update', $owner_sundry_fee_detail);
+        $types = [
+            '材料',
+            '垫付',
+            '人工',
+            '其他',
+        ];
+        $owners = Owner::all();
+
+        return view('customer.ownerSundryFee.create_and_edit', compact('owner_sundry_fee_detail','types','owners'));
+    }
+
+    public function update(OwnerSundryFeeDetailRequest $request, $owner_sundry_fee_detail)
+    {
+        $owner_sundry_fee_detail = OwnerSundryFeeDetail::find($owner_sundry_fee_detail);
+        $this->authorize('update', $owner_sundry_fee_detail);
+        $owner_sundry_fee_detail->update($request->all());
+        return redirect()->route('ownerSundryFeeDetails.index', $owner_sundry_fee_detail->id)->with('success', '更新成功');
+    }
+
+    public function destroy($owner_sundry_fee_detail)
+    {
+        $owner_sundry_fee_detail = OwnerSundryFeeDetail::find($owner_sundry_fee_detail);
+        $this->authorize('destroy', $owner_sundry_fee_detail);
+        $owner_sundry_fee_detail->delete();
+        return redirect()->route('ownerSundryFeeDetails.index')->with('success', '删除成功');
+    }
+}

+ 20 - 51
app/Http/Controllers/PriceModelController.php

@@ -55,8 +55,7 @@ class PriceModelController extends Controller
         $this->storageValidator($request->input())->validate();
         /** @var OwnerStoragePriceModel $model */
         $model = app('OwnerStoragePriceModelService')->create($request->input());
-        $result = $model->owners()->sync(explode(",",$request->input("owner_id")));
-        app("OwnerService")->refreshRelevance($result["attached"],0);
+        $model->owners()->sync(explode(",",$request->input("owner_id")));
         LogService::log(__METHOD__,"计费模型-创建仓储计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
         return response()->redirectTo('maintenance/priceModel/storage')->with('successTip',"创建成功!");
     }
@@ -92,9 +91,7 @@ class PriceModelController extends Controller
             $service->update(["id"=>$id],$values);
             $model = new OwnerStoragePriceModel();
             $model->id = $id;
-            $result = $model->owners()->sync(explode(",",request("owner_id")));
-            app("OwnerService")->refreshRelevance($result["attached"],0);
-            app("OwnerService")->refreshRelevance($result["detached"],0,true);
+            $model->owners()->sync(explode(",",request("owner_id")));
         }else $service->copy($model,$values,explode(",",request("owner_id")));
         return response()->redirectTo('maintenance/priceModel/storage')->with('successTip',"更新成功!");
     }
@@ -321,11 +318,7 @@ class PriceModelController extends Controller
         }
         //录入中间表
         /** @var OwnerPriceOperation $ownerPriceOperation */
-        if ($request->input("owner_id")){
-            $result = $ownerPriceOperation->owners()->sync($request->input("owner_id"));
-            app("OwnerService")->refreshRelevance($result["attached"],1);
-            app("OwnerService")->refreshRelevance($result["detached"],1,true);
-        }
+        if ($request->input("owner_id"))$ownerPriceOperation->owners()->sync($request->input("owner_id"));
         LogService::log(__METHOD__,"计费模型-录入作业计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
         return response()->redirectTo("maintenance/priceModel/operation")->with("successTip","创建“".$request->input("name")."”成功");
     }
@@ -381,11 +374,7 @@ class PriceModelController extends Controller
             }
             //录入中间表
             /** @var OwnerPriceOperation $model */
-            if ($request->input("owner_id")){
-                $result = $model->owners()->sync(request("owner_id"));
-                app("OwnerService")->refreshRelevance($result["attached"],1);
-                app("OwnerService")->refreshRelevance($result["detached"],1,true);
-            }
+            if ($request->input("owner_id"))$model->owners()->sync(request("owner_id"));
         }else $service->copy($model,$obj,request("owner_id"),request("items"),false);
         LogService::log(__METHOD__,"计费模型-修改作业计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
         return response()->redirectTo("maintenance/priceModel/operation")->with("successTip","修改“".$request->input("name")."”成功");
@@ -516,9 +505,7 @@ class PriceModelController extends Controller
             "initial_weight" => $request->input("initial_weight"),
             "additional_weight" => $request->input("additional_weight"),
         ]);
-        $result = $model->owners()->sync($request->input("owner_id"));
-        app("OwnerService")->refreshRelevance($result["attached"],2);
-        app("OwnerService")->refreshRelevance($result["detached"],2,true);
+        $model->owners()->sync($request->input("owner_id"));
         $model->logistics()->sync($request->input("logistic_id"));
         LogService::log(__METHOD__,"计费模型-录入快递计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
         return response()->redirectTo("maintenance/priceModel/express")->with("successTip","录入“".$request->input("name")."”成功");
@@ -550,9 +537,7 @@ class PriceModelController extends Controller
             app("OwnerPriceExpressService")->update(["id"=>$id],$values);
             $model = new OwnerPriceExpress();
             $model->id = $id;
-            $result = $model->owners()->sync($request->input("owner_id"));
-            app("OwnerService")->refreshRelevance($result["attached"],2);
-            app("OwnerService")->refreshRelevance($result["detached"],2,true);
+            $model->owners()->sync($request->input("owner_id"));
             $model->logistics()->sync($request->input("logistic_id"));
         }else app("OwnerPriceExpressService")->copy($model,$values,$request->input("owner_id"),$request->input("logistic_id"));
         LogService::log(__METHOD__,"计费模型-修改快递计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
@@ -637,9 +622,7 @@ class PriceModelController extends Controller
             "other_unit_id" => $request->input("other_unit_id"),
             "other_unit_range" => $request->input("other_unit_range"),
         ]);
-        $result = $model->owners()->sync($request->input("owner_id"));
-        app("OwnerService")->refreshRelevance($result["attached"],3);
-        app("OwnerService")->refreshRelevance($result["detached"],3,true);
+        $model->owners()->sync($request->input("owner_id"));
         $model->logistics()->sync($request->input("logistic_id"));
         LogService::log(__METHOD__,"计费模型-录入物流计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
         return response()->redirectTo("maintenance/priceModel/logistic")->with("successTip","创建“".$request->input("name")."”成功");
@@ -675,9 +658,7 @@ class PriceModelController extends Controller
             app("OwnerPriceLogisticService")->update(["id"=>$id],$values);
             $model = new OwnerPriceLogistic();
             $model->id = $id;
-            $result = $model->owners()->sync($request->input("owner_id"));
-            app("OwnerService")->refreshRelevance($result["attached"],3);
-            app("OwnerService")->refreshRelevance($result["detached"],3,true);
+            $model->owners()->sync($request->input("owner_id"));
             $model->logistics()->sync($request->input("logistic_id"));
         }else app("OwnerPriceLogisticService")->copy($model,$values,$request->input("owner_id"),$request->input("logistic_id"));
 
@@ -954,9 +935,7 @@ class PriceModelController extends Controller
             "name" => $request->input("name"),
             "base_km" => $request->input("base_km"),
         ]);
-        $result = $model->owners()->sync($request->input("owner_id"));
-        app("OwnerService")->refreshRelevance($result["attached"],4);
-        app("OwnerService")->refreshRelevance($result["detached"],4,true);
+        $model->owners()->sync($request->input("owner_id"));
         LogService::log(__METHOD__,"计费模型-录入直发车计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
         return response()->redirectTo("maintenance/priceModel/directLogistic")->with("successTip","创建“".$request->input("name")."”成功");
     }
@@ -995,9 +974,7 @@ class PriceModelController extends Controller
             app("OwnerPriceDirectLogisticService")->update(["id"=>$id],$values);
             $model = new OwnerPriceDirectLogistic();
             $model->id = $id;
-            $result = $model->owners()->sync($request->input("owner_id"));
-            app("OwnerService")->refreshRelevance($result["attached"],4);
-            app("OwnerService")->refreshRelevance($result["detached"],4,true);
+            $model->owners()->sync($request->input("owner_id"));
         }else app("OwnerPriceDirectLogisticService")->copy($model,$values,request("owner_id"));
         LogService::log(__METHOD__,"计费模型-修改直发车计费",json_encode($request->input(),JSON_UNESCAPED_UNICODE));
         return response()->redirectTo("maintenance/priceModel/directLogistic")->with("successTip","修改“".$request->input("name")."”成功");
@@ -1146,7 +1123,6 @@ class PriceModelController extends Controller
         }else{
             $model = app('OwnerStoragePriceModelService')->create($values);
             DB::insert(DB::raw("INSERT INTO owner_storage_price_model_owner VALUES(?,?)"),[$model->id,request("owner_id")]);
-            app("OwnerService")->refreshRelevance(request("owner_id"),0);
             $this->success($model->id);
         }
     }
@@ -1225,7 +1201,6 @@ class PriceModelController extends Controller
                 }
                 app("OwnerPriceOperationItemService")->insert($params["items"]);
                 DB::insert(DB::raw("INSERT INTO owner_price_operation_owner(owner_price_operation_id,owner_id) VALUES(?,?)"),[$model->id,request("owner_id")]);
-                app("OwnerService")->refreshRelevance(request("owner_id"),1);
                 DB::commit();
             });
         }
@@ -1300,7 +1275,6 @@ class PriceModelController extends Controller
                 }
                 OwnerPriceExpressProvince::query()->insert($params["items"]);
                 DB::insert(DB::raw("INSERT INTO owner_price_express_owner VALUES(?,?)"),[$model->id,request("owner_id")]);
-                app("OwnerService")->refreshRelevance(request("owner_id"),2);
                 /** @var OwnerPriceExpress $model */
                 $model->logistics()->syncWithoutDetaching(request("logistics"));
                 DB::commit();
@@ -1382,7 +1356,6 @@ class PriceModelController extends Controller
                 foreach ($params["items"] as &$param)$param["owner_price_logistic_id"] = $model->id;
                 OwnerPriceLogisticDetail::query()->insert($params["items"]);
                 DB::insert(DB::raw("INSERT INTO owner_price_logistic_owner VALUES(?,?)"),[$model->id,request("owner_id")]);
-                app("OwnerService")->refreshRelevance(request("owner_id"),3);
                 /** @var OwnerPriceLogistic $model */
                 $model->logistics()->syncWithoutDetaching(request("logistics"));
                 DB::commit();
@@ -1447,7 +1420,6 @@ class PriceModelController extends Controller
                 foreach ($items as &$item)$item["owner_price_direct_logistic_id"] = $model->id;
                 OwnerPriceDirectLogisticCar::query()->insert($items);
                 DB::insert(DB::raw("INSERT INTO owner_price_direct_logistic_owner VALUES(?,?)"),[$model->id,request("owner_id")]);
-                app("OwnerService")->refreshRelevance(request("owner_id"),4);
                 DB::commit();
             });
         }
@@ -1807,11 +1779,12 @@ class PriceModelController extends Controller
         /** @var \stdClass|Owner $owner */
         $owner = new Owner();
         $owner->id = $ownerId;
+        $response = null;
         switch (request("type")){
             case "storage":
                 app("OwnerStoragePriceModelService")->auditOrRecover(request("isAudit"),$ownerId);//priceModelAuditOrRecoverQuery
                 $owner->load("ownerStoragePriceModels");
-                $this->success($owner->ownerStoragePriceModels);
+                $response = $owner->ownerStoragePriceModels;
                 break;
             case "operation":
                 app("OwnerPriceOperationService")->auditOrRecover(request("isAudit"),$ownerId);
@@ -1834,7 +1807,7 @@ class PriceModelController extends Controller
                         }
                     }
                 }
-                $this->success($owner->ownerPriceOperations);
+                $response = $owner->ownerPriceOperations;
                 break;
             case "express":
                 app("OwnerPriceExpressService")->auditOrRecover(request("isAudit"),$ownerId);
@@ -1842,7 +1815,7 @@ class PriceModelController extends Controller
                     /** @var Builder $query */
                     $query->with(["details","logistics"]);
                 }]);
-                $this->success($owner->ownerPriceExpresses);
+                $response = $owner->ownerPriceExpresses;
                 break;
             case "logistic":
                 app("OwnerPriceLogisticService")->auditOrRecover(request("isAudit"),$ownerId);
@@ -1850,7 +1823,7 @@ class PriceModelController extends Controller
                     /** @var Builder $query */
                     $query->with(["details","logistics"]);
                 }]);
-                $this->success($owner->ownerPriceLogistics);
+                $response = $owner->ownerPriceLogistics;
                 break;
             case "directLogistic":
                 app("OwnerPriceDirectLogisticService")->auditOrRecover(request("isAudit"),$ownerId);
@@ -1859,18 +1832,14 @@ class PriceModelController extends Controller
                 break;
             case "system":
                 $result = app(QueryService::class)->priceModelAuditOrRecoverQuery(request("isAudit"),OwnerPriceSystem::query(),$ownerId,null,true);
-                if ($result["delete"]){
-                    OwnerPriceSystem::destroy($result["delete"]);
-                    app("OwnerService")->refreshRelevance($ownerId,5,true);
-                }
-                if ($result["update"]){
-                    OwnerPriceSystem::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
-                    app("OwnerService")->refreshRelevance($ownerId,5);
-                }
+                if ($result["delete"])OwnerPriceSystem::destroy($result["delete"]);
+                if ($result["update"])OwnerPriceSystem::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
                 $owner->load("ownerPriceSystem");
-                $this->success($owner->ownerPriceSystem);
+                $response = $owner->ownerPriceSystem;
                 break;
         }
+        app("OwnerService")->refreshRelevance($ownerId);
+        $this->success($response);
     }
 
     /**

+ 4 - 2
app/Http/Controllers/RejectedController.php

@@ -399,6 +399,8 @@ class RejectedController extends Controller
 //        return ['success'=>$re];
     }
     public function export(Request $request){
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
         if(!Gate::allows('退货管理-查询')){ return '没有权限';  }
         if ($request->checkAllSign){
             $param = $request->input();
@@ -418,9 +420,9 @@ class RejectedController extends Controller
             "owner_name"=>"客户名称","order_number"=>"订单号",
             "sender"=>"姓名","mobile_sender"=>"手机",
             "logistic_number"=>"原单单号","logistic_number_return"=>"退回单号","logistic_name"=>"退回公司",
-            "fee_collected"=>"到付费用","is_loaded"=>"是否入库",
+            "fee_collected"=>"到付费用","loaded"=>"是否入库",
             "item_barcode"=>"商品条码","item_name"=>"商品名称",
-            "item_amount"=>"商品数量","quality_label_name"=>"商品质量"
+            "item_amount"=>"商品数量","quality_label_name"=>"商品质量","operator_name"=>"录入人"
         ])->direct();
     }
 

+ 43 - 2
app/Http/Controllers/StorageController.php

@@ -5,6 +5,10 @@ namespace App\Http\Controllers;
 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 Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
@@ -21,7 +25,7 @@ class StorageController extends Controller
         $amount = (int)\request("amount");
         //check info
         if (!$asn || !$ide || !$barCode || !$amount)$this->error("信息不完整");
-        $fromLocation = 'HAIB1-03-03';//app("MaterialBoxService")->getBoxLocation($ide);
+        $fromLocation = app("MaterialBoxService")->getBoxLocation($ide);
         if (!$fromLocation)$this->error("海柔无此库位信息");
         $box = MaterialBox::query()->select("id")->where("code",$ide)->first();
         if (!$box)$this->error("WAS无此料箱");
@@ -55,7 +59,9 @@ sql;
         //亮灯
         app("CacheShelfService")->_stationCacheLightOn($fromLocation,$ide);
         //建立入库任务
-        app("ForeignHaiRoboticsService")->putWareHousing($fromLocation,'',$box->id);
+        if (!app("ForeignHaiRoboticsService")->putWareHousing($fromLocation,'',$box->id))$this->error("错误库位或库位已被下达任务");
+        //占用库位 应在任务完成后释放
+        app("StorageService")->markOccupy($fromLocation);
         $this->success();
     }
 
@@ -180,4 +186,39 @@ sql;
     {
         ValueStore::query()->select("value")->where("name","flux_tr_number")->update(["value"=>DB::raw("flux_tr_number+1")]);
     }
+
+    /**
+     * 重置缓存架指定格口
+     */
+    public function resetCacheShelf()
+    {
+        $boxes = request("boxes");
+        //清理任务
+        $data = '';
+        $station = Station::query()->select("id")->whereIn("code",$boxes);
+        $occupy = Storage::query()->with("station:id,code")->whereIn("station_id",$station)->where("status",1)->get();
+        foreach ($occupy as $item){
+            unset($boxes[array_search($item->station->code,$boxes)]);
+            $data .= '“'.$item->station->code.'”,';
+        }
+        if ($occupy->count()>0){
+            $data .= "存在任务待处理,无法释放";
+            $boxes = array_values($boxes);
+            $station = Station::query()->select("id")->whereIn("code",$boxes);
+        }
+        $task = StationTask::query()->select("id")->where("status","!=",'完成')->whereIn("station_id",$station);
+        StationTaskMaterialBox::query()->where("status","!=",'完成')->whereIn("station_task_id",$task)->update([
+            "status" => "完成"
+        ]);
+        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,
+        ]);
+        //重新调取料箱
+        app("StorageService")->paddingCacheShelf($station->get());
+        $this->success(["data"=>$data,"boxes"=>$boxes]);
+    }
 }

+ 7 - 1
app/Http/Controllers/StoreController.php

@@ -6,6 +6,8 @@ use App\Depository;
 use App\Owner;
 use App\Services\common\BatchUpdateService;
 use App\Services\StoreService;
+use App\Station;
+use App\Storage;
 use App\Store;
 use App\StoreItem;
 use App\Warehouse;
@@ -438,6 +440,10 @@ class StoreController extends Controller
      */
     public function cacheRackStorage()
     {
-        return \view("store.inStorage.cacheRackStorage");
+        $stations = Station::query()->select("id")->where("parent_id",6);
+        $storages = Storage::query()->with("station:id,code")->whereIn("station_id",$stations)->where(function (Builder $query){
+            $query->whereNotNull("material_box_id")->orWhere("status",1);
+        })->get();
+        return \view("store.inStorage.cacheRackStorage",compact("storages"));
     }
 }

+ 20 - 291
app/Http/Controllers/TestController.php

@@ -121,298 +121,21 @@ class TestController extends Controller
     {
         return call_user_func([$this, $method], $request);
     }
-    public function createCacheRack()
-    {
-        $stations = [
-            "HAIB1-01-02","HAIB1-01-03",
-            "HAIB1-02-01","HAIB1-02-03",
-            "HAIB1-03-01","HAIB1-03-02","HAIB1-03-03"
-        ];
-        foreach ($stations as $station){
-            Station::query()->create([
-                "parent_id" => 6,
-                "name" => $station,
-                "code" => $station,
-                "station_type_id" => 5,
-            ]);
-        }
-        dd("OK");
-    }
-    /**
-     * @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;
-    }
-    /**
-     * @param $wave
-     * @return string
-     */
-    private function wms_status($wave): string
-    {
-        switch ($wave->wavestatus) {
-            case 00:
-                $wms_status = '创建';
-                break;
-            case 40:
-                $wms_status = '部分收货';
-                break;
-            case 90:
-                $wms_status = '取消';
-                break;
-            case 99:
-                $wms_status = '完成';
-                break;
-            case 62:
-                $wms_status = '部分装箱';
-                break;
-            default:
-                $wms_status = (string)$wave->wavestatus;
-        }
-        return $wms_status;
-    }
-    /** @var DocWaveHeaderService $service */
-    private $service;
-    /** @var BatchService $batchService */
-    private $batchService;
-
-    private function detailExe($details)
-    {
-        $this->service = app(DocWaveHeaderService::class);
-        $this->batchService = app(BatchService::class);
-        if (count($details) < 1)return;
-        $map = [];
-        $nos = [];
-        $orderCodes = [];
-        $seqnos = [];
-        $batchMapping = [];
-        foreach ($details as $detail){
-            if (isset($map[$detail->waveno]))$map[$detail->waveno][] = $detail->orderno;
-            else {
-                $map[$detail->waveno] = [$detail->orderno];
-                $nos[] = $detail->waveno;
-            }
-            $orderCodes[] = $detail->orderno;
-            $seqnos[$detail->orderno] = $detail->seqno;
-            $batchMapping[$detail->orderno] = $detail->waveno;
-        }
-        $orders = Order::query()->select("id","batch_id","code")->whereIn("code",$orderCodes)->get();
-        if (count($orderCodes) != count($orders))LogService::log(__CLASS__,"格口号-订单存在差异",json_encode($orderCodes));
-        if ($orders){
-            $orderIds = [];
-            $orderMap = [];
-            $existOrder = [];
-            foreach ($orders as $order){
-                $orderIds[] = $order->id;
-                $orderMap[$order->id] = $seqnos[$order->code];
-                $existOrder[$order->code] = $order->batch_id;
-            }
-            $updateBin = [["id","number"]];
-            $insertBin = [];
-            $deleteBin = [];
-            $orderBins = OrderBin::query()->select("id","order_id","number")->whereIn("order_id",$orderIds)->get();
-            foreach ($orderBins as $orderBin){
-                if (!isset($orderMap[$orderBin->order_id])){
-                    $deleteBin[] = $orderBin->id;
-                    continue;
-                }
-                if ($orderBin->number != $orderMap[$orderBin->order_id])$updateBin[]=["id"=>$orderBin->id,"number"=>$orderMap[$orderBin->order_id]];
-                unset($orderMap[$orderBin->order_id]);
-            }
-            $d = date('Y-m-d H:i:s');
-            foreach ($orderMap as $orderId=>$binNumber){
-                $insertBin[]=[
-                    "order_id"=>$orderId,
-                    "number"=>$binNumber,
-                    'created_at' => $d
-                ];
-            }
-            if (count($updateBin)>1){
-                app(BatchUpdateService::class)->batchUpdate("order_bins",$updateBin);
-                LogService::log(__METHOD__,"波次同步-更新订单格口号",json_encode($updateBin));
-            }
-            if ($insertBin){
-                OrderBin::query()->insert($insertBin);
-                LogService::log(__METHOD__,"波次同步-录入订单格口号",json_encode($insertBin));
-            }
-            if ($deleteBin){
-                OrderBin::destroy($deleteBin);
-                LogService::log(__METHOD__,"波次同步-删除订单格口号",json_encode($deleteBin));
-            }
-        }
-        $batches = $this->batchService->get(["code"=>$nos]);
-        $batchDiff = array_keys(array_flip(array_diff($nos,array_column($batches->toArray(),"code"))));
-        if (count($batchDiff)>0){
-            $sql = <<<sql
-SELECT * FROM DOC_WAVE_HEADER WHERE WAVENO IN (''
-sql;
-            foreach ($batchDiff as $bd)$sql .= ",'".$bd."'";
-            $sql .= ')';
-            $wmsBatches = DB::connection("oracle")->select(DB::raw($sql));
-            $this->headerExe($wmsBatches);
-            $batches = $this->batchService->get(["code"=>$nos]);
-        }
-        $updateOrder = [["code","batch_id"]];
-        $updatingBatches = [];
-        foreach ($batches as $batch){
-            $mark = false;
-            foreach ($map[$batch->code] as $on){
-                if ((!isset($existOrder[$on])) || $existOrder[$on]!=$batch->id){
-                    $updateOrder[] = [
-                        "code"=>$on,
-                        "batch_id"=>$batch->id
-                    ];
-                    $mark = true;
-                }
-            }
-            if ($mark)$updatingBatches[] = $batch;
-            unset($map[$batch->code]);
-        }
-        if (count($updateOrder)>1){
-            app("OrderService")->batchUpdate($updateOrder);//反向修改订单
-            LogService::log(__METHOD__,"波次同步-修改订单波次号",json_encode($updateOrder));
-            app("BatchService")->checkBatchOrderInfo($updatingBatches);
-           dump($updatingBatches);
-        }
-        if ($map){
-            $waveCodes = array_keys($map);
-            $waves = $this->service->get(["waveno"=>$waveCodes],["waveno"=>"in"]);
-            $insert = [];
-            foreach ($waves as $wave){
-                $owner = app("OwnerService")->codeGetOwner($wave->customerid);
-                $insert[] = [
-                    "code" => $wave->waveno,
-                    "status" => '未处理',
-                    "wms_status" => $this->wms_status($wave),
-                    "wms_type"=>$wave->descr,
-                    "created_at"=>$wave->addtime,
-                    "updated_at"=>$wave->edittime,
-                    "owner_id"=>$owner->id,
-                ];
-            }
-            if ($insert){
-                $this->batchService->insert($insert);
-                LogService::log(__METHOD__,"SUCCESS-同步插入波次成功",json_encode($insert));
-                $batches = $this->batchService->get(["code"=>$waveCodes]);
-                foreach ($batches as $batch){
-                    app("OrderService")->update(["code"=>$map[$batch->code]],["batch_id"=>$batch->id]);
-                }
-                app("BatchService")->checkBatchOrderInfo($batches);
-
-            }
-        }
-        ValueStore::query()->where("name","wave_detail_last_sync_date")->update(["value"=>$details[count($details)-1]->edittime]);
-    }
-    private function headerExe($waves)
-    {
-        if (count($waves) < 1)return;
-        //获取本地数据对比差异
-        $codes = [];
-        foreach ($waves as $wave){
-            $codes[] = $wave->waveno;
-        }
-        $map = [];
-        $batches = $this->batchService->get(["code"=>$codes]);
-        if ($batches){
-            foreach ($batches as $index=>$batch)$map[$batch->code] = $index;
-        }
-        $update = [["id","wms_status","wms_type","updated_at"]];
-        $insert = [];
-
-        foreach ($waves as $wave){
-            if (isset($map[$wave->waveno])){
-                $bat = $batches[$map[$wave->waveno]];
-                $wms_status = $this->wms_status($wave);
-                if ($bat->wms_status != $wms_status || $bat->wms_type != $wave->descr){
-                    $update[] = [
-                        "id" => $bat->id,
-                        "wms_status" => $this->wms_status($wave),
-                        "wms_type"=>$wave->descr,
-                        "updated_at"=>$wave->edittime,
-                    ];
-                }
-                continue;
-            }
-            $owner = app("OwnerService")->codeGetOwner($wave->customerid);
-            $insert[] = [
-                "code" => $wave->waveno,
-                "wms_type"=>$wave->descr,
-                "status" => '未处理',
-                "wms_status" => $this->wms_status($wave),
-                "created_at"=>$wave->addtime,
-                "updated_at"=>$wave->edittime,
-                "owner_id"=>$owner->id,
-            ];
-        }
-
-        //存在则更新
-        if (count($update)>1){
-            $bool = app(BatchUpdateService::class)->batchUpdate("batches",$update);
-            if ($bool!==false)LogService::log(__METHOD__,"SUCCESS-同步更新波次成功",json_encode($update));
-            else LogService::log(__METHOD__,"ERROR-同步更新波次失败",json_encode($update));
-        }
-
-        //不存在则录入
-        if ($insert){
-            $this->batchService->insert($insert);
-            LogService::log(__METHOD__,"SUCCESS-同步插入波次成功",json_encode($insert));
-        }
-        ValueStore::query()->where("name","wave_last_sync_date")->update(["value"=>$waves[count($waves)-1]->edittime]);
-    }
     public function test()
     {
-        $sql = "SELECT ORDERNO,WAVENO,SEQNO,EDITTIME FROM DOC_WAVE_DETAILS WHERE WAVENO = 'W210526000315'";
-        $details = DB::connection("oracle")->select(DB::raw($sql));
-        $this->detailExe($details);
-        dd();
-        $asnno = "ASN2105240178";
-        $query = DB::raw("SELECT b.ALTERNATE_SKU1,h.WAREHOUSEID,h.asnno,d.ASNLINENO,d.SKUDESCRC,h.CUSTOMERID,d.SKU,d.PACKID,d.RECEIVEDQTY_EACH,d.EXPECTEDQTY_EACH,d.LOTATT01,d.LOTATT02,d.lotatt04,".
-            "d.lotatt05,d.lotatt08,d.USERDEFINE1,d.USERDEFINE2,d.USERDEFINE3,d.USERDEFINE4,d.USERDEFINE5,d.RECEIVINGLOCATION FROM DOC_ASN_DETAILS d ".
-            " LEFT JOIN BAS_SKU b ON d.CUSTOMERID = b.CUSTOMERID AND d.SKU = b.SKU INNER JOIN DOC_ASN_HEADER h ON d.ASNNO = h.ASNNO WHERE h.ASNNO = ?");
-        $detail = DB::connection("oracle")->selectOne($query,[$asnno]);
-        //dd($detail);
-        $ser = new StoreService();
-        $result = $ser->warehousing(array(
-            "IN_Warehouse" => $detail->warehouseid ?? '',
-            "In_ASNNo_C" => $detail->asnno ?? '',
-            "In_ASNLineNo_C" => $detail->asnlineno ?? '',
-            "In_New_TraceID_C" => (string)rand(100,999),
-            "In_CustomerID" => $detail->customerid ?? '',
-            "In_SKU" => $detail->sku ?? '',
-            "In_ReceivedQty" => (string)((int)$detail->expectedqty_each - (int)$detail->receivedqty_each) ?? '',
-            "In_PackID" => $detail->packid ?? '',
-            "In_LotAtt01_C" => $detail->lotatt01 ?? '',
-            "In_LotAtt02_C" => $detail->lotatt02 ?? '',
-            "In_LotAtt04_C" => $detail->lotatt04 ?? '',
-            "In_LotAtt05_C" => $detail->lotatt05 ?? '',
-            "In_LotAtt08_C" => $detail->lotatt08 ?? '',
-            "In_UserDefine1" => $detail->userdefine1 ?? '',
-            "In_UserDefine2" => $detail->userdefine2 ?? '',
-            "In_UserDefine3" => $detail->userdefine3 ?? '',
-            "In_UserDefine4" => $detail->userdefine4 ?? '',
-            "In_UserDefine5" => $detail->userdefine5 ?? '',
-            "In_FMLocation"  => 'STAGE' . $detail->warehouseid,
-            "In_TOLocation_C" => 'STAGE' . $detail->warehouseid,//'IDE0000001',
-        ));
-       dd($result);
-        /*$order = Order::query()->where("code","SO210511005663")->first();
-        $ser = new OrderService();
-        $ser->createInstantBill($order);
-        dd();*/
-        $store = Store::query()->find(173382);dd($store->load("storeItems.commodity"));
-        $ser = new StoreService();
-        $ser->createInstantBill($store);
-        dd($store);
+        StationTask::destroy([1278,1279,1280,1282,1283]);
+        StationTaskMaterialBox::destroy([18405,18406,18407,18409,18410]);
+        dd("OK");
+        $s = Station::query()->select("id")->where("parent_id",6)->whereNotIn("code",[
+            "HAIB1-01-01","HAIB1-03-01","HAIB1-03-03"
+        ]);
+        dd($s->get());
+        $t = StationTask::query()->select("id")->where("status",'待处理')
+            ->whereIn("station_id",$s);
+        StationTask::query()->where("status",'待处理')
+            ->whereIn("station_id",$s)->update(["status"=>"完成"]);
+        StationTaskMaterialBox::query()->whereIn("station_task_id",$t)->update(["status"=>"完成"]);
+        dd("OK");
     }
     public function orderCreateBill()
     {
@@ -452,7 +175,7 @@ sql;
                 "type" => null,
                 "wms_type" => "09.[BAOSHI]\u622a\u5355\u6ce2\u6b21\u3010\u65e0\u5907\u6ce8\u3011",
                 "wms_status" => "\u90e8\u5206\u6536\u8d27",
-                "wms_created_at" => "0000-00-00 00=>00=>00",
+                "wms_created_at" => "0000-00-00 00=>00 =>00",
                 "created_at" => "2021-03-12T09=>10=>44.000000Z",
                 "updated_at" => "2021-03-12T09=>10=>44.000000Z",
                 "remark" => null,
@@ -1781,4 +1504,10 @@ TEXT;
         dd(json_decode($post->body()),$post->body(),$body);
     }
 
+
+    public function zop_test(Request $request)
+    {
+        $logistic_number = $request->logistic_number;
+        \App\Jobs\LogisticZopSync::dispatchNow($logistic_number);
+    }
 }

+ 52 - 57
app/Http/Controllers/WaybillController.php

@@ -7,7 +7,6 @@ use App\CarType;
 use App\Components\AsyncResponse;
 use App\Region;
 use App\Services\CarTypeService;
-use App\Services\common\ExportService;
 use App\Services\LogisticService;
 use App\Services\OwnerService;
 use App\Services\UnitService;
@@ -24,7 +23,6 @@ use App\WaybillPayoff;
 use App\WaybillFinancialExcepted;
 use App\WaybillFinancialSnapshot;
 use Carbon\Carbon;
-use Exception;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Database\Eloquent\Model;
@@ -32,7 +30,6 @@ use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
-use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Facades\Validator;
 use Intervention\Image\Facades\Image;
@@ -493,51 +490,47 @@ class WaybillController extends Controller
     }
 
     public function upload(Request $request){
-        if(!Gate::allows('运输管理-运单-图片上传')){ return '没有权限';  }
-        $file=$request->file('file');
-        $waybill_number=$request->input('waybill_number');
-        $waybill=Waybill::query()->where('waybill_number',$waybill_number)->first();
-        if (!$waybill){
-            return ['success'=>false,'error'=>"未找到该运单!"];
-        }
-        if ($waybill->upload_file_url){
-            return ['success'=>false,'error'=>"该运单已存在照片!"];
-        }
-        if (!$file){
-            return ['success'=>false,'error'=>"照片不得为空!"];
-        }
-        if (!$file->isValid()){
-            return ['success'=>false,'error'=>"找不到照片!"];
-        }
-        $tmpFile = $file->getRealPath();
-        if (! is_uploaded_file($tmpFile)) {
-            return ['success'=>false,'error'=>"文件错误!"];
-        }
-        $fileExtension=$file->getClientOriginalExtension();
-        // 5.存储, 生成一个随机文件名
-        $fileName = date('ymd').'-'.Uuid::uuid1();//thumbnail common bulky
-        $thumbnailName=storage_path('app/public/files/'.$fileName.'-thumbnail.'.$fileExtension);
-        $commonName=storage_path('app/public/files/'.$fileName.'-common.'.$fileExtension);
-        $bulkyName=storage_path('app/public/files/'.$fileName.'-bulky.'.$fileExtension);
-        $result=move_uploaded_file ($tmpFile ,$bulkyName);
-        if ($result){
-            $img=Image::make($bulkyName);
-            if ($img->height() > $img->width())
-                $img->heighten(250)->save($commonName);
-            else $img->widen(250)->save($commonName);
-            $img->heighten(28)->save($thumbnailName);
-            $uploadFile=new UploadFile([
-                "table_name"=>"waybills",
-                "table_id"=>$waybill->id,
-                "url"=>'/files/'.$fileName,
-                "type"=>$fileExtension,
-            ]);
-            if ($uploadFile->save())
-                app('LogService')->log(__METHOD__,'图片上传',json_encode($request),Auth::user()['id']);
-            $uploadFile->url=asset('/storage'.$uploadFile->url);
-            return ['success'=>true,'data'=>$uploadFile];
+        $this->gate("运输管理-运单-图片上传");
+        $files=$request->file("files");
+        if (!$files)$this->error("未传递照片");
+        $id=$request->input('id');
+        $waybill=Waybill::query()->find($id);
+        if (!$waybill)$this->error("未找到该运单!");
+        $res = [];
+        foreach ($files as $file){
+            if (!$file->isValid()){
+                return ['success'=>false,'error'=>"找不到照片!"];
+            }
+            $tmpFile = $file->getRealPath();
+            if (! is_uploaded_file($tmpFile)) {
+                return ['success'=>false,'error'=>"文件错误!"];
+            }
+            $fileExtension=$file->getClientOriginalExtension();
+            // 5.存储, 生成一个随机文件名
+            $fileName = date('ymd').'-'.Uuid::uuid1();//thumbnail common bulky
+            $thumbnailName=storage_path('app/public/files/'.$fileName.'-thumbnail.'.$fileExtension);
+            $commonName=storage_path('app/public/files/'.$fileName.'-common.'.$fileExtension);
+            $bulkyName=storage_path('app/public/files/'.$fileName.'-bulky.'.$fileExtension);
+            $result=move_uploaded_file ($tmpFile ,$bulkyName);
+            if ($result){
+                $img=Image::make($bulkyName);
+                if ($img->height() > $img->width())
+                    $img->heighten(250)->save($commonName);
+                else $img->widen(250)->save($commonName);
+                $img->heighten(28)->save($thumbnailName);
+                /** @var UploadFile|\stdClass $uploadFile */
+                $uploadFile=new UploadFile([
+                    "table_name"=>"waybills",
+                    "table_id"=>$waybill->id,
+                    "url"=>'/files/'.$fileName,
+                    "type"=>$fileExtension,
+                ]);
+                if ($uploadFile->save())
+                    app('LogService')->log(__CLASS__,'运输图片上传',json_encode($request),Auth::user()['id']);
+                $res[] = $uploadFile;
+            }else $this->error("图片存储失败,检查服务器状态");
         }
-        return ['success'=>false,'error'=>"图片保存失败!"];
+        $this->success($res);
     }
 
     //批量上传图片
@@ -566,9 +559,9 @@ class WaybillController extends Controller
             $number[] = $num;
             $mapping[$num] = $index;
         }
-        $waybills = Waybill::query()->select("id","source_bill")->doesntHave("uploadFile")->whereIn('source_bill',$number)->get();
+        $waybills = Waybill::query()->select("id","source_bill")->whereIn('source_bill',$number)->get();
         foreach (array_diff($number,array_column($waybills->toArray(),"source_bill")) as $diff){
-            $errors[] = "“".$diff."”不存在运单或已存在照片";
+            $errors[] = "“".$diff."”不存在运单";
             unset($images[$mapping[$diff]]);
         }
         $insert = [];
@@ -598,16 +591,17 @@ class WaybillController extends Controller
             ];
         }
         if ($insert)UploadFile::query()->insert($insert);
-        $waybills->load("uploadFile");
+        $waybills->load("uploadFiles");
         $this->success(["errors"=>$errors,"data"=>$waybills]);
     }
 
     //删除照片
     public function deleteImg(Request $request){
-        if(!Gate::allows('运输管理-运单-图片删除')){ return '没有权限';  }
-        $ids=$request->input('ids');
-        $uploadFiles=UploadFile::where('table_name','waybills')->whereIn('table_id',$ids)->get();
-        foreach ($uploadFiles as $uploadFile){
+        $this->gate("运输管理-运单-图片删除");
+        $query=UploadFile::query()->where('table_name','waybills');
+        if ($request->input("url"))$query = $query->where('table_id',$request->input("id"))->where("url",$request->input("url"));
+        else $query = $query->whereIn('table_id',$request->input("id"));
+        foreach ($query->get() as $uploadFile){
             $bulky=storage_path('app/public/'.$uploadFile->url.'-bulky.'.$uploadFile->type);
             $common=storage_path('app/public/'.$uploadFile->url.'-common.'.$uploadFile->type);
             $thumbnail=storage_path('app/public/'.$uploadFile->url.'-thumbnail.'.$uploadFile->type);
@@ -615,9 +609,9 @@ class WaybillController extends Controller
                 unlink($bulky);unlink($common);unlink($thumbnail);
             }
         }
-        UploadFile::where('table_name','waybills')->whereIn('table_id',$ids)->delete();
+        $query->delete();
         app('LogService')->log(__METHOD__,'图片删除',json_encode($request),Auth::user()['id']);
-        return ['success'=>true];
+        $this->success();
     }
 
     public function export(){
@@ -629,7 +623,7 @@ class WaybillController extends Controller
         /** @var Collection $waybills */
         $row = [
             "运单类型", "货主", "上游单号", "wms订单号", "运单号", "运输收费",
-            "其他收费", "其他收费备注", "始发地", "目的地", "承运商", "承运商单号",
+            "其他收费", "其他收费备注", "始发地", "目的地","下单备注", "承运商", "承运商单号",
             "仓库计抛", "承运商计抛", "仓库计重", "承运商计重", "车型", "车辆信息",
             "计件", "里程数", "运费(元)", "提货费(元)", "其他费用(元)", "发货时间",
             "调度备注", "创建时间"
@@ -647,6 +641,7 @@ class WaybillController extends Controller
                 $waybill->other_charge_remark,
                 $waybill->origination,
                 $waybill->order->address ?? $waybill->destination,
+                $waybill->ordering_remark,
                 $waybill->logistic->name ?? "",
                 $waybill->carrier_bill,
                 $waybill->warehouse_weight,

+ 6 - 8
app/Http/Controllers/WeighController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\MeasuringMachine;
 use App\OrderPackage;
 use App\PaperBox;
 use App\Services\OrderPackageService;
@@ -9,11 +10,9 @@ use App\Services\OwnerService;
 use App\Services\PackageService;
 use App\Services\PackageStatisticsService;
 use Carbon\Carbon;
-use Exception;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Gate;
-use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Validator;
 use Oursdreams\Export\Export;
 
@@ -27,7 +26,8 @@ class WeighController extends Controller
         /** @var PackageService $application */
         $application = app('PackageService');
         $packages = $application->paginate($request);
-        return view('package.weigh.index',['packages'=>$packages,'owners'=>$ownerService->getIntersectPermitting(),'paginateParams'=>$paginateParams]);
+        $measuringMachines = MeasuringMachine::query()->get();
+        return view('package.weigh.index',['packages'=>$packages,"measuringMachines"=>$measuringMachines,'owners'=>$ownerService->getIntersectPermitting(),'paginateParams'=>$paginateParams]);
     }
 
     public function create()
@@ -145,12 +145,10 @@ class WeighController extends Controller
 
     public function statistics(Request $request){
         $packages = app('PackageStatisticsService')->get($request->input());
-        $owners=app('OwnerService')->getIntersectPermitting();
+        $owners=app('OwnerService')->get([],null,false);
         $logistics=app('LogisticService')->getSelection();
         $ownerTemp = [];
-        foreach ($owners as $owner){
-            $ownerTemp[$owner->id] = $owner->name;
-        }
+        foreach ($owners as $owner)$ownerTemp[$owner->id] = $owner->name;
         $ps = [];
         $logisticsTemp = [];
         foreach ($packages as $package){
@@ -163,7 +161,7 @@ class WeighController extends Controller
                     $package->logistic_id => $package->count,
                     "sum" => (int)$package->count,
                     "owner_id" => $package->owner_id,
-                    "owner_name" => $ownerTemp[$package->owner_id]
+                    "owner_name" => $ownerTemp[$package->owner_id] ?? '未知',
                 ];
             }
         }

+ 41 - 0
app/Http/Requests/OwnerSundryFeeDetailRequest.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Http\Requests;
+
+class OwnerSundryFeeDetailRequest extends Request
+{
+    public function rules()
+    {
+        switch($this->method())
+        {
+            // CREATE
+            case 'POST':
+            {
+                return [
+                    // CREATE ROLES
+                ];
+            }
+            // UPDATE
+            case 'PUT':
+            case 'PATCH':
+            {
+                return [
+                    // UPDATE ROLES
+                ];
+            }
+            case 'GET':
+            case 'DELETE':
+            default:
+            {
+                return [];
+            }
+        }
+    }
+
+    public function messages()
+    {
+        return [
+            // Validation messages
+        ];
+    }
+}

+ 14 - 0
app/Http/Requests/Request.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class Request extends FormRequest
+{
+    public function authorize()
+    {
+    	// Using policy for Authorization
+        return true;
+    }
+}

+ 4 - 1
app/Jobs/LogisticSFSync.php

@@ -12,6 +12,10 @@ use Illuminate\Queue\SerializesModels;
 
 class LogisticSFSync implements ShouldQueue
 {
+    public $tries = 2;
+
+    public $timeout = 10;
+
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
     public $logistic_number;
@@ -40,7 +44,6 @@ class LogisticSFSync implements ShouldQueue
      */
     public function handle()
     {
-        ini_set('max_execution_time', 60);
         LogService::log(LogisticSFSync::class, "{$this->logistic_number}-JOB-SF", '');
         $this->logisticSFService = app('LogisticSFService');
         $formedData = $this->logisticSFService->get([$this->logistic_number]);

+ 4 - 1
app/Jobs/LogisticYDSync.php

@@ -13,6 +13,10 @@ use Illuminate\Queue\SerializesModels;
 
 class LogisticYDSync implements ShouldQueue
 {
+    public $tries = 2;
+
+    public $timeout = 10;
+
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
     /**
      * @var $logisticYDService LogisticYDService
@@ -43,7 +47,6 @@ class LogisticYDSync implements ShouldQueue
      */
     public function handle()
     {
-        ini_set('max_execution_time', 60);
         LogService::log(LogisticYDSync::class, "{$this->logistic_number}-JOB-YD", '');
         $this->logisticYDService = app('LogisticYDService');
         //先订阅订单

+ 5 - 1
app/Jobs/LogisticYTOSync.php

@@ -14,7 +14,12 @@ use Illuminate\Queue\SerializesModels;
 
 class LogisticYTOSync implements ShouldQueue
 {
+    public $tries = 2;
+
+    public $timeout = 10;
+
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
     /**
      * @var $logisticYTOService LogisticYTOService
      * @var $orderPackageReceivedSyncService OrderPackageReceivedSyncService
@@ -43,7 +48,6 @@ class LogisticYTOSync implements ShouldQueue
      */
     public function handle()
     {
-        ini_set('max_execution_time', 60);
         LogService::log(LogisticYTOSync::class, "{$this->logistic_number}-JOB-YTO", '');
         $this->logisticYTOService = app('LogisticYTOService');
         $nativeResponse = $this->logisticYTOService->query($this->logistic_number);

+ 23 - 150
app/Jobs/LogisticZopSync.php

@@ -2,10 +2,8 @@
 
 namespace App\Jobs;
 
-use App\library\zop\ZopClient;
-use App\library\zop\ZopProperties;
-use App\library\zop\ZopRequest;
-use App\OrderPackage;
+
+use App\Services\LogisticZopService;
 use App\Services\LogService;
 use App\Services\OrderPackageReceivedSyncService;
 use Illuminate\Bus\Queueable;
@@ -13,13 +11,26 @@ use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Queue\InteractsWithQueue;
 use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Carbon;
 
 class LogisticZopSync implements ShouldQueue
 {
+    public $tries = 2;
+    public $timeout = 10;
+
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
+    /**
+     * @var string $logistic_number
+     */
     protected $logistic_number;
+//    /**
+//     * @var LogisticZopService $logistic_zop_service
+//     */
+//    protected $logistic_zop_service;
+    /**
+     * @var  OrderPackageReceivedSyncService $order_package_received_sync_service
+     */
+    protected $order_package_received_sync_service;
 
     /**
      * Create a new job instance.
@@ -29,6 +40,8 @@ class LogisticZopSync implements ShouldQueue
     public function __construct($logistic_number)
     {
         $this->logistic_number = $logistic_number;
+//        $this->logistic_zop_service = app('LogisticZopService');
+        $this->order_package_received_sync_service = app('OrderPackageReceivedSyncService');
     }
 
     /**
@@ -39,150 +52,10 @@ class LogisticZopSync implements ShouldQueue
     public function handle()
     {
         ini_set('max_execution_time', 60);
-        LogService::log(LogisticZopSync::class, "{$this->logistic_number}-JOB-ZOP", '');
-        $zopResult = [];
-        $response = $this->sentRequestToZT();
-        dd($response);
-        if(is_null($response)) return;
-        if ($response->status) {
-            $zopResult[] = [
-                'routes' => $response->result,
-                'logisticNum' => $this->logistic_number,
-            ];
-        }
-        $result = $this->transformRoutes($zopResult);
-        /* @var $orderPackageReceivedSyncService OrderPackageReceivedSyncService */
-        $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
-        !empty($result) && $orderPackageReceivedSyncService->update($result);
-    }
-
-    /**
-     * 转换快递路由信息
-     * @param array $routs 快递路由
-     * @return array
-     */
-    public function transformRoutes(array $routs): array
-    {
-        $result = [];
-        foreach ($routs as $route) {
-            $result = $this->transformRouteItem($route, $result);
-        }
-        return $result;
-    }
-
-    /**
-     * @param $route
-     * @param array $result
-     * @return array
-     */
-    private function transformRouteItem($route, array $result): array
-    {
-        $resultItem = [];
-        $resultItem['logistic_number'] = $route['logisticNum'];
-        $itemRoutes = $route['routes'];
-        $lastRoute = null;
-        if (!empty($itemRoutes)) {
-            $lastRoute = $itemRoutes[count($itemRoutes) - 1];
-            $resultItem = $this->getNormalStatusAndReceivedAt($lastRoute, $resultItem);
-            $resultItem['transfer_status'] = $this->getTransferStatus($itemRoutes);
-        } else {
-            $resultItem['status'] = null;
-            $resultItem['transfer_status'] = [];
-        }
-        if (!array_key_exists('status', $resultItem)) {
-            $resultItem['status'] = null;
-            $resultItem['transfer_status'] = [];
-        }
-        try {
-            $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
-            $exceptionData = $orderPackageReceivedSyncService->setExceptionType($resultItem, $lastRoute ? $lastRoute->scanDate / 1000 : null);
-            $resultItem['exception_type'] = $exceptionData['exception_type'];
-            $resultItem['exception'] = $exceptionData['exception'];
-        } catch (\Exception $e) {
-        }
-        if ($resultItem['status'] == null) {
-            unset($resultItem['status']);
-            unset($resultItem['transfer_status']);
-        }
-        //如果没有发现额外的异常,且查询到物流轨迹,将异常置为无
-        if (!array_key_exists('exception', $resultItem)
-            && !array_key_exists('exception_type', $resultItem)
-            && array_key_exists('transfer_status', $resultItem)
-        ) {
-            $resultItem['exception_type'] = '无';
-            $resultItem['exception'] = '否';
-        }
-        $resultItem['routes_length'] = array_key_exists('transfer_status', $resultItem) ? count($resultItem['transfer_status']) : 0;
-        $result[] = $resultItem;
-        return $result;
-    }
-    /**
-     * 正常的状态与签收时间
-     * @param $lastRoute
-     * @param array $resultItem
-     * @return array
-     */
-    private function getNormalStatusAndReceivedAt($lastRoute, array $resultItem): array
-    {
-        switch ($lastRoute->scanType) {
-            case '收件':
-                $resultItem['status'] = '已揽收';
-                break;
-            case '到件':
-            case '发件':
-                $resultItem['status'] = '在途';
-                break;
-            case 'ARRIVAL':
-            case '派件':
-                $resultItem['status'] = '派送中';
-                break;
-            case 'SIGNED':
-            case '签收':
-                $resultItem['status'] = '已收件';
-                $resultItem['received_at'] = Carbon::parse($lastRoute->scanDate / 1000)->toDateTimeString();
-                break;
-            default:
-                $resultItem['status'] = '无';
-                break;
-        }
-        return $resultItem;
-    }
-
-    /**
-     * @param $itemRoutes
-     * @return array
-     */
-    private function getTransferStatus($itemRoutes): array
-    {
-        $transfer_status = [];
-        foreach ($itemRoutes as $item) {
-            $data = [];
-            $data['accept_time'] = Carbon::parse($item->scanDate / 1000)->addHours(8)->toDateTimeString();
-            $scanSite = $item->scanSite;
-            $data['accept_address'] = $scanSite->prov . '-' . $scanSite->name;
-            $data['remark'] = $item->desc;
-            $transfer_status[] = $data;
-        }
-        return $transfer_status;
-    }
-
-    /**
-     * 发送请求到中通
-     * @return mixed
-     */
-    private function sentRequestToZT()
-    {
-        $url = config('api_logistic.ZTO.url');
-        $xAppKey = config('api_logistic.ZTO.x-appKey');
-        $appSecret = config('api_logistic.ZTO.appSecret');
-        $properties = new ZopProperties($xAppKey, $appSecret);
-        $client = new ZopClient($properties);
-        $request = new ZopRequest();
-
-        $request->setUrl($url);
-        $request->setBody(json_encode([
-            'billCode' => $this->logistic_number,
-        ],JSON_UNESCAPED_UNICODE));
-        return json_decode($client->execute($request));
+        LogService::log(LogisticZopSync::class, "JOB-ZOP", $this->logistic_number);
+        $logistic_zop_service = new LogisticZopService();
+        $nativeResponse = $logistic_zop_service->query($this->logistic_number);
+        $formatted_data = $logistic_zop_service->format($nativeResponse);
+        $this->order_package_received_sync_service->update([$formatted_data]);
     }
 }

+ 21 - 0
app/Observers/OwnerSundryFeeDetailObserver.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Observers;
+
+use App\OwnerSundryFeeDetail;
+
+// creating, created, updating, updated, saving,
+// saved,  deleting, deleted, restoring, restored
+
+class OwnerSundryFeeDetailObserver
+{
+    public function creating(OwnerSundryFeeDetail $owner_sundry_fee_detail)
+    {
+        //
+    }
+
+    public function updating(OwnerSundryFeeDetail $owner_sundry_fee_detail)
+    {
+        //
+    }
+}

+ 22 - 0
app/OrderPackageReceivedSyncRecord.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class OrderPackageReceivedSyncRecord extends Model
+{
+    use ModelLogChanging;
+
+    //
+    public $fillable = ['logistic_name', 'recorded_at', 'succeed_count', 'failed_count'];
+
+    public $timestamps = false;
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+}

+ 6 - 0
app/Owner.php

@@ -4,6 +4,7 @@ namespace App;
 
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Support\Facades\Auth;
 
 /**
@@ -209,4 +210,9 @@ class Owner extends Model
             ->select(DB::raw(1))->whereNotNull("operation")
             ->where("operation","!=","");
     }
+
+    public function ownerSundryFeeDetail(): HasMany
+    {
+        return $this->hasMany(OwnerSundryFeeDetail::class);
+    }
 }

+ 70 - 0
app/OwnerSundryFeeDetail.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelLogChanging;
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class OwnerSundryFeeDetail extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+    use SoftDeletes;
+
+    protected $fillable = ['type', 'fee_explain', 'remark', 'fee', 'changable','owner_id'];
+
+
+    static public $enums = [
+        'type' => [
+            '' => 0,
+            '材料' => 1,
+            '垫付' => 2,
+            '人工' => 3,
+            '其他' => 4,
+        ],
+        'changable' => [
+            '' => 0,
+            '未冻结' => 1,
+            '已冻结' => 2,
+        ],
+    ];
+
+    function __construct(array $attributes = [])
+    {
+        foreach (self::$enums as &$enum) {
+            $enum = $enum + array_flip($enum);
+        }
+        parent::__construct($attributes);
+    }
+
+    public function getTypeAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['type'][$value];
+    }
+
+    public function setTypeAttribute($value)
+    {
+        if (!$value) return 0;
+        $this->attributes['type'] = self::$enums['type'][$value];
+    }
+
+    public function getRouteKey()
+    {
+        return 'id';
+    }
+
+    public function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+}

+ 20 - 0
app/Policies/OwnerSundryFeeDetailPolicy.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Policies;
+
+use App\User;
+use App\OwnerSundryFeeDetail;
+
+class OwnerSundryFeeDetailPolicy extends Policy
+{
+    public function update(User $user, OwnerSundryFeeDetail $owner_sundry_fee_detail)
+    {
+        // return $owner_sundry_fee_detail->user_id == $user->id;
+        return true;
+    }
+
+    public function destroy(User $user, OwnerSundryFeeDetail $owner_sundry_fee_detail)
+    {
+        return true;
+    }
+}

+ 22 - 0
app/Policies/Policy.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Policies;
+
+use Illuminate\Auth\Access\HandlesAuthorization;
+
+class Policy
+{
+    use HandlesAuthorization;
+
+    public function __construct()
+    {
+        //
+    }
+
+    public function before($user, $ability)
+	{
+	    // if ($user->isSuperAdmin()) {
+	    // 		return true;
+	    // }
+	}
+}

+ 156 - 85
app/Providers/AppServiceProvider.php

@@ -3,6 +3,10 @@
 namespace App\Providers;
 
 use App\Http\Controllers\Controller;
+use App\Jobs\LogisticSFSync;
+use App\Jobs\LogisticYDSync;
+use App\Jobs\LogisticYTOSync;
+use App\Jobs\LogisticZopSync;
 use App\Services\AuthorityService;
 use App\Services\BatchService;
 use App\Services\CacheService;
@@ -26,6 +30,7 @@ use App\Services\InventoryCompareService;
 use App\Services\LaborReportsCountingRecordService;
 use App\Services\LogisticSFService;
 use App\Services\LogisticYTOService;
+use App\Services\LogisticZopService;
 use App\Services\LogService;
 use App\Services\MaterialBoxService;
 use App\Services\OracleBasCustomerService;
@@ -43,6 +48,7 @@ use App\Services\OracleActAllocationDetailService;
 use App\Services\OrderIssueProcessLogService;
 use App\Services\OrderIssueRejectedBillService;
 use App\Services\OrderIssueService;
+use App\Services\OrderPackageReceivedSyncRecordService;
 use App\Services\OrderPackageReceivedSyncService;
 use App\Services\OrderPackageService;
 use App\Services\OrderService;
@@ -107,6 +113,8 @@ use App\Services\StationCacheShelfGridService;
 use App\Services\PrintPartService;
 use App\Services\PrintTemplateService;
 use Illuminate\Queue\Events\JobFailed;
+use Illuminate\Queue\Events\JobProcessed;
+use Illuminate\Queue\Events\JobProcessing;
 use Illuminate\Support\Facades\Queue;
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\Facades\View;
@@ -118,6 +126,7 @@ use App\Services\OrderPackageCommoditySerialNumberService;
 use App\Services\OrderPackageExceptionTypeCountingRecordService;
 use App\Services\LogisticYDService;
 use App\Services\ForeignZhenCangService;
+use App\Services\StorageService;
 
 class AppServiceProvider extends ServiceProvider
 {
@@ -141,7 +150,13 @@ class AppServiceProvider extends ServiceProvider
         //
         Schema::defaultStringLength(191);
         Queue::failing(function (JobFailed $event) {
-            (new Controller())->log(__METHOD__,'EventError_',json_encode($event));
+            (new Controller())->log(__METHOD__, 'EventError_', json_encode($event));
+            $payload = $event->job->payload();
+            $displayName = $payload['displayName'];
+            //快递信息同步失败计数
+            if ($this->isLogisticSyncJob($displayName)) {
+                $this->logisticSyncRecord($displayName, 'failed_count');
+            }
         });
         //扩展身份证验证规则
         Validator::extend('identity_cards', function($attribute, $value, $parameters) {
@@ -158,6 +173,19 @@ class AppServiceProvider extends ServiceProvider
         \Illuminate\Database\Eloquent\Builder::macro('sql', function(){
             return ($this->getQuery()->sql());
         });
+
+        Queue::before(function (JobProcessing $event) {
+
+        });
+        //任务成功后的回调
+        Queue::after(function (JobProcessed $event) {
+            //快递信息同步成功计数
+            $payload = $event->job->payload();
+            $displayName = $payload['displayName'];
+            if ($this->isLogisticSyncJob($displayName)) {
+                $this->logisticSyncRecord($displayName, 'succeed_count');
+            }
+        });
     }
 
     private function loadingService(){
@@ -186,93 +214,136 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('FeatureService',FeatureService::class);
         app()->singleton('ForeignHaiRoboticsService',ForeignHaiRoboticsService::class);
         app()->singleton('ForeignZhenCangService',ForeignZhenCangService::class);
-        app()->singleton('InventoryAccountMissionService',InventoryAccountMissionService::class);
-        app()->singleton('InventoryCompareService',InventoryCompareService::class);
-        app()->singleton('InventoryDailyLogService',InventoryDailyLogService::class);
-        app()->singleton('LaborReportsCountingRecordService',LaborReportsCountingRecordService::class);
-        app()->singleton('LogService',LogService::class);
-        app()->singleton('LogisticSFService',LogisticSFService::class);
-        app()->singleton('LogisticService',LogisticService::class);
-        app()->singleton('LogisticYDService',LogisticYDService::class);
-        app()->singleton('LogisticYTOService',LogisticYTOService::class);
-        app()->singleton('MaterialBoxService',MaterialBoxService::class);
-        app()->singleton('OracleActAllocationDetailService',OracleActAllocationDetailService::class);
-        app()->singleton('OracleBasCustomerService',OracleBasCustomerService::class);
-        app()->singleton('OracleBasSkuService',OracleBasSkuService::class);
-        app()->singleton('OracleDocAsnDetailService',OracleDocAsnDetailService::class);
-        app()->singleton('OracleDocOrderHeaderService',OracleDOCOrderHeaderService::class);
-        app()->singleton('OracleDocWaveDetailService',OracleDocWaveDetailService::class);
-        app()->singleton('OrderCommodityAssignService',OrderCommodityAssignService::class);
-        app()->singleton('OrderCommodityService',OrderCommodityService::class);
-        app()->singleton('OrderFreezeService',OrderFreezeService::class);
-        app()->singleton('OrderIssuePerformanceService',OrderIssuePerformanceService::class);
-        app()->singleton('OrderIssueProcessLogService',OrderIssueProcessLogService::class);
-        app()->singleton('OrderIssueRejectedBillService',OrderIssueRejectedBillService::class);
-        app()->singleton('OrderIssueService',OrderIssueService::class);
-        app()->singleton('OrderIssueWorkLoadService',OrderIssueWorkLoadService::class);
-        app()->singleton('OrderPackageCommoditiesService',OrderPackageCommoditiesService::class);
-        app()->singleton('OrderPackageCommoditySerialNumberService',OrderPackageCommoditySerialNumberService::class);
-        app()->singleton('OrderPackageExceptionTypeCountingRecordService',OrderPackageExceptionTypeCountingRecordService::class);
-        app()->singleton('OrderPackageReceivedSyncService',OrderPackageReceivedSyncService::class);
-        app()->singleton('OrderPackageService',OrderPackageService::class);
-        app()->singleton('OrderService',OrderService::class);
-        app()->singleton('OrderTrackingService',OrderTrackingService::class);
-        app()->singleton('OwnerAreaReportService',OwnerAreaReportService::class);
-        app()->singleton('OwnerBillReportService',OwnerBillReportService::class);
-        app()->singleton('OwnerFeeDetailService',OwnerFeeDetailService::class);
-        app()->singleton('OwnerMaterialService',OwnerMaterialService::class);
-        app()->singleton('OwnerMaterialService',OwnerMaterialService::class);
-        app()->singleton('OwnerPriceDirectLogisticService',OwnerPriceDirectLogisticService::class);
-        app()->singleton('OwnerPriceExpressService',OwnerPriceExpressService::class);
-        app()->singleton('OwnerPriceLogisticService',OwnerPriceLogisticService::class);
-        app()->singleton('OwnerPriceOperationItemService',OwnerPriceOperationItemService::class);
-        app()->singleton('OwnerPriceOperationService',OwnerPriceOperationService::class);
-        app()->singleton('OwnerReportService',OwnerReportService::class);
-        app()->singleton('OwnerService',OwnerService::class);
-        app()->singleton('OwnerStoragePriceModelService',OwnerStoragePriceModelService::class);
-        app()->singleton('PackageService',PackageService::class);
-        app()->singleton('PackageStatisticsService',PackageStatisticsService::class);
+        app()->singleton('LogisticZopService', LogisticZopService::class);
+        app()->singleton('InventoryAccountMissionService', InventoryAccountMissionService::class);
+        app()->singleton('InventoryCompareService', InventoryCompareService::class);
+        app()->singleton('InventoryDailyLogService', InventoryDailyLogService::class);
+        app()->singleton('LaborReportsCountingRecordService', LaborReportsCountingRecordService::class);
+        app()->singleton('OrderPackageReceivedSyncRecordService', OrderPackageReceivedSyncRecordService::class);
+        app()->singleton('LogService', LogService::class);
+        app()->singleton('LogisticSFService', LogisticSFService::class);
+        app()->singleton('LogisticService', LogisticService::class);
+        app()->singleton('LogisticYDService', LogisticYDService::class);
+        app()->singleton('LogisticYTOService', LogisticYTOService::class);
+        app()->singleton('MaterialBoxService', MaterialBoxService::class);
+        app()->singleton('OracleActAllocationDetailService', OracleActAllocationDetailService::class);
+        app()->singleton('OracleBasCustomerService', OracleBasCustomerService::class);
+        app()->singleton('OracleBasSkuService', OracleBasSkuService::class);
+        app()->singleton('OracleDocAsnDetailService', OracleDocAsnDetailService::class);
+        app()->singleton('OracleDocOrderHeaderService', OracleDOCOrderHeaderService::class);
+        app()->singleton('OracleDocWaveDetailService', OracleDocWaveDetailService::class);
+        app()->singleton('OrderCommodityAssignService', OrderCommodityAssignService::class);
+        app()->singleton('OrderCommodityService', OrderCommodityService::class);
+        app()->singleton('OrderFreezeService', OrderFreezeService::class);
+        app()->singleton('OrderIssuePerformanceService', OrderIssuePerformanceService::class);
+        app()->singleton('OrderIssueProcessLogService', OrderIssueProcessLogService::class);
+        app()->singleton('OrderIssueRejectedBillService', OrderIssueRejectedBillService::class);
+        app()->singleton('OrderIssueService', OrderIssueService::class);
+        app()->singleton('OrderIssueWorkLoadService', OrderIssueWorkLoadService::class);
+        app()->singleton('OrderPackageCommoditiesService', OrderPackageCommoditiesService::class);
+        app()->singleton('OrderPackageCommoditySerialNumberService', OrderPackageCommoditySerialNumberService::class);
+        app()->singleton('OrderPackageExceptionTypeCountingRecordService', OrderPackageExceptionTypeCountingRecordService::class);
+        app()->singleton('OrderPackageReceivedSyncService', OrderPackageReceivedSyncService::class);
+        app()->singleton('OrderPackageService', OrderPackageService::class);
+        app()->singleton('OrderService', OrderService::class);
+        app()->singleton('OrderTrackingService', OrderTrackingService::class);
+        app()->singleton('OwnerAreaReportService', OwnerAreaReportService::class);
+        app()->singleton('OwnerBillReportService', OwnerBillReportService::class);
+        app()->singleton('OwnerFeeDetailService', OwnerFeeDetailService::class);
+        app()->singleton('OwnerMaterialService', OwnerMaterialService::class);
+        app()->singleton('OwnerMaterialService', OwnerMaterialService::class);
+        app()->singleton('OwnerPriceDirectLogisticService', OwnerPriceDirectLogisticService::class);
+        app()->singleton('OwnerPriceExpressService', OwnerPriceExpressService::class);
+        app()->singleton('OwnerPriceLogisticService', OwnerPriceLogisticService::class);
+        app()->singleton('OwnerPriceOperationItemService', OwnerPriceOperationItemService::class);
+        app()->singleton('OwnerPriceOperationService', OwnerPriceOperationService::class);
+        app()->singleton('OwnerReportService', OwnerReportService::class);
+        app()->singleton('OwnerService', OwnerService::class);
+        app()->singleton('OwnerStoragePriceModelService', OwnerStoragePriceModelService::class);
+        app()->singleton('PackageService', PackageService::class);
+        app()->singleton('PackageStatisticsService', PackageStatisticsService::class);
         app()->singleton('PrintPartService',PrintPartService::class);
         app()->singleton('PrintTemplateService',PrintTemplateService::class);
-        app()->singleton('ProcessMethodService',ProcessMethodService::class);
-        app()->singleton('ProcessService',ProcessService::class);
-        app()->singleton('ProcessStatisticService',ProcessStatisticService::class);
-        app()->singleton('ProcessesContentService',ProcessesContentService::class);
-        app()->singleton('ProcurementService',ProcurementService::class);
-        app()->singleton('ProcurementTotalBillService',ProcurementTotalBillService::class);
-        app()->singleton('ProcurementWeiXinSendMessageService',ProcurementWeiXinSendMessageService::class);
-        app()->singleton('ProvinceService',ProvinceService::class);
-        app()->singleton('RealtimePendingOrdersService',RealtimePendingOrdersService::class);
-        app()->singleton('RegionService',RegionService::class);
-        app()->singleton('RejectedBillItemService',RejectedBillItemService::class);
-        app()->singleton('RejectedBillService',RejectedBillService::class);
-        app()->singleton('RejectedService',RejectedService::class);
-        app()->singleton('ShopService',ShopService::class);
-        app()->singleton('StationCacheShelfGridService',StationCacheShelfGridService::class);
-        app()->singleton('StationRuleBatchService',StationRuleBatchService::class);
-        app()->singleton('StationService',StationService::class);
-        app()->singleton('StationTaskBatchService',StationTaskBatchService::class);
-        app()->singleton('StationTaskBatchTypeService',StationTaskBatchTypeService::class);
-        app()->singleton('StationTaskChildService',StationTaskChildService::class);
-        app()->singleton('StationTaskCommodityService',StationTaskCommodityService::class);
-        app()->singleton('StationTaskMaterialBoxService',StationTaskMaterialBoxService::class);
-        app()->singleton('StationTaskService',StationTaskService::class);
-        app()->singleton('StationTaskTypeService',StationTaskTypeService::class);
-        app()->singleton('StationTypeBinMonitorService',StationTypeBinMonitorService::class);
-        app()->singleton('StationTypeService',StationTypeService::class);
-        app()->singleton('StoreCheckingReceiveItemService',StoreCheckingReceiveItemService::class);
-        app()->singleton('StoreCheckingReceiveService',StoreCheckingReceiveService::class);
-        app()->singleton('StoreItemService',StoreItemService::class);
-        app()->singleton('StoreService',StoreService::class);
-        app()->singleton('SupplierService',SupplierService::class);
-        app()->singleton('UnitService',UnitService::class);
-        app()->singleton('UserOwnerGroupService',UserOwnerGroupService::class);
-        app()->singleton('UserService',UserService::class);
-        app()->singleton('UserWorkgroupService',UserWorkgroupService::class);
-        app()->singleton('WarehouseService',WarehouseService::class);
-        app()->singleton('WaybillFinancialService',WaybillFinancialService::class);
-        app()->singleton('WeighExceptedService',WeighExceptedService::class);
+        app()->singleton('ProcessMethodService', ProcessMethodService::class);
+        app()->singleton('ProcessService', ProcessService::class);
+        app()->singleton('ProcessStatisticService', ProcessStatisticService::class);
+        app()->singleton('ProcessesContentService', ProcessesContentService::class);
+        app()->singleton('ProcurementService', ProcurementService::class);
+        app()->singleton('ProcurementTotalBillService', ProcurementTotalBillService::class);
+        app()->singleton('ProcurementWeiXinSendMessageService', ProcurementWeiXinSendMessageService::class);
+        app()->singleton('ProvinceService', ProvinceService::class);
+        app()->singleton('RealtimePendingOrdersService', RealtimePendingOrdersService::class);
+        app()->singleton('RegionService', RegionService::class);
+        app()->singleton('RejectedBillItemService', RejectedBillItemService::class);
+        app()->singleton('RejectedBillService', RejectedBillService::class);
+        app()->singleton('RejectedService', RejectedService::class);
+        app()->singleton('ShopService', ShopService::class);
+        app()->singleton('StationCacheShelfGridService', StationCacheShelfGridService::class);
+        app()->singleton('StationRuleBatchService', StationRuleBatchService::class);
+        app()->singleton('StationService', StationService::class);
+        app()->singleton('StationTaskBatchService', StationTaskBatchService::class);
+        app()->singleton('StationTaskBatchTypeService', StationTaskBatchTypeService::class);
+        app()->singleton('StationTaskChildService', StationTaskChildService::class);
+        app()->singleton('StationTaskCommodityService', StationTaskCommodityService::class);
+        app()->singleton('StationTaskMaterialBoxService', StationTaskMaterialBoxService::class);
+        app()->singleton('StationTaskService', StationTaskService::class);
+        app()->singleton('StationTaskTypeService', StationTaskTypeService::class);
+        app()->singleton('StationTypeBinMonitorService', StationTypeBinMonitorService::class);
+        app()->singleton('StationTypeService', StationTypeService::class);
+        app()->singleton('StorageService',StorageService::class);
+        app()->singleton('StoreCheckingReceiveItemService', StoreCheckingReceiveItemService::class);
+        app()->singleton('StoreCheckingReceiveService', StoreCheckingReceiveService::class);
+        app()->singleton('StoreItemService', StoreItemService::class);
+        app()->singleton('StoreService', StoreService::class);
+        app()->singleton('SupplierService', SupplierService::class);
+        app()->singleton('UnitService', UnitService::class);
+        app()->singleton('UserOwnerGroupService', UserOwnerGroupService::class);
+        app()->singleton('UserService', UserService::class);
+        app()->singleton('UserWorkgroupService', UserWorkgroupService::class);
+        app()->singleton('WarehouseService', WarehouseService::class);
+        app()->singleton('WaybillFinancialService', WaybillFinancialService::class);
+        app()->singleton('WeighExceptedService', WeighExceptedService::class);
     }
 
+    /**
+     * 快递同步接口 同步情况统计
+     */
+    private function logisticSyncRecord($displayName, $column_name): void
+    {
+
+
+        /**
+         * @var OrderPackageReceivedSyncRecordService $orderPackageReceivedSyncRecordService
+         */
+        $orderPackageReceivedSyncRecordService = app('OrderPackageReceivedSyncRecordService');
+        switch ($displayName) {
+            case LogisticZopSync::class:
+                $orderPackageReceivedSyncRecordService->createOrIncrementSucceededCount('中通', now()->toDateString(), $column_name);
+                break;
+            case LogisticSFSync::class:
+                $orderPackageReceivedSyncRecordService->createOrIncrementSucceededCount('顺丰', now()->toDateString(), $column_name);
+                break;
+            case LogisticYDSync::class:
+                $orderPackageReceivedSyncRecordService->createOrIncrementSucceededCount('韵达', now()->toDateString(), $column_name);
+                break;
+            case LogisticYTOSync::class:
+                $orderPackageReceivedSyncRecordService->createOrIncrementSucceededCount('圆通', now()->toDateString(), $column_name);
+                break;
+            default:
+                $orderPackageReceivedSyncRecordService->createOrIncrementSucceededCount('其他', now()->toDateString(), $column_name);
+        }
+    }
 
+    /**
+     * 判断当前任务类型是否为快递信息同步
+     * @param $displayName
+     * @return bool
+     */
+    private function isLogisticSyncJob($displayName): bool
+    {
+        return ($displayName == LogisticZopSync::class)
+            || ($displayName == LogisticSFSync::class)
+            || ($displayName == LogisticYDSync::class)
+            || ($displayName == LogisticYTOSync::class);
+    }
 }

+ 1 - 0
app/Providers/AuthServiceProvider.php

@@ -22,6 +22,7 @@ class AuthServiceProvider extends ServiceProvider
      * @var array
      */
     protected $policies = [
+		 \App\OwnerSundryFeeDetail::class => \App\Policies\OwnerSundryFeeDetailPolicy::class,
         // 'App\Model' => 'App\Policies\ModelPolicy',
         CustomerLog::class => CustomerLogPolice::class,
 

+ 1 - 0
app/Services/ForeignHaiRoboticsService.php

@@ -510,6 +510,7 @@ class ForeignHaiRoboticsService
     {
         $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' => "待处理",

+ 12 - 0
app/Services/LogisticRouteInterface.php

@@ -0,0 +1,12 @@
+<?php
+
+
+namespace App\Services;
+
+
+interface LogisticRouteInterface
+{
+    public function query($logistic_number);
+
+    public function format($nativeResponse);
+}

+ 1 - 1
app/Services/LogisticYDService.php

@@ -89,7 +89,7 @@ class LogisticYDService
 
     public function format($nativeResponse)
     {
-        if ($nativeResponse->code != '0000' || $nativeResponse->data->result=="false") {
+        if (is_null($nativeResponse) || $nativeResponse->code != '0000' || $nativeResponse->data->result == "false") {
             return [];
         } else {
             $nativeData = $nativeResponse->data;

+ 87 - 77
app/Services/LogisticZopService.php

@@ -3,101 +3,111 @@
 
 namespace App\Services;
 
-
-use App\library\zop\ZopClient;
-use App\library\zop\ZopProperties;
-use App\library\zop\ZopRequest;
+use App\OrderPackage;
 use Carbon\Carbon;
+use Illuminate\Support\Facades\Http;
 
-class LogisticZopService
+class LogisticZopService implements LogisticRouteInterface
 {
 
-
-    /**
-     * 获取中通快递路由信息
-     * @param array $logisticNums
-     * @return array
-     */
-    public function get(array $logisticNums): array
+    public function query($logistic_number)
     {
-        $result = [];
-
         $url = config('api_logistic.ZTO.url');
         $xAppKey = config('api_logistic.ZTO.x-appKey');
         $appSecret = config('api_logistic.ZTO.appSecret');
+        $body = json_encode([
+            'billCode' => $logistic_number,
+        ], JSON_UNESCAPED_UNICODE);
+        $data_digest = base64_encode(md5($body . $appSecret, TRUE));
+        $headers = [
+            'Content-Type' => 'application/json; charset=UTF-8',
+            'x-companyid' => $xAppKey,
+            'x-datadigest' => $data_digest,
+        ];
+        $response = Http::withHeaders($headers)->withBody($body, 'application/json')->post($url);
+        return json_decode($response->body());
+    }
 
-        $properties = new ZopProperties($xAppKey, $appSecret);
-        $client = new ZopClient($properties);
-        $request = new ZopRequest();
+    public function format($nativeResponse)
+    {
+        if (is_null($nativeResponse)||isEmpty($nativeResponse->result)) {//返回的结果为空,或者路由为[] 直接返回就好
+            return [];
+        }
+        $nativeRoutes = $nativeResponse->result;
+        $this->logistic_number = $nativeRoutes[0]->billCode;
+        $order_package = OrderPackage::query()->where('logistic_number', $this->logistic_number)->first();
 
-        $request->setUrl($url);
-        foreach ($logisticNums as $logisticNum) {
-            $request->setBody(json_encode([
-                'billCode' => $logisticNum,
-            ]));
-            $response = json_decode($client->execute($request));
+        $lastRoute = $nativeRoutes[count($nativeRoutes) - 1];
 
-            if ($response->status) {
-                $result[] = [
-                    'routes' => $response->result,
-                    'logisticNum' => $logisticNum,
-                ];
-            } else {
-//                throw new WarningException("单号没有查询到快递路由信息','LogisticZopService->get->{$logisticNum}");
-            }
+        $result = [
+            'logistic_number' => $this->logistic_number,
+            'exception_type' => $order_package->exception_type,
+            'exception'=>$order_package->exception,
+            'status' => $order_package->status,
+            'transfer_status' => $order_package->transfer_status,
+            'received_at' =>$order_package->received_at,
+        ];
+        list($status, $received_at) = $this->getNormalStatusAndReceivedAt($lastRoute);
+        $result['status'] = $status;
+        $result['received_at'] = $received_at;
+        $result['transfer_status'] = $this->getTransferStatus($nativeRoutes);
+        $result['routes_length'] = count($result['transfer_status']);
+        $orderPackageReceivedSyncService = app('OrderPackageReceivedSyncService');
+        $lastRouteDate = Carbon::parse($lastRoute->scanDate / 1000)->addHours(8)->toDateTimeString();
+        $exceptionData = $orderPackageReceivedSyncService->setExceptionType($result, $lastRouteDate);
+        $result['exception_type'] = $exceptionData['exception_type'];
+        $result['exception'] = $exceptionData['exception'];
+        return $result;
+    }
+
+    /**
+     * 正常的状态与签收时间
+     */
+    private function getNormalStatusAndReceivedAt($lastRoute): array
+    {
+        $status = null;
+        $received_at = null;
+        switch ($lastRoute->scanType) {
+            case '收件':
+                $status = '已揽收';
+                break;
+            case '到件':
+            case '发件':
+                $status = '在途';
+                break;
+            case 'ARRIVAL':
+            case '派件':
+                $status = '派送中';
+                break;
+            case 'SIGNED':
+            case '签收':
+                $status = '已收件';
+                $received_at = Carbon::parse($lastRoute->scanDate / 1000)->toDateTimeString();
+                break;
+            default:
+                $status = '无';
+                break;
         }
-        return $this->transformRoutes($result);
+        return array($status, $received_at);
     }
 
+
     /**
-     * 转换快递路由信息
-     * @param array $routs 快递路由
+     * @param $nativeRoutes
      * @return array
      */
-    public function transformRoutes(array $routs): array
+    private function getTransferStatus($nativeRoutes): array
     {
-        $result = [];
-        foreach ($routs as $route) {
-            $resultItem = [];
-            $resultItem['logistic_number'] = $route['logisticNum'];
-            $itemRoutes = $route['routes'];
-            if (empty($itemRoutes)) {
-                continue;
-            }
-            $lastRoute = $itemRoutes[count($itemRoutes) - 1];
-            switch ($lastRoute->scanType) {
-                case '收件':
-                    $resultItem['status'] = '已揽收';
-                    break;
-                case '到件':
-                case '发件':
-                    $resultItem['status'] = '在途';
-                    break;
-                case 'ARRIVAL':
-                case '派件':
-                    $resultItem['status'] = '派送中';
-                    break;
-                case 'SIGNED':
-                case '签收':
-                    $resultItem['status'] = '已收件';
-                    $resultItem['received_at'] = Carbon::parse($lastRoute->scanDate / 1000)->toDateTimeString();
-                    break;
-                default:
-                    break;
-            }
-            $transfer_status = [];
-            foreach ($itemRoutes as $item) {
-                $data = [];
-                $data['accept_time'] = Carbon::parse($item->scanDate / 1000)->toDateTimeString();
-                $scanSite = $item->scanSite;
-                $data['accept_address'] = $scanSite->prov . '-' . $scanSite->name;
-                $data['remark'] = $item->scanType;
-
-                $transfer_status[] = $data;
-            }
-            $resultItem['transfer_status'] = $transfer_status;
-            $result[] = $resultItem;
+        $transfer_status = [];
+        foreach ($nativeRoutes as $item) {
+            $data = [];
+            $data['accept_time'] = Carbon::parse($item->scanDate / 1000)->addHours(8)->toDateTimeString();
+            $scanSite = $item->scanSite;
+            $data['accept_address'] = $scanSite->prov . '-' . $scanSite->name;
+            $data['remark'] = $item->desc;
+            $transfer_status[] = $data;
         }
-        return $result;
+        return $transfer_status;
     }
+
 }

+ 5 - 0
app/Services/MaterialBoxService.php

@@ -39,6 +39,11 @@ class MaterialBoxService
                     ->where("status","!=","已完成")->groupBy("material_box_id"))
                 ->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();
+            if ($haiBoxes->count()==0)continue;
+            $haiBoxes->each(function ($haiBox)use(&$codes){$codes[$haiBox->ks_bin_code] = true;});
+            foreach ($boxes as $index=>$box)if (!isset($codes[$box->code]))$boxes->splice($index,1);
             $ides = [];
             $str = "(";
             for ($i=0;$i<count($boxes)-1;$i++){

+ 33 - 0
app/Services/OrderPackageReceivedSyncRecordService.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\OrderPackageReceivedSyncRecord;
+
+class OrderPackageReceivedSyncRecordService
+{
+    use ServiceAppAop;
+
+    protected $modelClass = OrderPackageReceivedSyncRecord::class;
+
+    /**
+     * @param $logistic_name string 成员商名称
+     * @param $recorded_at string 统计日期
+     * @param $column_name string 操作列名称 succeed_count or failed_count
+     */
+    public function createOrIncrementSucceededCount(string $logistic_name, string $recorded_at, string $column_name)
+    {
+        $orderPackageReceivedSyncRecord = OrderPackageReceivedSyncRecord::query()->where('logistic_name', $logistic_name)->whereDate('recorded_at', $recorded_at)->first();
+
+        if (is_null($orderPackageReceivedSyncRecord)) {
+            OrderPackageReceivedSyncRecord::query()->create([
+                'logistic_name' => $logistic_name,
+                'recorded_at' => $recorded_at,
+                $column_name => 1,
+            ]);
+        } else {
+            $orderPackageReceivedSyncRecord->increment($column_name);
+        }
+    }
+}

+ 4 - 4
app/Services/OrderPackageReceivedSyncService.php

@@ -26,8 +26,8 @@ class OrderPackageReceivedSyncService
      */
     public function syncLogisticRoute()
     {
+        ini_set('max_execution_time', 2 * 60 * 60);
         LogService::log(OrderPackageReceivedSyncService::class, "同步快递信息定时方法", '');
-        ini_set('max_execution_time', 60 * 60);
         //初始化时间 2020-12-31 23:59:59
         $initDate = Carbon::parse(config('api_logistic.init_date'));
         $query = OrderPackage::query()
@@ -141,17 +141,17 @@ class OrderPackageReceivedSyncService
                     unset($data['exception']);
                 }
             } catch (Exception $e) {
-                LogService::log(OrderPackageReceivedSyncService::class, "标记问题件不需要更新异常状态失败", $data['logistic_number'].'-'.json_encode($e));
+                LogService::log(OrderPackageReceivedSyncService::class, "标记问题件不需要更新异常状态失败", $data['logistic_number'] . '-' . json_encode($e));
             }
             //如果已经收货,将异常更新为正常
-            if (array_key_exists('received_at',$data)) {
+            if (array_key_exists('received_at', $data)) {
                 $data['exception_type'] = '无';
                 $data['exception'] = '否';
             }
             if (isset($data['status'])) $orderPackage->status = $data['status'];
             if (isset($data['received_at'])) $orderPackage->received_at = $data['received_at'];
             if (isset($data['exception'])) $orderPackage->exception = $data['exception'];
-            if (isset($data['transfer_status'])&&!empty($data['transfer_status'])) $orderPackage->transfer_status = $data['transfer_status'];
+            if (isset($data['transfer_status']) && !empty($data['transfer_status'])) $orderPackage->transfer_status = $data['transfer_status'];
             if (isset($data['exception_type'])) $orderPackage->exception_type = $data['exception_type'];
             $orderPackage->save();
         }

+ 2 - 5
app/Services/OrderService.php

@@ -6,7 +6,6 @@ use App\Commodity;
 use App\Feature;
 use App\Jobs\OrderCreateInstantBill;
 use App\Jobs\OrderFreeze;
-use App\Log;
 use App\Logistic;
 use App\OracleActAllocationDetails;
 use App\OracleDOCASNHeader;
@@ -17,7 +16,6 @@ use App\OrderIssue;
 use App\Owner;
 use App\OwnerFeeDetail;
 use App\OwnerFeeDetailLogistic;
-use App\OwnerPriceExpress;
 use App\OwnerReport;
 use App\Province;
 use App\RejectedBill;
@@ -30,7 +28,6 @@ use App\Warehouse;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\App;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
 use App\Traits\ServiceAppAop;
@@ -1320,7 +1317,7 @@ sql
         $order->loadMissing("packages","owner");//加载包裹
         if (!$order->packages || !$order->owner)return false;
         $order->owner->loadCount("ownerPriceExpresses");
-        if ($order->owner->owner_price_expresses_count < 1)return false; //不存在计费模型 跳出
+        //if ($order->owner->owner_price_expresses_count < 1)return false; //不存在计费模型 跳出
         foreach ($order->packages as $package)if (!$package->weight)return false; //包裹存在且全部存在数量
 
         $logistic_fee = 0;
@@ -1363,7 +1360,7 @@ sql
             $taxFee += $tax;
         }
         if ($isBunched && !$weightExceptionMark && $weight>0 && $provinceId)list($logistic_fee,$taxFee) = app("OwnerPriceExpressService")->matching($weight, $order->owner_id, $order->logistic_id, $provinceId);
-        if ($logistic_fee!==null && $logistic_fee>0) $feeBill->update(["logistic_fee"=>$logistic_fee,"volume"=>$volume,"weight"=>$weight,"logistic_tax_fee"=>$taxFee]);
+        $feeBill->update(["logistic_fee"=>$logistic_fee,"volume"=>$volume,"weight"=>$weight,"logistic_tax_fee"=>$taxFee]);
         return true;
     }
 

+ 2 - 2
app/Services/OwnerAreaReportService.php

@@ -62,8 +62,8 @@ class OwnerAreaReportService
                     ->where("counting_month",'like',$area->counting_month."%")->first();
                 if ($report){
                     if (!$area->ownerStoragePriceModel)return false;
-                    $storeFee = app("OwnerStoragePriceModelService")->calculationAmount($area->ownerStoragePriceModel, $values["accounting_area"], $area->owner_id, $area->counting_month);
-                    $up = ["storage_fee"=>$storeFee];
+                    list($storeFee,$taxFee) = app("OwnerStoragePriceModelService")->calculationAmount($area->ownerStoragePriceModel, $values["accounting_area"], $area->owner_id, $area->counting_month);
+                    $up = ["storage_fee"=>$storeFee,"storage_tax_fee"=>$taxFee];
                     if ($report->confirm_fee !== null || $report->confirmed == '是'){
                         $initial = $report->work_fee + $report->logistic_fee + $storeFee;
                         $up["difference"] = $initial - $report->confirm_fee;

+ 0 - 7
app/Services/OwnerPriceDirectLogisticService.php

@@ -106,14 +106,7 @@ class OwnerPriceDirectLogisticService
         if (!is_array($id))$id = [$id];
         OwnerPriceDirectLogisticCar::query()->whereIn("owner_price_direct_logistic_id",$id)->delete();
 
-        $query = "IN (";
-        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
-        $query .= "{$id[count($id)-1]})";
-
-        $sql = "SELECT * FROM owner_price_direct_logistic_owner WHERE owner_price_direct_logistic_id {$query}";
-        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
         DB::table("owner_price_direct_logistic_owner")->whereIn("owner_price_direct_logistic_id",$id)->delete();
-        app("OwnerService")->refreshRelevance($owners,4,true);
         return OwnerPriceDirectLogistic::destroy($id);
     }
 

+ 0 - 8
app/Services/OwnerPriceExpressService.php

@@ -193,15 +193,7 @@ class OwnerPriceExpressService
         if (!$id)return 0;
         if (!is_array($id))$id = [$id];
         OwnerPriceExpressProvince::query()->whereIn("owner_price_express_id",$id)->delete();
-
-        $query = "IN (";
-        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
-        $query .= "{$id[count($id)-1]})";
-
-        $sql = "SELECT * FROM owner_price_express_owner WHERE owner_price_express_id {$query}";
-        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
         DB::table("owner_price_express_owner")->whereIn("owner_price_express_id",$id)->delete();
-        app("OwnerService")->refreshRelevance($owners,2,true);
         DB::table("owner_price_express_logistic")->whereIn("owner_price_express_id",$id)->delete();
         return OwnerPriceExpress::destroy($id);
     }

+ 0 - 7
app/Services/OwnerPriceLogisticService.php

@@ -125,14 +125,7 @@ class OwnerPriceLogisticService
         if (!is_array($id))$id = [$id];
         OwnerPriceLogisticDetail::query()->whereIn("owner_price_logistic_id",$id)->delete();
 
-        $query = "IN (";
-        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
-        $query .= "{$id[count($id)-1]})";
-
-        $sql = "SELECT * FROM owner_price_logistic_owner WHERE owner_price_logistic_id {$query}";
-        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
         DB::table("owner_price_logistic_owner")->whereIn("owner_price_logistic_id",$id)->delete();
-        app("OwnerService")->refreshRelevance($owners,3,true);
         DB::table("owner_price_logistic_logistic")->whereIn("owner_price_logistic_id",$id)->delete();
 
         return OwnerPriceLogistic::destroy($id);

+ 26 - 18
app/Services/OwnerPriceOperationService.php

@@ -141,14 +141,7 @@ class OwnerPriceOperationService
         if (!is_array($id))$id = [$id];
         OwnerPriceOperationItem::query()->whereIn("owner_price_operation_id",$id)->delete();
 
-        $query = "IN (";
-        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
-        $query .= "{$id[count($id)-1]})";
-
-        $sql = "SELECT * FROM owner_price_operation_owner WHERE owner_price_operation_id {$query}";
-        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
         DB::table("owner_price_operation_owner")->whereIn("owner_price_operation_id",$id)->delete();
-        app("OwnerService")->refreshRelevance($owners,1,true);
 
         return OwnerPriceOperation::destroy($id);
     }
@@ -319,7 +312,7 @@ class OwnerPriceOperationService
      */
     public function matching($matchObject, $columnMapping, $ownerId, $type = '出库', $typeMark = null)
     {
-        $units = app("UnitService")->getUnitMapping(["件","箱"]); //获取单位映射集
+        $units = app("UnitService")->getUnitMapping(["件","箱","m³","T","kg"]); //获取单位映射集
         $rules = $this->getOwnerPriceOperation($ownerId,$type,$typeMark);//货主下的全部规则
         if (!$rules)return -2;  //规则不存在跳出
 
@@ -331,6 +324,9 @@ class OwnerPriceOperationService
         if ($type == '出库'){
             $total = app("OrderService")->getOrderQuantity($ownerId)+1;//获取该货主本月C端单量
             $matchObject->packages->each(function ($package)use(&$orderTotal){
+                if($package->commodities->count()==0)return;
+                $package->commodities[0]->bulk = $package->bulk/1000000;
+                $package->commodities[0]->weight = $package->weight;
                 $package->commodities->each(function ($commodity)use(&$orderTotal){
                     $orderTotal += (int)$commodity->amount;
                 });
@@ -468,17 +464,29 @@ class OwnerPriceOperationService
                 }
                 $package["price"] = $rule->unit_price;
             }
-            if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
-                $amount = 0;
-                foreach ($matchObject as $commodity){
-                    $pack = $this->changeUnit($ownerId,$commodity[$columnMapping[9]]);
-                    if ($rule->odd_price){
-                        $amount += floor($amount/$pack);
-                        $surcharge += $rule->odd_price * ($amount%$pack); //零头附加费
-                    }else$amount += ceil($amount/$pack);
+            if ($units[$rule->unit_id] != '件'){ //非件时改变商品数量 此时数量可能为小数
+                foreach ($matchObject as &$commodity){
+                    switch ($units[$rule->unit_id]){
+                        case "箱"://为箱时同步商品寻找箱规并改变商品数量
+                            $pack = $this->changeUnit($ownerId,$commodity[$columnMapping[9]]);
+                            if ($rule->odd_price){
+                                $amount = floor($commodity[$columnMapping[8]]/$pack);
+                                $surcharge += $rule->odd_price * ($amount%$pack); //零头附加费
+                            }else$amount = ceil($commodity[$columnMapping[8]]/$pack);
+                            if ($amount<0)return $amount;
+                            $commodity[$columnMapping[8]] = $amount;
+                            break;
+                        case "m³":
+                            $commodity[$columnMapping[8]] = $commodity["bulk"] ?? 0;
+                            break;
+                        case "kg":
+                            $commodity[$columnMapping[8]] = $commodity["weight"] ?? 0;
+                            break;
+                        case "T":
+                            $commodity[$columnMapping[8]] = ($commodity["weight"]/1000) ?? 0;
+                            break;
+                    }
                 }
-                if ($amount<0)return $amount;
-                $package[$columnMapping[8]] = $amount;
             }
         }
         if ($matchObject){

+ 46 - 53
app/Services/OwnerService.php

@@ -185,14 +185,12 @@ class OwnerService
 
     public function get(array $params, array $withs = null, bool $authority = true, bool $notShowSoftDelete = false, $user = null)
     {
+        /** @var User $user */
+        if ($user==null)$user = Auth::user();
         return Cache::remember(
             'owner_'.md5(json_encode($params).json_encode($withs).$authority.$notShowSoftDelete.json_encode($user))
             ,config('cache.expirations.rarelyChange')
             ,function()use($params,$withs,$authority,$notShowSoftDelete,$user){
-            /** @var User $user */
-            if ($user==null) {
-                $user = Auth::user();
-            }
             $query = Owner::query();
             if ($withs)$query->with($withs);
             if ($authority&&$user){
@@ -380,58 +378,53 @@ sql
     /**
      * 计费模型变动时更新货主中关联属性
      *
-     * @param integer|array $owner
-     * @param integer $type
-     * @param bool $isDestroy
+     * @param integer $ownerId
      *
      */
-    public function refreshRelevance($owner, $type, $isDestroy = false)
+    public function refreshRelevance($ownerId)
     {
-        if (!$owner)return;
-        if (!is_array($owner))$owner = [$owner];
-        $owners = Owner::query()->select("id","relevance")->whereIn("id",$owner)->get();
-        $update = [["id","relevance"]];
-        foreach ($owners as $ow){
-            $relevance = $ow->relevance ?? [];
-            $index = array_search($type,$relevance);
-            $exist = $index===false ? false : true;
-            if ($exist && $isDestroy && !$this->isExistModel($ow->id,$type)){
-                array_splice($relevance,$index,1);
-                $update[] = [
-                    "id"=>$ow->id,
-                    "relevance"=>$relevance,
-                ];
-            }
-            if (!$exist && !$isDestroy){
-                array_push($relevance,$type);
-                $update[] = [
-                    "id"=>$ow->id,
-                    "relevance"=>$relevance,
-                ];
-            }
-        }
-        if (count($update)>1)app(BatchUpdateService::class)->batchUpdate("owners",$update);
-    }
-
-    private function isExistModel($owner, $type):bool
-    {
-        switch ($type){
-            case 0:
-                $table = "owner_storage_price_model_owner";
-                break;
-            case 1:
-                $table = "owner_price_operation_owner";
-                break;
-            case 2:
-                $table = "owner_price_logistic_owner";
-                break;
-            case 3:
-                $table = "owner_price_express_owner";
-                break;
-            default:
-                $table = "owner_price_direct_logistic_owner";
-        }
-        return DB::selectOne(DB::raw("SELECT 1 FROM {$table} WHERE owner_id = ? LIMIT 1"),[$owner]) ? true : false;
+        $relevance = [];
+        $sql = <<<sql
+SELECT 1 FROM owner_storage_price_models a 
+LEFT JOIN owner_storage_price_model_owner b ON a.id =  b.owner_storage_price_model_id 
+LEFT JOIN owners c ON b.owner_id = c.id 
+WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
+sql;
+        if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 0;
+        $sql = <<<sql
+SELECT 1 FROM owner_price_operations a 
+LEFT JOIN owner_price_operation_owner b ON a.id =  b.owner_price_operation_id 
+LEFT JOIN owners c ON b.owner_id = c.id 
+WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
+sql;
+        if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 1;
+        $sql = <<<sql
+SELECT 1 FROM owner_price_expresses a 
+LEFT JOIN owner_price_express_owner b ON a.id =  b.owner_price_express_id 
+LEFT JOIN owners c ON b.owner_id = c.id 
+WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
+sql;
+        if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 2;
+        $sql = <<<sql
+SELECT 1 FROM owner_price_logistics a 
+LEFT JOIN owner_price_logistic_owner b ON a.id =  b.owner_price_logistic_id 
+LEFT JOIN owners c ON b.owner_id = c.id 
+WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
+sql;
+        if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 3;
+        $sql = <<<sql
+SELECT 1 FROM owner_price_direct_logistics a 
+LEFT JOIN owner_price_direct_logistic_owner b ON a.id =  b.owner_price_direct_logistic_id 
+LEFT JOIN owners c ON b.owner_id = c.id 
+WHERE (a.operation IS NULL OR a.operation = '') AND c.id = ? LIMIT 1
+sql;
+        if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 4;
+        $sql = <<<sql
+SELECT 1 FROM owner_price_systems a LEFT JOIN owners b ON a.owner_id = b.id
+WHERE b.id = ? LIMIT 1
+sql;
+        if (DB::selectOne(DB::raw($sql),[$ownerId]))$relevance[] = 5;
+        Owner::query()->where("id",$ownerId)->update(["relevance"=>$relevance]);
     }
 
     /**

+ 0 - 4
app/Services/OwnerStoragePriceModelService.php

@@ -92,7 +92,6 @@ class OwnerStoragePriceModelService
     }
     public function destroy($id)
     {
-        $sql = "SELECT * FROM owner_storage_price_model_owner WHERE owner_storage_price_model_id ";
         if (is_array($id)){
             $query = "IN (";
             for ($i=0;$i<count($id)-1;$i++)$query .= "?,";
@@ -101,10 +100,7 @@ class OwnerStoragePriceModelService
             $query = "= ?";
             $id = [$id];
         }
-        $owners = array_column(DB::select(DB::raw($sql.$query),$id),"owner_id");
         DB::delete(DB::raw("DELETE FROM owner_storage_price_model_owner WHERE owner_storage_price_model_id ".$query),$id);
-        app("OwnerService")->refreshRelevance($owners,0,true);
-
         return OwnerStoragePriceModel::destroy($id);
     }
 

+ 2 - 1
app/Services/RejectedService.php

@@ -118,7 +118,8 @@ class RejectedService
         },config('cache.expirations.oftenChange'));
     }
     public function getSql(array $param){
-        $sql = $this->conditionQuery($param)->selectRaw('rejected_bills.*')->whereNull('rejected_bills.deleted_at')
+        $sql = $this->conditionQuery($param)->selectRaw("rejected_bills.*,CASE rejected_bills.is_loaded WHEN 0 THEN '否' WHEN 1 THEN '是' WHEN 2 THEN '待推单' WHEN 3 THEN '上传异常' WHEN 4 THEN '待确认' ELSE '无需入库' END loaded")
+            ->whereNull('rejected_bills.deleted_at')
             ->leftJoin('owners','rejected_bills.id_owner','=','owners.id')
             ->selectRaw('owners.name owner_name')
             ->leftJoin('logistics','rejected_bills.id_logistic_return','=','logistics.id')

+ 7 - 1
app/Services/StationService.php

@@ -60,16 +60,20 @@ class StationService
 
 
     function broadcast($station_id, ?StationTask $stationTask){
+        LogService::log('海柔请求in2','broadcast',
+            $station_id.'|'.json_encode($stationTask));
         if($stationTask)
             $json = $stationTask->toJson();
         else
             $json =[];
-        LogService::log('海柔请求','broadcastBinMonitor',
+        LogService::log('海柔请求done2','broadcast',
             $station_id.'|'.$json);
         broadcast(new BroadcastToStation($station_id, $json));
     }
 
     function broadcastBinMonitor($station_id, ?StationTask $stationTask){
+        LogService::log('海柔请求in1','broadcastBinMonitor',
+            $station_id.'|'.json_encode($stationTask));
         if(!$stationTask)return;
         $this->instant($this->stationTaskService,'StationTaskService');
         if($stationTask['status']=='完成')
@@ -81,6 +85,8 @@ class StationService
                 "stationTaskBatches.batch",
                 "stationTaskMaterialBoxes.materialBox",
             ]);
+        LogService::log('海柔请求done1','broadcastBinMonitor',
+            $station_id.'|'.json_encode($stationTask));
         $this->broadcast($station_id, $stationTask);
     }
 

+ 61 - 0
app/Services/StorageService.php

@@ -0,0 +1,61 @@
+<?php 
+
+namespace App\Services;
+
+use App\StationTask;
+use App\StationTaskMaterialBox;
+use App\Traits\ServiceAppAop;
+use App\Storage;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Collection;
+
+class StorageService
+{
+    use ServiceAppAop;
+    protected $modelClass=Storage::class;
+
+
+    /**
+     * 填充缓存架
+     *
+     * @param \Illuminate\Database\Eloquent\Collection $stations
+     */
+    public function paddingCacheShelf($stations)
+    {
+        $collection = new Collection();
+        $stationCollection = new Collection();
+        $blacklist = [];
+        foreach ($stations as $station){
+            $box = app("MaterialBoxService")->getAnEmptyBox($blacklist);
+            if (!$box)continue;
+            $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;
+        }
+        app("ForeignHaiRoboticsService")->fetchGroup_multiLocation($stationCollection,$collection,'','立架出至缓存架');
+    }
+    /**
+     * 标记指定库位为占用
+     *
+     * @param string $location
+     *
+     * @return int
+     */
+    public function markOccupy($location)
+    {
+        return Storage::query()->whereHas("station",function (Builder $query)use($location){
+            $query->where("code",$location);
+        })->update(["status"=>1]);
+    }
+
+}

+ 4 - 4
app/Services/WaybillService.php

@@ -28,8 +28,8 @@ class WaybillService
      */
     private function conditionQuery(array $param){
         $waybills = Waybill::filterAuthorities()->with(['owner','logistic','originationCity','destinationCity.parent',
-            'uploadFile','amountUnit','warehouseWeightUnit','carrierWeightUnit','district','order',
-            'warehouseWeightUnitOther','carrierWeightUnitOther','carType','uploadFile','waybillAuditLogs.user'])
+            'uploadFiles','amountUnit','warehouseWeightUnit','carrierWeightUnit','district','order',
+            'warehouseWeightUnitOther','carrierWeightUnitOther','carType','uploadFiles','waybillAuditLogs.user'])
             ->selectRaw('waybills.* ,waybill_on_tops.id top_id ,waybill_on_tops.remark,waybill_on_tops.updated_at top_update')
             ->leftJoin('waybill_on_tops','waybill_on_tops.waybill_id','=','waybills.id')
             ->whereNull('waybill_on_tops.deleted_at')
@@ -163,8 +163,8 @@ class WaybillService
     }
     public function dailyBilling(array $param){
         $waybills = Waybill::query()->with(['owner','logistic','originationCity','destinationCity.parent',
-            'uploadFile','amountUnit','warehouseWeightUnit','carrierWeightUnit','district','order',
-            'warehouseWeightUnitOther','carrierWeightUnitOther','carType','uploadFile','waybillAuditLogs.user'])
+            'uploadFiles','amountUnit','warehouseWeightUnit','carrierWeightUnit','district','order',
+            'warehouseWeightUnitOther','carrierWeightUnitOther','carType','uploadFiles','waybillAuditLogs.user'])
             ->selectRaw('waybills.* ,waybill_on_tops.id top_id,waybill_on_tops.remark,waybill_on_tops.updated_at top_update')
             ->leftJoin('waybill_on_tops','waybill_on_tops.waybill_id','=','waybills.id')
             ->whereNull('waybill_on_tops.deleted_at')

+ 14 - 3
app/Storage.php

@@ -11,17 +11,28 @@ class Storage extends Model
     use ModelLogChanging;
 
     protected $fillable = [
+        "station_id",
         "material_box_id",
         "commodity_id",
-        "amount"
+        "amount",
+        "status"
     ];
 
+    const STATUS=[
+        0 => "正常",
+        1 => "占用",
+    ];
+
+    public function station()
+    {   //货架
+        return $this->belongsTo(Station::class);
+    }
     public function materialBox()
     {   //料箱
-        $this->belongsTo(MaterialBox::class);
+        return $this->belongsTo(MaterialBox::class);
     }
     public function commodity()
     {   //商品
-        $this->belongsTo(Commodity::class);
+        return $this->belongsTo(Commodity::class);
     }
 }

+ 2 - 2
app/Waybill.php

@@ -107,8 +107,8 @@ class Waybill extends Model
     public function waybillAuditLogs(){
         return $this->hasMany('App\WaybillAuditLog','waybill_id','id')->orderByDesc("created_at");
     }
-    public function uploadFile(){
-        return $this->hasOne('App\UploadFile','table_id','id')->where('table_name','waybills');
+    public function uploadFiles(){
+        return $this->hasMany(UploadFile::class,'table_id','id')->where('table_name','waybills');
     }
     public function order()
     {   //订单

+ 0 - 23
app/library/zop/README.md

@@ -1,23 +0,0 @@
-# 中通开放平台SDK(php版)
-
-## 使用方式
-
-```php
-use App\library\zop\ZopClient;
-use App\library\zop\ZopProperties;
-use App\library\zop\ZopRequest;
-
-// ZopProperties类的构造方法接收两个参数,分别是companyid和key,都需要注册中通开放平台后到个人中心查看
-$properties = new ZopProperties("kfpttestCode", "kfpttestkey==");
-$client = new ZopClient($properties);
-
-$request = new ZopRequest();
-$request->setUrl("http://58.40.16.120:9001/submitOrderCode");
-$request->setData('{"data":{"content":{"branchId":"","buyer":"","collectMoneytype":"CNY","collectSum":"12.00","freight":"10.00","id":"xfs2018031500002222333","orderSum":"0.00","orderType":"1","otherCharges":"0.00","packCharges":"1.00","premium":"0.50","price":"126.50","quantity":"2","receiver":{"address":"育德路XXX号","area":"501022","city":"四川省,XXX,XXXX","company":"XXXX有限公司","email":"yyj@abc.com","id":"130520142097","im":"yangyijia-abc","mobile":"136*****321","name":"XXX","phone":"010-222***89","zipCode":"610012"},"remark":"请勿摔货","seller":"","sender":{"address":"华新镇华志路XXX号","area":"310118","city":"上海,上海市,青浦区","company":"XXXXX有限公司","email":"ll@abc.com","endTime":1369033200000,"id":"131*****010","im":"1924656234","mobile":"1391***5678","name":"XXX","phone":"021-87***321","startTime":1369022400000,"zipCode":"610012"},"size":"12,23,11","tradeId":"2701843","type":"1","typeId":"","weight":"0.753"},"datetime":"2018-3-30 12:00:00","partner":"test","verify":"ZTO123"}}');
-
-echo $client->execute($request);
-```
-
-## 其他
-1. 该项目刚创建,功能还很不完善,如有问题请提issue
-2. 由于中通开放平台各个接口返回值格式没有统一,所以未封装返回值,未来可能会做封装

+ 0 - 60
app/library/zop/ZopClient.php

@@ -1,60 +0,0 @@
-<?php
-
-
-namespace App\library\zop;
-use App\library\zop\ZopHttpUtil;
-use Illuminate\Support\Facades\Http;
-
-class ZopClient
-{
-    private $zopProperties;
-
-    private $httpClient;
-    /**
-     * ZopClient constructor.
-     * @param $zopProperties
-     */
-    public function __construct($zopProperties)
-    {
-        $this->zopProperties = $zopProperties;
-        $this->httpClient = new ZopHttpUtil();
-    }
-
-    public function execute($zopRequest)
-    {
-        if($zopRequest->getBody()==null) {
-            $url = $zopRequest->getUrl();
-            $params = $zopRequest->getParams();
-            $fixedParams = array();
-            foreach ($params as $k => $v) {
-                if (gettype($v) != "string") {
-                    $fixedParams += [$k => json_encode($v)];
-                } else {
-                    $fixedParams += [$k => $v];
-                }
-            }
-            $str_to_digest = "";
-            foreach ($fixedParams as $k => $v) {
-                $str_to_digest = $str_to_digest .$k ."=" .$v ."&";
-            }
-            $str_to_digest = substr($str_to_digest, 0, -1) .$this->zopProperties->getKey();
-            $data_digest = base64_encode(md5($str_to_digest, TRUE));
-            $headers = array(
-                "Content-Type: application/x-www-form-urlencoded; charset=UTF-8",
-                "x-companyid: " . $this->zopProperties->getCompanyid(),
-                "x-datadigest: " . $data_digest
-            );
-            return $this->httpClient->post($url, $headers, http_build_query($fixedParams), 2000);
-        } else {
-            $url = $zopRequest->getUrl();
-            $body = $zopRequest->getBody();
-            $str_to_digest = $body . $this->zopProperties->getKey();
-            $data_digest = base64_encode(md5($str_to_digest, TRUE));
-            return Http::withHeaders([
-                'Content-Type' => 'application/json; charset=UTF-8',
-                'x-companyid' => $this->zopProperties->getCompanyid(),
-                'x-datadigest' => $data_digest,
-            ])->withBody(json_encode((array)json_decode($body), JSON_UNESCAPED_UNICODE), 'application/json')->post($url)->body();
-        }
-    }
-}

+ 0 - 20
app/library/zop/ZopHttpUtil.php

@@ -1,20 +0,0 @@
-<?php
-
-namespace App\library\zop;
-
-class ZopHttpUtil
-{
-    public function post($url, $headers, $querystring, $timeout)
-    {
-        $ch = curl_init();
-        curl_setopt($ch, CURLOPT_URL, $url);//设置链接
-        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置是否返回信息
-        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);//设置HTTP头
-        curl_setopt($ch, CURLOPT_POST, 1);//设置为POST方式
-        curl_setopt($ch, CURLOPT_TIMEOUT_MS, $timeout);
-        curl_setopt($ch, CURLOPT_POSTFIELDS, $querystring);
-        $response = curl_exec($ch);
-        return $response;
-    }
-
-}

+ 0 - 46
app/library/zop/ZopProperties.php

@@ -1,46 +0,0 @@
-<?php
-/**
- * Created by PhpStorm.
- * User: choco
- * Date: 6/13/18
- * Time: 5:47 PM
- */
-namespace App\library\zop;
-
-
-class ZopProperties
-{
-    private $companyid;
-    private $key;
-
-    /**
-     * ZopProperties constructor.
-     * @param $companyid
-     * @param $key
-     */
-    public function __construct($companyid, $key)
-    {
-        $this->companyid = $companyid;
-        $this->key = $key;
-    }
-
-    /**
-     * @return mixed
-     */
-    public function getCompanyid()
-    {
-        return $this->companyid;
-    }
-
-    /**
-     * @return mixed
-     */
-    public function getKey()
-    {
-        return $this->key;
-    }
-
-
-
-
-}

+ 0 - 59
app/library/zop/ZopRequest.php

@@ -1,59 +0,0 @@
-<?php
-
-namespace App\library\zop;
-
-
-class ZopRequest
-{
-    private $url;
-    private $params = Array();
-    private $body;
-
-    public function addParam($k, $v)
-    {
-        $this->params += [$k => $v];
-    }
-
-    /**
-     * @param mixed $url
-     */
-    public function setUrl($url)
-    {
-        $this->url = $url;
-    }
-
-    public function setData($data)
-    {
-        $this->params = json_decode($data);
-    }
-
-    public function setBody($body)
-    {
-        $this->body = $body;
-    }
-
-    public function getBody()
-    {
-        return $this->body;
-    }
-
-
-
-    /**
-     * @return mixed
-     */
-    public function getUrl()
-    {
-        return $this->url;
-    }
-
-    /**
-     * @return array
-     */
-    public function getParams()
-    {
-        return $this->params;
-    }
-
-
-}

+ 1 - 5
composer.json

@@ -66,11 +66,7 @@
             "database/factories"
         ],
         "files": [
-            "app/Utils/helpers.php",
-            "app/library/zop/ZopClient.php",
-            "app/library/zop/ZopHttpUtil.php",
-            "app/library/zop/ZopProperties.php",
-            "app/library/zop/ZopRequest.php"
+            "app/Utils/helpers.php"
         ]
     },
     "autoload-dev": {

+ 16 - 0
database/factories/OrderPackageReceivedSyncRecordFactory.php

@@ -0,0 +1,16 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OrderPackageReceivedSyncRecord;
+use Faker\Generator as Faker;
+
+$factory->define(OrderPackageReceivedSyncRecord::class, function (Faker $faker) {
+    $logistic_names = ['中通', '顺丰', '韵达', '圆通', '其他'];
+    return [
+        'logistic_name' => $faker->randomElement($logistic_names),
+        'recorded_at' => now()->toDateString(),
+        'succeed_count' => random_int(10000, 20000),
+        'failed_count' => random_int(10000, 20000),
+    ];
+});

+ 11 - 0
database/factories/OwnerSundryFeeDetailFactory.php

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

+ 4 - 3
database/migrations/2020_11_30_140957_create_station_types_table.php

@@ -1,5 +1,6 @@
 <?php
 
+use App\StationType;
 use Illuminate\Database\Migrations\Migration;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Support\Facades\Schema;
@@ -18,9 +19,9 @@ class CreateStationTypesTable extends Migration
             $table->string('name')->index();
             $table->timestamps();
         });
-        \App\StationType::query()->firstOrCreate(['name'=>'料箱出货口']);
-        \App\StationType::query()->firstOrCreate(['name'=>'料箱入货口']);
-        \App\StationType::query()->firstOrCreate(['name'=>'料箱监视器']);
+        StationType::query()->firstOrCreate(['name'=>'料箱出货口']);
+        StationType::query()->firstOrCreate(['name'=>'料箱入货口']);
+        StationType::query()->firstOrCreate(['name'=>'料箱监视器']);
     }
 
     /**

+ 8 - 8
database/migrations/2021_05_21_131520_add_order_packages_logistic_number_unique.php

@@ -13,10 +13,10 @@ class AddOrderPackagesLogisticNumberUnique extends Migration
      */
     public function up()
     {
-        Schema::table('order_packages', function (Blueprint $table) {
-            //
-            $table->string('logistic_number')->unique()->change();
-        });
+//        Schema::table('order_packages', function (Blueprint $table) {
+//            //
+//            $table->string('logistic_number')->unique()->change();
+//        });
     }
 
     /**
@@ -26,9 +26,9 @@ class AddOrderPackagesLogisticNumberUnique extends Migration
      */
     public function down()
     {
-        Schema::table('order_packages', function (Blueprint $table) {
-            //
-            $table->dropUnique(['logistic_number']);
-        });
+//        Schema::table('order_packages', function (Blueprint $table) {
+//            //
+//            $table->dropUnique(['logistic_number']);
+//        });
     }
 }

+ 27 - 0
database/migrations/2021_05_27_103720_create_ownersundryfeedetails_table.php

@@ -0,0 +1,27 @@
+<?php
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateOwnerSundryFeeDetailsTable extends Migration
+{
+	public function up()
+	{
+		Schema::create('owner_sundry_fee_details', function(Blueprint $table) {
+            $table->increments('id');
+            $table->integer('owner_id')->comment('货主ID');
+            $table->integer('type')->unsigned()->comment('作业类型');
+            $table->string('fee_explain')->nullable()->comment('费用描述');
+            $table->string('remark')->nullable()->comment('备注');
+            $table->decimal('fee')->default(0)->comment('收费金额');
+            $table->integer('changable')->unsigned()->default(1)->comment('冻结状态');
+            $table->softDeletes();
+            $table->timestamps();
+        });
+	}
+
+	public function down()
+	{
+		Schema::drop('owner_sundry_fee_details');
+	}
+}

+ 39 - 0
database/migrations/2021_05_27_105155_add_authority_settlement_bills.php

@@ -0,0 +1,39 @@
+<?php
+
+use App\Authority;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddAuthoritySettlementBills extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+//        Authority::query()->firstOrCreate(["name" => "结算管理-结算账单"],["alias_name"=>"结算管理-结算账单"]);
+//        Authority::query()->firstOrCreate(["name" => "结算管理-结算账单-杂项费"],["alias_name"=>"结算管理-结算账单-杂项费"]);
+
+        Authority::query()->firstOrCreate(["name" => "项目管理-杂项费-查询"],["alias_name"=>"项目管理-杂项费-查询"]);
+        Authority::query()->firstOrCreate(["name" => "项目管理-杂项费-录入"],["alias_name"=>"项目管理-杂项费-录入"]);
+        Authority::query()->firstOrCreate(["name" => "项目管理-杂项费-编辑"],["alias_name"=>"项目管理-杂项费-编辑"]);
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+//        Authority::query()->where('name', '结算管理-结算账单')->delete();
+//        Authority::query()->where('name', '结算管理-结算账单-杂项费')->delete();
+
+        Authority::query()->where('name', '项目管理-杂项费-查询')->delete();
+        Authority::query()->where('name', '项目管理-杂项费-录入')->delete();
+        Authority::query()->where('name', '项目管理-杂项费-编辑')->delete();
+    }
+}

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

@@ -2,8 +2,6 @@
 
 use App\StationType;
 use Illuminate\Database\Migrations\Migration;
-use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Support\Facades\Schema;
 
 class CreateStationTypes2Table extends Migration
 {

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

@@ -0,0 +1,28 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddAuthorityDeliveryAppointmentTableSignIdData extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        \App\Authority::query()->firstOrCreate(["name" => "入库管理-入库预约-预约管理-签到"],["name" => "入库管理-入库预约-预约管理-签到","alias_name"=>"入库管理-入库预约-预约管理-签到"]);
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        \App\Authority::query()->where('name', '入库管理-入库预约-预约管理-签到')->delete();
+    }
+}

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

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateOrderPackageReceivedSyncRecordsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('order_package_received_sync_records', function (Blueprint $table) {
+            $table->id();
+            $table->string('logistic_name')->comment('承运商名称');
+            $table->date('recorded_at')->comment('归档日期');
+            $table->integer('succeed_count')->unsigned()->default(0)->comment('成功计数');
+            $table->integer('failed_count')->unsigned()->default(0)->comment('失败计数');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('order_package_received_sync_records');
+    }
+}

+ 44 - 0
database/migrations/2021_06_02_114506_change_storages_table.php

@@ -0,0 +1,44 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangeStoragesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::dropIfExists('storages');
+        Schema::create('storages', function (Blueprint $table) {
+            $table->id();
+            $table->bigInteger("station_id")->index()->comment("外键库位");
+            $table->bigInteger("material_box_id")->nullable()->index()->comment("外键料箱");
+            $table->bigInteger("commodity_id")->nullable()->index()->comment("外键商品");
+            $table->integer("amount")->default(0)->comment("数量");
+            $table->tinyInteger("status")->default(0)->comment("状态");
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('storages');
+        Schema::create('storages', function (Blueprint $table) {
+            $table->id();
+            $table->bigInteger("material_box_id")->index()->comment("外键料箱");
+            $table->bigInteger("commodity_id")->nullable()->index()->comment("外键商品");
+            $table->integer("amount")->default(0)->comment("数量");
+            $table->timestamps();
+        });
+    }
+}

+ 24 - 0
database/seeds/OrderPackageReceivedSyncRecordSeeder.php

@@ -0,0 +1,24 @@
+<?php
+
+use Illuminate\Database\Seeder;
+
+class OrderPackageReceivedSyncRecordSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     * @return void
+     */
+    public function run()
+    {
+        $logistic_names = ['中通', '顺丰', '韵达', '圆通', '其他'];
+        $recorded_ats = now()->subMonth()->daysUntil(now());
+        foreach ($recorded_ats as $recorded_at) {
+            foreach ($logistic_names as $logistic_name) {
+                factory(\App\OrderPackageReceivedSyncRecord::class)->create([
+                    'recorded_at' => $recorded_at->toDateString(),
+                    'logistic_name' => $logistic_name,
+                ]);
+            }
+        }
+    }
+}

+ 20 - 0
database/seeds/OwnerSundryFeeDetailsTableSeeder.php

@@ -0,0 +1,20 @@
+<?php
+
+use Illuminate\Database\Seeder;
+use App\OwnerSundryFeeDetail;
+
+class OwnerSundryFeeDetailsTableSeeder extends Seeder
+{
+    public function run()
+    {
+        $owner_sundry_fee_details = factory(OwnerSundryFeeDetail::class)->times(50)->make()->each(function ($owner_sundry_fee_detail, $index) {
+            if ($index == 0) {
+                // $owner_sundry_fee_detail->field = 'value';
+            }
+        });
+
+        OwnerSundryFeeDetail::insert($owner_sundry_fee_details->toArray());
+    }
+
+}
+

+ 23 - 0
package-lock.json

@@ -2931,6 +2931,21 @@
         "timsort": "^0.3.0"
       }
     },
+    "css-line-break": {
+      "version": "1.1.1",
+      "resolved": "https://registry.nlark.com/css-line-break/download/css-line-break-1.1.1.tgz",
+      "integrity": "sha1-1em90peEAJnrBQPHMQ/TSSegJu8=",
+      "requires": {
+        "base64-arraybuffer": "^0.2.0"
+      },
+      "dependencies": {
+        "base64-arraybuffer": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npm.taobao.org/base64-arraybuffer/download/base64-arraybuffer-0.2.0.tgz",
+          "integrity": "sha1-S5RPrAGRqlkHr+LYyZnMxXzoD0U="
+        }
+      }
+    },
     "css-loader": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz",
@@ -4739,6 +4754,14 @@
         "uglify-js": "3.4.x"
       }
     },
+    "html2canvas": {
+      "version": "1.0.0-rc.7",
+      "resolved": "https://registry.npm.taobao.org/html2canvas/download/html2canvas-1.0.0-rc.7.tgz",
+      "integrity": "sha1-cMFZzg5jlUqRFpUxiU0IrVYnrJg=",
+      "requires": {
+        "css-line-break": "1.1.1"
+      }
+    },
     "http-deceiver": {
       "version": "1.2.7",
       "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",

+ 1 - 1
public/t.php

@@ -1,4 +1,4 @@
 <?php
 
 $a=[];
-var_dump();
+var_dump(111);

+ 1 - 1
resources/js/utilities/html2canvas.js

@@ -8,4 +8,4 @@ window.canvasImg = function(dom,imageDiv,scale=1,func){
     }).then(canvas=>{
         func(canvas);
     });
-}
+};

+ 4 - 2
resources/js/utilities/tempTip.js

@@ -117,9 +117,11 @@ const tempTip={
         $('body').append(tiper);
         $input.focus()
     },
-    postBasicRequest(url, params, successExe, isPriority = false) {
+    postBasicRequest(url, params, successExe, isPriority = false, isMultipart = false) {
         if (isPriority)this.setIndex(1099);
-        window.axios.post(url,params).then(res=> {
+        let header = {};
+        if (isMultipart)header = {'Content-Type': 'multipart/form-data'};
+        window.axios.post(url,params,header).then(res=> {
             if (res.data.success){
                 let successMsg = successExe(res.data.data);
                 if (successMsg){

+ 90 - 1
resources/views/control/panel.blade.php

@@ -364,6 +364,7 @@
                     </div>
                 </div>
                 @endcan
+                {{--异常分布图--}}
                 <div class="col-6">
                     <div class="card">
                         <div class="card-header">
@@ -392,7 +393,32 @@
                     </div>
                 </div>
             </div>
-
+            <div class="row my-3">
+                {{--快递接口请求成功失败统计图--}}
+                <div class="col-6">
+                    <div class="card">
+                        <div class="card-header">
+                            <div class="row">
+                                <el-date-picker size="small" class="col-6 date" @blur="loadOrderPackageReceivedSyncRecordInfo()"
+                                                type="daterange" align="right"
+                                                v-model="searchOption.OrderPackageReceivedSyncRecordDate" unlink-panels range-separator="-"
+                                                start-placeholder="开始日期" end-placeholder="结束日期"
+                                                value-format="yyyy-MM-dd">
+                                </el-date-picker>
+                                <label class="col-3 offset-3">
+                                    <select class="form-control rounded" v-model="searchOption.OrderPackageReceivedSyncRecordSelect"
+                                            @change="switchOrderPackageReceivedSyncRecordDate()">
+                                        <option v-for="(date,i) in dateOptions" :value="i">@{{ date.text }}</option>
+                                    </select>
+                                </label>
+                            </div>
+                        </div>
+                        <div class="card-body row">
+                            <div id="orderPackageReceivedSyncRecord" class="col-12" style="min-height: 500px"></div>
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
 @endsection
@@ -513,6 +539,8 @@
                     exceptionTypeDate: [],
                     weightSelect:"",
                     exceptionTypeSelect:"",
+                    OrderPackageReceivedSyncRecordDate: [],
+                    OrderPackageReceivedSyncRecordSelect:"",
                 },
             },
             watch:{
@@ -537,8 +565,10 @@
                 $('#list').removeClass('d-none');
                 let index = 4;
                 this.searchOption.weightSelect = index;
+                this.searchOption.OrderPackageReceivedSyncRecordSelect = 2;
                 this.searchOption.exceptionTypeSelect = index;
                 this.searchOption.weightDate = [this.dateOptions[index].start, this.dateOptions[index].end];
+                this.searchOption.OrderPackageReceivedSyncRecordDate = [this.dateOptions[2].start, this.dateOptions[2].end];
                 this.searchOption.exceptionTypeDate = [this.dateOptions[index].start, this.dateOptions[index].end];
                 let _this = this;
                 this.warehousesOrders.forEach(function (item) {
@@ -576,6 +606,8 @@
                 this.cardPool.weight = echarts.init(document.getElementById("weight"));
                 this.loadWeightInfo();
                 @endcan
+                this.cardPool.orderPackageReceivedSyncRecord = echarts.init(document.getElementById("orderPackageReceivedSyncRecord"));
+                this.loadOrderPackageReceivedSyncRecordInfo();
                 this.cardPool.exceptionType = echarts.init(document.getElementById("exceptionType"));
                 this.loadExceptionTypeInfo();
             },
@@ -933,6 +965,24 @@
                         this.cardPool.weight.setOption(this._setWeightData(res.title,res.data));
                     });
                 },
+                loadOrderPackageReceivedSyncRecordInfo(){
+                    window.tempTip.setDuration(3000);
+                    if (!this.searchOption.OrderPackageReceivedSyncRecordDate[0]){
+                        window.tempTip.show("开始时间未选择");
+                        return;
+                    }
+                    if (!this.searchOption.OrderPackageReceivedSyncRecordDate[1]){
+                        window.tempTip.show("结束时间未选择");
+                        return;
+                    }
+                    this.cardPool.orderPackageReceivedSyncRecord.showLoading('default',{text:"加 载 中",color:'#C0C0C0'});
+                    let url = "{{url('apiLocal/control/panel/menu/orderPackageReceivedSyncRecordApi')}}";
+                    let params = {start:this.searchOption.OrderPackageReceivedSyncRecordDate[0],end:this.searchOption.OrderPackageReceivedSyncRecordDate[1]};
+                    window.tempTip.postBasicRequest(url,params,res=>{
+                        this.cardPool.orderPackageReceivedSyncRecord.hideLoading();
+                        this.cardPool.orderPackageReceivedSyncRecord.setOption(this._setOrderPackageReceivedSyncRecordData(res.title, res.data));
+                    });
+                },
                 loadExceptionTypeInfo() {
                     window.tempTip.setDuration(3000);
                     if (!this.searchOption.exceptionTypeDate[0]){
@@ -956,6 +1006,11 @@
                     this.searchOption.weightDate = [obj.start,obj.end];
                     this.loadWeightInfo();
                 },
+                switchOrderPackageReceivedSyncRecordDate(){
+                    let obj = this.dateOptions[this.searchOption.OrderPackageReceivedSyncRecordSelect];
+                    this.searchOption.OrderPackageReceivedSyncRecordDate = [obj.start,obj.end];
+                    this.loadOrderPackageReceivedSyncRecordInfo();
+                },
                 switchExceptionTypeDate(){
                     let obj = this.dateOptions[this.searchOption.exceptionTypeSelect];
                     this.searchOption.exceptionTypeDate = [obj.start,obj.end];
@@ -995,6 +1050,40 @@
                         }]
                     };
                 },
+                _setOrderPackageReceivedSyncRecordData(title,data){
+                    return {
+                        title: {
+                            text: '快递信息同步成功失败占比',
+                            left: 'left'
+                        },
+                        tooltip: {
+                            trigger: 'item',
+                            formatter: function (params) {
+                                return params.data.date + "<br>" + "总量:<span class='text-success font-weight-bold'>" + params.data.total + "</span><br>" + "成功:<span class='text-info font-weight-bold'>" + params.data.count + "</span><br>"+ "承运商:<span class='text-info font-weight-bold'>" + params.data.logistic_name + "</span>";
+                            }
+                        }, xAxis: {
+                            data: title
+                        }, yAxis: {
+                            axisLabel: {
+                                show: true,
+                                interval: 'auto',
+                                formatter: '{value} %'
+                            },
+                            max: 100
+                        }, label: {
+                            show: true,
+                            position: 'top',
+                            formatter: '{c}%',
+                            color: "red"
+                        }, series: [{
+                            type: "bar",
+                            data: data,
+                            itemStyle: {
+                                color: "RGB(62,157,231)",
+                            }
+                        }]
+                    };
+                },
                 _setExceptionTypeData(data) {
                     let resData = [];
                     data.forEach(item => {

+ 4 - 0
resources/views/customer/menu.blade.php

@@ -15,6 +15,10 @@
                 <a target="customer/relating" class="nav-link" href="{{url('customer/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
             </li>
                 @endcan
+            @can('项目管理-杂项费-查询')
+                <li class="nav-item">
+                    <a target="customer/ownerSundryFeeDetails" class="nav-link" href="{{url('customer/ownerSundryFeeDetails')}}" :class="{active:isActive('ownerSundryFeeDetails',2)}">杂项费</a>
+                </li>@endcan
         </ul>
     </div>
 </div>

+ 67 - 0
resources/views/customer/ownerSundryFee/create_and_edit.blade.php

@@ -0,0 +1,67 @@
+@extends('layouts.app')
+
+@section('content')
+    @component("customer.ownerSundryFee.menu")@endcomponent
+
+<div class="container">
+  <div class="col-md-10 offset-md-1">
+    <div class="card ">
+      <div class="card-body">
+        @if($owner_sundry_fee_detail->id)
+          <form action="{{ route('ownerSundryFeeDetails.update', $owner_sundry_fee_detail->id) }}" method="POST" accept-charset="UTF-8">
+          <input type="hidden" name="_method" value="PUT">
+        @else
+          <form action="{{ route('ownerSundryFeeDetails.store') }}" method="POST" accept-charset="UTF-8">
+        @endif
+      @include('shared._error')
+
+          <input type="hidden" name="_token" value="{{ csrf_token() }}">
+                <div class="form-group">
+                    <label for="fee_explain-field">作业类型</label>
+                    <select class="form-control" name="type" required>
+                        <option value="" hidden disabled {{ $owner_sundry_fee_detail->id ? '' : 'selected' }}>请选择作业类型</option>
+                        @foreach ($types as $value)
+                            <option value="{{ $value }}" {{ $owner_sundry_fee_detail->type == $value ? 'selected' : '' }}>
+                                {{ $value }}
+                            </option>
+                        @endforeach
+                    </select>
+                </div>
+              <div class="form-group">
+                  <label for="fee_explain-field">货主</label>
+                  <select class="form-control" name="owner_id" required>
+                      <option value="" hidden disabled {{ $owner_sundry_fee_detail->id ? '' : 'selected' }}>请选择货主</option>
+                      @foreach ($owners as $value)
+                          <option value="{{ $value->id }}" {{ $owner_sundry_fee_detail->owner_id == $value->id ? 'selected' : '' }}>
+                              {{ $value->name }}
+                          </option>
+                      @endforeach
+                  </select>
+              </div>
+                <div class="form-group">
+                	<label for="fee_explain-field">费用描述</label>
+                	<input class="form-control" type="text" name="fee_explain" id="fee_explain-field" value="{{ old('fee_explain', $owner_sundry_fee_detail->fee_explain ) }}" />
+                </div>
+                <div class="form-group">
+                	<label for="remark-field">备注</label>
+                	<input class="form-control" type="text" name="remark" id="remark-field" value="{{ old('remark', $owner_sundry_fee_detail->remark ) }}" />
+                </div>
+                <div class="form-group">
+                    <label for="fee-field">收费金额</label>
+                    <input class="form-control" type="number" name="fee" id="fee-field" value="{{ old('fee', $owner_sundry_fee_detail->fee ) }}" />
+                </div>
+{{--                <div class="form-group">--}}
+{{--                    <label for="changable-field">Changable</label>--}}
+{{--                    <input class="form-control" type="text" name="changable" id="changable-field" value="{{ old('changable', $owner_sundry_fee_detail->changable ) }}" />--}}
+{{--                </div>--}}
+          <div class="well well-sm">
+            <button type="submit" class="btn btn-primary">保存</button>
+            <a class="btn btn-link float-xs-right" href="{{ route('ownerSundryFeeDetails.index') }}"> <- 返回</a>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</div>
+
+@endsection

+ 117 - 0
resources/views/customer/ownerSundryFee/index.blade.php

@@ -0,0 +1,117 @@
+@extends('layouts.app')
+
+@section('content')
+    @component("customer.ownerSundryFee.menu")@endcomponent
+    @include('shared._messages')
+    @include('shared._error')
+    <div id="list" class="d-none">
+        <div class="container-fluid">
+            <div id="form_div"></div>
+            <div class="form-inline" id="btn"></div>
+            <table class="table table-striped table-sm text-nowrap table-hover" id="table">
+                <tr v-for="(owner_sundry_fee_detail,i) in owner_sundry_fee_details"
+                    @click="selectTr===i+1?selectTr=0:selectTr=i+1"
+                    :class="selectTr===i+1?'focusing' : ''">
+                    <td><input class="checkItem" type="checkbox" :value="owner_sundry_fee_detail.id"></td>
+                    <td>@{{ i+1 }}</td>
+                    <td>@{{ owner_sundry_fee_detail.owner.name }}</td>
+                    <td>@{{ owner_sundry_fee_detail.created_at }}</td>
+                    <td>@{{ owner_sundry_fee_detail.type }}</td>
+                    <td>@{{ owner_sundry_fee_detail.fee_explain }}</td>
+                    <td>@{{ owner_sundry_fee_detail.fee }}</td>
+                    <td>@{{ owner_sundry_fee_detail.remark }}</td>
+                    <td>
+                        @can('项目管理-杂项费-编辑')
+                            <button @click="edit(owner_sundry_fee_detail.id)" type="button"
+                                    class="btn btn-outline-primary btn-sm">改
+                            </button>
+
+                            <form :action="targetUrl(owner_sundry_fee_detail.id)" method="post"
+                                  style="display: inline-block;"
+                                  onsubmit="return confirm('您确定要删除吗?');">
+                                {{ csrf_field() }}
+                                {{ method_field('DELETE') }}
+                                <button type="submit" class="btn btn-outline-danger btn-sm">
+                                    <i class="far fa-trash-alt"></i> 删
+                                </button>
+                            </form>
+                        @endcan
+                    </td>
+                </tr>
+            </table>
+            <div class="text-info h5 btn btn">{{$owner_sundry_fee_details->count()}}
+                /{{$owner_sundry_fee_details->total()}}</div>
+            {{$owner_sundry_fee_details->appends($paginateParams)->links()}}
+        </div>
+        <textarea id="clipboardDiv" style="opacity:0"></textarea>
+    </div>
+@endsection
+@section('lastScript')
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>{{--新版2--}}
+    <script>
+        let vue = new Vue({
+            el: "#list",
+            data: {
+                owner_sundry_fee_details: [
+                    @foreach($owner_sundry_fee_details as $owner_sundry_fee_detail)
+                        {!! $owner_sundry_fee_detail !!},
+                    @endforeach
+                ],
+                owners: [@foreach($owners as $owner){name: '{{ $owner->id }}', value: '{{ $owner->name}}'},@endforeach],
+                selectTr: 0,
+            },
+            created() {
+            },
+            mounted() {
+                $('#list').removeClass('d-none');
+                let _this = this;
+                $(".up").slideUp();
+                let data = [
+                    [
+                        {
+                            name: 'owner_id',
+                            type: 'select_multiple_select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的客户'],
+                            placeholder: ['货主', '定位或多选货主'],
+                            data: _this.owners
+                        },
+                    ]
+                ];
+                _this.form = new query({
+                    el: '#form_div',
+                    condition: data,
+                });
+                _this.form.init();
+                let column = [
+                    {name: 'index', value: '序号', neglect: true},
+                    {name: 'owner', value: '货主'},
+                    {name: 'created_at', value: '日期'},
+                    {name: 'type', value: '作业类型'},
+                    {name: 'fee_explain', value: '费用描述'},
+                    {name: 'fee', value: '收费金额'},
+                    {name: 'remark', value: '备注'},
+                    {name: 'operation', value: '操作'},
+                ];
+                new Header({
+                    el: "table",
+                    name: "owner_sundry_fee_detail",
+                    column: column,
+                    data: this.owner_sundry_fee_details,
+                    restorationColumn: 'addtime',
+                    fixedTop: ($('#form_div').height()) + ($('#btn').height()) + 1,
+                }).init();
+            },
+            methods: {
+                edit(id) {
+                    location.href = "{{url('customer/ownerSundryFeeDetails')}}/" + id + "/edit";
+                },
+                targetUrl(id) {
+                    return "{{ url('customer/ownerSundryFeeDetails') }}/" + id;
+                }
+            },
+            filters: {},
+        });
+    </script>
+@endsection

+ 30 - 0
resources/views/customer/ownerSundryFee/menu.blade.php

@@ -0,0 +1,30 @@
+<div id="nav2">
+    @component('customer.menu')@endcomponent
+    <div class="container-fluid nav3">
+        <div class="card menu-third">
+            <ul class="nav nav-pills">
+                @can('项目管理-杂项费-查询')
+                    <li class="nav-item">
+                        <a target="customer/ownerSundryFee" class="nav-link"
+                           href="{{url('customer/ownerSundryFeeDetails')}}"
+                           :class="{active:isActive('',3)}">查询</a>
+                    </li>
+                @endcan
+                @can('项目管理-杂项费-录入')
+                    <li class="nav-item">
+                        <a target="customer/ownerSundryFee/create" class="nav-link"
+                           href="{{url('customer/ownerSundryFeeDetails/create')}}"
+                           :class="{active:isActive('create',3)}">录入</a>
+                    </li>
+                @endcan
+{{--                @can('项目管理-杂项费-编辑')--}}
+{{--                    <li class="nav-item">--}}
+{{--                        <a target="customer/ownerSundryFee/edit" class="nav-link"--}}
+{{--                           href="{{url('customer/ownerSundryFeeDetails/{ownerSundryFeeDetail}/edit')}}"--}}
+{{--                           :class="{active:isActive('edit',4)}">编辑</a>--}}
+{{--                    </li>--}}
+{{--                @endcan--}}
+            </ul>
+        </div>
+    </div>
+</div>

+ 44 - 0
resources/views/customer/ownerSundryFee/show.blade.php

@@ -0,0 +1,44 @@
+@extends('layouts.app')
+@section('content')
+    @component("customer.ownerSundryFee.menu")@endcomponent
+    <div class="container">
+        <div class="col-md-10 offset-md-1">
+            <div class="card ">
+                <div class="card-body">
+                    <div class="card-block bg-light">
+                        <div class="row">
+                            <div class="col-md-6">
+                                <a class="btn btn-link" href="{{ route('ownerSundryFeeDetails.index') }}"><- Back</a>
+                            </div>
+                            <div class="col-md-6">
+                                <a class="btn btn-sm btn-warning float-right mt-1"
+                                   href="{{ route('ownerSundryFeeDetails.edit', $owner_sundry_fee_detail->id) }}">
+                                    Edit
+                                </a>
+                            </div>
+                        </div>
+                    </div>
+                    <br>
+
+                    <label>Type</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->type }}
+                    </p> <label>Fee_explain</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->fee_explain }}
+                    </p> <label>Remark</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->remark }}
+                    </p> <label>Fee</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->fee }}
+                    </p> <label>Changable</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->changable }}
+                    </p>
+                </div>
+            </div>
+        </div>
+    </div>
+
+@endsection

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

@@ -892,6 +892,13 @@
                         this.$set(this.errors,"surcharge_unit_id",["耗材附加费未填写"]);
                         return;
                     }
+                    let unit = this.model.operation.items[0].unit_id;
+                    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.isSingle){
                         for (let i=0;i<this.model.operation.items.length;i++){
                             if (this._verifyOperationItem(i))return;
@@ -1915,7 +1922,8 @@
                 //开启满减
                 onDiscount(type){
                   if (!type)return;
-                  if (this.model.operation.discount_count.length===0) this.model.operation.discount_count = [""];
+                  if (this.model.operation.discount_count.length===1) this.model.operation.discount_count = ["0"];
+                  if (this.model.operation.discount_count.length===0) this.model.operation.discount_count = ["0"];
                 },
                 //删除阶梯满减阈值
                 delDiscount(index){

+ 4 - 1
resources/views/customer/project/part/_auditComparison.blade.php

@@ -61,10 +61,13 @@
                                     <td>@{{ s.unit_id }}</td>
                                     <td>@{{ s.time_unit_id }}</td>
                                     <td>
-                                        <div class="float-left small">
+                                        <div class="float-left small" v-if="s.amount_interval">
                                             <span v-for="(a,i) in s.amount_interval" v-if="i!=s.amount_interval.length-1">@{{ a }}-@{{ s.amount_interval[i+1] }}(@{{ s.price[i] }}元)<br></span>
                                             <span>@{{ s.amount_interval[s.amount_interval.length-1] }}&nbsp;+(@{{ s.price[s.amount_interval.length-1] }}元)<br></span>
                                         </div>
+                                        <div v-else>
+                                            @{{ s.price[0] }}元
+                                        </div>
                                     </td>
                                     <td>@{{ s.tax_rate_id }}</td>
                                 </tr>

+ 6 - 6
resources/views/customer/project/part/_operation.blade.php

@@ -45,7 +45,7 @@
     <div class="col-8 row" v-if="model.operation.isDiscount">
         <div class="col-1 cursor-pointer"><span class="fa fa-plus" @click="addDiscount(model.operation.discount_count)"></span></div>
         <label class="col-2" for="discount">满减阈值</label>
-        <input id="discount" v-model="model.operation.discount_count[0]" :class="errors['discount_count_0'] ? 'is-invalid' : ''"
+        <input disabled id="discount" :value="model.operation.discount_count[0]" :class="errors['discount_count_0'] ? 'is-invalid' : ''"
                class="form-control form-control-sm col-6" step="1" type="number" min="0">
     </div>
 </div>
@@ -76,7 +76,7 @@
         <label class="col-3" for="total_discount_price">满减价</label>
         <input id="total_discount_price" v-model="model.operation.total_discount_price[i]"
                class="form-control form-control-sm col-5" :class="errors.total_discount_price ? 'is-invalid' : ''" step="0.01" type="number" min="0">
-        <label class="col-4 text-secondary">@{{ value ? (model.operation.discount_count[i+1] ? value+'-'+(model.operation.discount_count[i+1]-1)+' 单' : value+'+ 单') : '' }}</label>
+        <label class="col-4 text-secondary">@{{ value ? (model.operation.discount_count[i+1] ? value+'-'+(model.operation.discount_count[i+1]-1)+' '+(model.operation.operation_type=='入库' ? '件' : '')+'/月' : value+'+ '+(model.operation.operation_type=='入库' ? '件' : '')+'/月') : '' }}</label>
     </div>
 </div>
 <div class="row mt-3">
@@ -125,7 +125,7 @@
             <div class="row mt-2" v-if="item.strategy!='起步' || (item.strategy=='起步' && item.type==0)">
                 <label class="col-3">单位</label>
                 <label class="col-3 mb-0"><select v-model="item.unit_id" class="form-control" :class="errors['items.'+i+'.unit_id'] ? 'is-invalid' : ''">
-                    <option v-for="unit in pool.units" :value="unit.id" v-if="unit.name=='件' || unit.name=='箱'">@{{ unit.name }}</option>
+                    <option v-for="unit in pool.units" :value="unit.id" v-if="unit.name=='件' || unit.name=='箱' || unit.name=='m³' || unit.name=='T' || unit.name=='kg'">@{{ unit.name }}</option>
                 </select></label>
                 <label class="col-2 text-right" v-if="poolMapping.units[item.unit_id]=='箱'">零头价</label>
                 <label class="col-3 mb-0" v-if="poolMapping.units[item.unit_id]=='箱'">
@@ -133,9 +133,9 @@
                 </label>
             </div>
             <div class="row mt-0" v-if="errors['items.'+i+'.unit_id']">
-                <div class="offset-3"><small class="text-danger font-weight-bold ml-3">单位为必选项</small></div>
+                <div class="offset-3"><small class="text-danger font-weight-bold ml-3">@{{ errors['items.'+i+'.unit_id'][0] }}</small></div>
             </div>
-            <div class="row mt-2" v-if="item.strategy!='起步' || (item.strategy=='起步' && item.type==0)">
+            <div class="row mt-2" v-if="item.strategy!='起步' || (item.strategy=='起步' && item.type==0)" v-show="!model.operation.isDiscount">
                 <label class="col-3"><span v-if="item.strategy=='起步'">起步费</span><span v-else>单价</span></label>
                 <label class="col-6 mb-0 input-group">
                     <input type="number" min="0" step="0.01" class="form-control" v-model="item.unit_price"
@@ -157,7 +157,7 @@
                           <span class="input-group-text">元</span>
                     </span>
                 </label>
-                <label class="col-4">@{{ value ? (model.operation.discount_count[i+1] ? value+'-'+(model.operation.discount_count[i+1]-1)+' 单' : value+'+ 单') : '' }}</label>
+                <label class="col-4">@{{ value ? (model.operation.discount_count[i+1] ? value+'-'+(model.operation.discount_count[i+1]-1)+' '+(model.operation.operation_type=='入库' ? '件' : '')+'/月' : value+'+ '+(model.operation.operation_type=='入库' ? '件' : '')+'/月') : '' }}</label>
             </div>
             <div class="row mt-2" v-if="item.strategy=='特征'">
                 <label class="col-3">特征:</label>

+ 4 - 0
resources/views/finance/menu.blade.php

@@ -9,6 +9,10 @@
             <li class="nav-item">
                 <a target="finance/billConfirmation" class="nav-link" href="{{url('finance/billConfirmation')}}" :class="{active:isActive('billConfirmation',2)}">账单确认</a>
             </li>@endcan
+{{--            @can('结算管理-结算账单')--}}
+{{--                <li class="nav-item">--}}
+{{--                    <a target="finance/settlementBills" class="nav-link" href="{{url('finance/settlementBills/ownerSundryFeeDetails')}}" :class="{active:isActive('settlementBills',2)}">结算账单</a>--}}
+{{--                </li>@endcan--}}
         </ul>
     </div>
 </div>

+ 14 - 0
resources/views/finance/settlementBills/menu.blade.php

@@ -0,0 +1,14 @@
+<div id="nav2">
+    @component('finance.menu')@endcomponent
+    <div class="container-fluid nav3">
+        <div class="card menu-third">
+            <ul class="nav nav-pills">
+                @can('结算管理-结算账单-杂项费')
+                    <li class="nav-item" >
+                        <a target="finance/settlementBills/ownerSundryFeeDetails" class="nav-link" href="{{url('finance/settlementBills/ownerSundryFeeDetails')}}" :class="{active:isActive('ownerSundryFeeDetails',3)}">杂项费</a>
+                    </li>
+                @endcan
+            </ul>
+        </div>
+    </div>
+</div>

+ 65 - 0
resources/views/finance/settlementBills/ownerSundryFee/create_and_edit.blade.php

@@ -0,0 +1,65 @@
+@extends('layouts.app')
+
+@section('content')
+    @component("finance.settlementBills.ownerSundryFee.menu")@endcomponent
+
+<div class="container">
+  <div class="col-md-10 offset-md-1">
+    <div class="card ">
+      <div class="card-body">
+        @if($owner_sundry_fee_detail->id)
+          <form action="{{ route('ownerSundryFeeDetails.update', $owner_sundry_fee_detail->id) }}" method="POST" accept-charset="UTF-8">
+          <input type="hidden" name="_method" value="PUT">
+        @else
+          <form action="{{ route('ownerSundryFeeDetails.store') }}" method="POST" accept-charset="UTF-8">
+        @endif
+      @include('shared._error')
+
+          <input type="hidden" name="_token" value="{{ csrf_token() }}">
+                <div class="form-group">
+                    <select class="form-control" name="type" required>
+                        <option value="" hidden disabled {{ $owner_sundry_fee_detail->id ? '' : 'selected' }}>请选择分类</option>
+                        @foreach ($types as $value)
+                            <option value="{{ $value }}" {{ $owner_sundry_fee_detail->type == $value ? 'selected' : '' }}>
+                                {{ $value }}
+                            </option>
+                        @endforeach
+                    </select>
+                </div>
+              <div class="form-group">
+                  <select class="form-control" name="owner_id" required>
+                      <option value="" hidden disabled {{ $owner_sundry_fee_detail->id ? '' : 'selected' }}>请选择货主</option>
+                      @foreach ($owners as $value)
+                          <option value="{{ $value->id }}" {{ $owner_sundry_fee_detail->owner_id == $value->id ? 'selected' : '' }}>
+                              {{ $value->name }}
+                          </option>
+                      @endforeach
+                  </select>
+              </div>
+                <div class="form-group">
+                	<label for="fee_explain-field">费用描述</label>
+                	<input class="form-control" type="text" name="fee_explain" id="fee_explain-field" value="{{ old('fee_explain', $owner_sundry_fee_detail->fee_explain ) }}" />
+                </div>
+                <div class="form-group">
+                	<label for="remark-field">备注</label>
+                	<input class="form-control" type="text" name="remark" id="remark-field" value="{{ old('remark', $owner_sundry_fee_detail->remark ) }}" />
+                </div>
+                <div class="form-group">
+                    <label for="fee-field">收费金额</label>
+                    <input class="form-control" type="number" name="fee" id="fee-field" value="{{ old('fee', $owner_sundry_fee_detail->fee ) }}" />
+                </div>
+{{--                <div class="form-group">--}}
+{{--                    <label for="changable-field">Changable</label>--}}
+{{--                    <input class="form-control" type="text" name="changable" id="changable-field" value="{{ old('changable', $owner_sundry_fee_detail->changable ) }}" />--}}
+{{--                </div>--}}
+          <div class="well well-sm">
+            <button type="submit" class="btn btn-primary">保存</button>
+            <a class="btn btn-link float-xs-right" href="{{ route('ownerSundryFeeDetails.index') }}"> <- 返回</a>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</div>
+
+@endsection

+ 105 - 0
resources/views/finance/settlementBills/ownerSundryFee/index.blade.php

@@ -0,0 +1,105 @@
+@extends('layouts.app')
+
+@section('content')
+    @component("finance.settlementBills.ownerSundryFee.menu")@endcomponent
+    @include('shared._messages')
+    @include('shared._error')
+    <div id="list" class="d-none">
+        <div class="container-fluid">
+            <div id="form_div"></div>
+            <div class="form-inline" id="btn"></div>
+            <table class="table table-striped table-sm text-nowrap table-hover" id="table">
+                <tr v-for="(owner_sundry_fee_detail,i) in owner_sundry_fee_details"
+                    @click="selectTr===i+1?selectTr=0:selectTr=i+1"
+                    :class="selectTr===i+1?'focusing' : ''">
+                    <td><input class="checkItem" type="checkbox" :value="owner_sundry_fee_detail.id"></td>
+                    <td>@{{ i+1 }}</td>
+                    <td>@{{ owner_sundry_fee_detail.owner.name }}</td>
+                    <td>@{{ owner_sundry_fee_detail.created_at }}</td>
+                    <td>@{{ owner_sundry_fee_detail.type }}</td>
+                    <td>@{{ owner_sundry_fee_detail.fee_explain }}</td>
+                    <td>@{{ owner_sundry_fee_detail.fee }}</td>
+                    <td>@{{ owner_sundry_fee_detail.remark }}</td>
+                    <td>
+                        <button @click="edit(owner_sundry_fee_detail.id)" type="button"
+                                class="btn btn-outline-primary btn-sm">改
+                        </button>
+                        <form :action="targetUrl(owner_sundry_fee_detail.id)" method="post"
+                              style="display: inline-block;"
+                              onsubmit="return confirm('您确定要删除吗?');">
+                            {{ csrf_field() }}
+                            {{ method_field('DELETE') }}
+                            <button type="submit" class="btn btn-outline-danger btn-sm">
+                                <i class="far fa-trash-alt"></i> 删
+                            </button>
+                        </form>
+                    </td>
+                </tr>
+            </table>
+            <div class="text-info h5 btn btn">{{$owner_sundry_fee_details->count()}}
+                /{{$owner_sundry_fee_details->total()}}</div>
+            {{$owner_sundry_fee_details->appends($paginateParams)->links()}}
+        </div>
+        <textarea id="clipboardDiv" style="opacity:0"></textarea>
+    </div>
+@endsection
+@section('lastScript')
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>{{--新版2--}}
+    <script>
+        let vue = new Vue({
+            el: "#list",
+            data: {
+                owner_sundry_fee_details: [
+                    @foreach($owner_sundry_fee_details as $owner_sundry_fee_detail)
+                        {!! $owner_sundry_fee_detail !!},
+                    @endforeach
+                ],
+                selectTr: 0,
+            },
+            created() {
+            },
+            mounted() {
+                $('#list').removeClass('d-none');
+                let _this = this;
+                $(".up").slideUp();
+                let data = [
+                    []
+                ];
+                _this.form = new query({
+                    el: '#form_div',
+                    condition: data,
+                });
+                _this.form.init();
+                let column = [
+                    {name: 'index', value: '序号', neglect: true},
+                    {name: 'owner', value: '货主'},
+                    {name: 'created_at', value: '日期'},
+                    {name: 'type', value: '作业类型'},
+                    {name: 'fee_explain', value: '费用描述'},
+                    {name: 'fee', value: '收费金额'},
+                    {name: 'remark', value: '备注'},
+                    {name: 'operation', value: '操作'},
+                ];
+                new Header({
+                    el: "table",
+                    name: "owner_sundry_fee_detail",
+                    column: column,
+                    data: this.owner_sundry_fee_details,
+                    restorationColumn: 'addtime',
+                    fixedTop: ($('#form_div').height()) + ($('#btn').height()) + 1,
+                }).init();
+            },
+            methods: {
+                edit(id) {
+                    location.href = "{{url('finance/settlementBills/ownerSundryFeeDetails')}}/" + id + "/edit";
+                },
+                targetUrl(id) {
+                    return "{{ url('finance/settlementBills/ownerSundryFeeDetails') }}/" + id;
+                }
+            },
+            filters: {},
+        });
+    </script>
+@endsection

+ 26 - 0
resources/views/finance/settlementBills/ownerSundryFee/menu.blade.php

@@ -0,0 +1,26 @@
+<div id="nav2">
+    @component('finance.settlementBills.menu')@endcomponent
+    <div class="container-fluid nav4">
+        <div class="card menu-third">
+            <ul class="nav nav-pills">
+                @can('结算管理-结算账单-杂项费')
+                    <li class="nav-item">
+                        <a target="finance/settlementBills/ownerSundryFeeDetails" class="nav-link"
+                           href="{{url('finance/settlementBills/ownerSundryFeeDetails')}}"
+                           :class="{active:isActive('',4)}">查询</a>
+                    </li>
+                @endcan
+                    <li class="nav-item">
+                        <a target="finance/settlementBills/ownerSundryFeeDetails/create" class="nav-link"
+                           href="{{url('finance/settlementBills/ownerSundryFeeDetails/create')}}"
+                           :class="{active:isActive('create',4)}">新建</a>
+                    </li>
+                    <li class="nav-item">
+                        <a target="finance/settlementBills/ownerSundryFeeDetails/edit" class="nav-link"
+                           href="{{url('finance/settlementBills/ownerSundryFeeDetails/edit')}}"
+                           :class="{active:isActive('edit',4)}">编辑</a>
+                    </li>
+            </ul>
+        </div>
+    </div>
+</div>

+ 44 - 0
resources/views/finance/settlementBills/ownerSundryFee/show.blade.php

@@ -0,0 +1,44 @@
+@extends('layouts.app')
+@section('content')
+    @component("finance.settlementBills.ownerSundryFee.menu")@endcomponent
+    <div class="container">
+        <div class="col-md-10 offset-md-1">
+            <div class="card ">
+                <div class="card-body">
+                    <div class="card-block bg-light">
+                        <div class="row">
+                            <div class="col-md-6">
+                                <a class="btn btn-link" href="{{ route('ownerSundryFeeDetails.index') }}"><- Back</a>
+                            </div>
+                            <div class="col-md-6">
+                                <a class="btn btn-sm btn-warning float-right mt-1"
+                                   href="{{ route('ownerSundryFeeDetails.edit', $owner_sundry_fee_detail->id) }}">
+                                    Edit
+                                </a>
+                            </div>
+                        </div>
+                    </div>
+                    <br>
+
+                    <label>Type</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->type }}
+                    </p> <label>Fee_explain</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->fee_explain }}
+                    </p> <label>Remark</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->remark }}
+                    </p> <label>Fee</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->fee }}
+                    </p> <label>Changable</label>
+                    <p>
+                        {{ $owner_sundry_fee_detail->changable }}
+                    </p>
+                </div>
+            </div>
+        </div>
+    </div>
+
+@endsection

+ 2 - 1
resources/views/order/index/delivering.blade.php

@@ -140,7 +140,8 @@
                 </table>
                 <button type="button" @click="pageUp()" :readonly="page>1?false:true" class="btn btn-sm " :class="page>1?'btn-outline-info':''">上一页</button>
                 <button type="button" @click="pageDown()" :readonly="maxPage == 0 ? false : (page<maxPage?false:true)" class="btn btn-sm m-3" :class="maxPage == 0 ? 'btn-outline-info' : (page<maxPage?'btn-outline-info':'')">下一页</button>
-                <input  @keyup.enter="pageSkip($event)" class="form-control-sm ml-3 tooltipTarget" :placeholder="pagePlaceholder" title="去往指定页">
+                <input  @keyup.enter="pageSkip($event)" class="form-control-sm ml-3 tooltipTarget" placeholder="此处输入页数" title="去往指定页">
+                <span class="text-muted m-1">@{{ pagePlaceholder }}</span>
                 <span class="text-muted m-1" v-if="maxPage != 0">共 @{{ sum }} 条</span>
 
 

+ 4 - 3
resources/views/package/logistic/index.blade.php

@@ -8,9 +8,9 @@
     <div id="list" class="d-none">
         <div class="container-fluid">
             <div id="form_div"></div>
-            <div class="form-inline" id="btn">
+            <div class="ml-3 form-inline" id="btn">
                 @can('包裹管理-快递-异常类型-编辑')
-                    <span class="dropdown ml-1">
+                    <span class="dropdown">
                         <button type="button"
                                 class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget"
                                 data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">导出Excel
@@ -46,7 +46,7 @@
                     </span>
                 @endcan
             </div>
-            <table class="table table-striped table-sm text-nowrap table-hover" id="table">
+            <table class="table table-striped table-bordered table-hover card-body td-min-width-80" id="table">
                 <tr v-for="(package,i) in packages" @click="selectTr===i+1?selectTr=0:selectTr=i+1"
                     :class="selectTr===i+1?'focusing' : ''">
                     <td>
@@ -300,6 +300,7 @@
                 _this.form = new query({
                     el: '#form_div',
                     condition: data,
+                    appendDom : "btn",
                 });
                 _this.form.init();
                 let column = [

+ 4 - 4
resources/views/package/measureMonitor/index.blade.php

@@ -125,7 +125,7 @@
                         if (package.id ===_this.package.id){
                             _this.package.measuringMachine_status=package.measuring_machine.status;
                             _this.measuringMachinesIndex[package.measuring_machine.name].status=package.measuring_machine.status;
-                            tempTip.setDuration(4000);
+                            tempTip.setDuration(2000);
                             tempTip.showSuccess('暂无新数据');
                             return;
                         }
@@ -135,7 +135,7 @@
                             audio.src=_this.logisticAudioURL[logistic_name];
                             setTimeout(()=>{
                                 audio.play();
-                            },10);
+                            },0);
                         }else {
                             window.tempTip.setDuration(3000);
                             window.axios.post("{{url('package/weigh/measureMonitor/speech')}}",{logistic:logistic_name})
@@ -145,7 +145,7 @@
                                         audio.src=response.data;
                                         setTimeout(()=>{
                                             audio.play();
-                                        },10);
+                                        },0);
                                     }else window.tempTip.show('没有对应快递名称!');
                                 }).catch(function (err) {
                                     window.tempTip.show('语音合成发生错误:'+err);
@@ -165,7 +165,7 @@
                                 let orderPackage=response.data;
                                 _this.updateData(_this,orderPackage);
                                 _this.package.measuringMachine=orderPackage.measuring_machine ? orderPackage.measuring_machine.name : '';                            }else {
-                                tempTip.setDuration(4000);
+                                tempTip.setDuration(3000);
                                 tempTip.showSuccess('暂无数据!');
                             }
                         })

+ 7 - 1
resources/views/package/weigh/index.blade.php

@@ -86,6 +86,11 @@
                     {name:'{{$owner->id}}',value:'{{$owner->name}}'},
                     @endforeach
                 ],
+                measuringMachines:[
+                    @foreach($measuringMachines as $measuringMachine)
+                    {name:'{{$measuringMachine->id}}',value:'{{$measuringMachine->name}}'},
+                    @endforeach
+                ],
                 form:'',
                 sum:{!! $packages->total() !!},
                 selectTr:0
@@ -102,7 +107,8 @@
                     {name:'is_weighed',type:'checkbox',tip:'是否已称重', data: [{name: 'true', value: '是否已称重'}]}
                 ],[
                     {name:'weighed_at_end',type:'time',tip:['选择显示称重日期的结束时间','选择显示称重日期的结束时间']},
-                    {name:'batch_number',type:'input',tip:'可支持多波次号,糊模查找需要在右边打上%符号',placeholder:'波次号'}
+                    {name:'batch_number',type:'input',tip:'可支持多波次号,糊模查找需要在右边打上%符号',placeholder:'波次号'},
+                    {name:'measuring_machine_id',type:'select',placeholder:'设备',data:this.measuringMachines},
                 ]];
 
                 _this.form = new query({

+ 10 - 0
resources/views/shared/_error.blade.php

@@ -0,0 +1,10 @@
+@if (count($errors) > 0)
+  <div class="alert alert-danger">
+    <div class="mt-2"><b>有错误发生:</b></div>
+    <ul class="mt-2 mb-2">
+      @foreach ($errors->all() as $error)
+        <li><i class="glyphicon glyphicon-remove"></i> {{ $error }}</li>
+      @endforeach
+    </ul>
+  </div>
+@endif

+ 9 - 0
resources/views/shared/_messages.blade.php

@@ -0,0 +1,9 @@
+@foreach (['danger', 'warning', 'success', 'info'] as $msg)
+  @if(session()->has($msg))
+    <div class="flash-message">
+      <p class="alert alert-{{ $msg }}">
+        {{ session()->get($msg) }}
+      </p>
+    </div>
+  @endif
+@endforeach

+ 7 - 4
resources/views/station/monitor/show.blade.php

@@ -382,10 +382,12 @@
                     });
                 },
                 _listenTaskBroadcast(){
+                    let _this=this;
+                    console.log(this.taskBroadcastName,this.channelName);
                     window.Echo.channel(this.taskBroadcastName).listen(this.channelName,(msg)=> {
-                        console.log((new Date()).toTimeString(),msg);
-                        let json = JSON.parse(msg.json);
-                        if(!json||json.length===0)return;
+                        console.log('1:',(new Date()).toTimeString(),msg);
+                        let taskIn = JSON.parse(msg.json);
+                        if(!taskIn||taskIn.length===0)return;
                         taskIn['station_task_batches'].forEach(function(station_task_batch){
                             let taskOld=_this.stationTask_indexByBatch[station_task_batch['batch_id']];
                             if(typeof(taskOld)==='undefined')return;
@@ -401,8 +403,9 @@
                 },
                 _listenAllTaskBroadcast(){
                     let _this=this;
+                    console.log(this.allTaskBroadcastName,this.channelName);
                     window.Echo.channel(this.allTaskBroadcastName).listen(this.channelName,(msg)=> {
-                        console.log((new Date()).toTimeString(),msg);
+                        console.log('2:',(new Date()).toTimeString(),msg);
                         let stationTasksIn = JSON.parse(msg.json);
                         if(!stationTasksIn||stationTasksIn.length===0)return;
                         stationTasksIn.forEach(function(stationTaskIn){

+ 10 - 0
resources/views/store/deliveryAppointment/list.blade.php

@@ -116,6 +116,7 @@
                             <div class="col-2 text-secondary">@{{ info.cars[0].driver_phone }}</div>
                             <div class="col-3">
                                 @can("入库管理-入库预约-预约管理-卸货完成")<button class="btn btn-sm btn-outline-success" @click="unloading(i,0)" v-if="info.cars[0].status==1">卸货完成</button>@endcan
+                                @can("入库管理-入库预约-预约管理-签到")<button class="btn btn-sm btn-outline-success" @click="signIn(i,0)" v-if="info.cars[0].status==0">签到</button>@endcan
                                 <div v-if="info.cars[0].status==2">@{{ info.cars[0].delivery_time }}</div>
                             </div>
                         </div>
@@ -128,6 +129,7 @@
                                 <div class="col-2 text-secondary">@{{ car.driver_phone }}</div>
                                 <div class="col-3">
                                     @can("入库管理-入库预约-预约管理-卸货完成")<button class="btn btn-sm btn-outline-success" @click="unloading(i,j)" v-if="car.status==1">卸货完成</button>@endcan
+                                    @can("入库管理-入库预约-预约管理-签到")<button class="btn btn-sm btn-outline-success" @click="signIn(i,j)" v-if="car.status==0">签到</button>@endcan
                                     <div v-if="car.status==2">@{{ car.delivery_time }}</div>
                                 </div>
                             </div>
@@ -317,6 +319,14 @@
                         })
                     })
                 },
+                signIn(i,j){
+                    window.tempTip.confirm("确定为司机签到?",()=>{
+                        window.tempTip.postBasicRequest("{{url('store/deliveryAppointment/signIn')}}",{id:this.list[i].cars[j].id},()=>{
+                            this.list[i].cars[j].status = 1;
+                            return "成功签到";
+                        })
+                    })
+                },
                 cancel(id,index){
                     window.tempTip.confirm("确定要取消该次预约吗?此操作不可逆,请谨慎选择",()=>{
                         window.tempTip.postBasicRequest("{{url('store/deliveryAppointment/cancel')}}",{id:id},res=>{

+ 63 - 1
resources/views/store/inStorage/cacheRackStorage.blade.php

@@ -8,7 +8,7 @@
     </span>
     <div class="container-fluid" id="container">
         <div class="row">
-            <div class="card offset-md-3 col-md-6 col-sm-12">
+            <div class="card offset-md-1 col-md-5 col-sm-12">
                 <div class="card-body">
                     <div class="form-group text-center font-weight-bold h4">
                         入库信息
@@ -46,6 +46,41 @@
                     </div>
                 </div>
             </div>
+            <div class="card col-md-5 col-sm-12">
+                <div class="card-body">
+                    <div class="mt-1 text-center">
+                        <button class="btn btn-primary" @click="submitBox()">为选中格口手动补充料箱</button>
+                    </div>
+                    <div class="mt-2 h-75">
+                        <table class="table table-sm table-bordered border-dark w-100 h-100 text-center" style="cursor: pointer">
+                            <tr>
+                                <th :class="[shelfOccupy['HAIB1-03-03'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-03-03'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-03-03')">HAIB1-03-03</th>
+                                <th :class="[shelfOccupy['HAIB1-02-03'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-02-03'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-02-03')">HAIB1-02-03</th>
+                                <th :class="[shelfOccupy['HAIB1-01-03'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-01-03'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-01-03')">HAIB1-01-03</th>
+                            </tr>
+                            <tr>
+                                <th :class="[shelfOccupy['HAIB1-03-02'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-03-02'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-03-02')">HAIB1-03-02</th>
+                                <th :class="[shelfOccupy['HAIB1-02-02'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-02-02'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-02-02')">HAIB1-02-02</th>
+                                <th :class="[shelfOccupy['HAIB1-01-02'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-01-02'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-01-02')">HAIB1-01-02</th>
+                            </tr>
+                            <tr>
+                                <th :class="[shelfOccupy['HAIB1-03-01'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-03-01'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-03-01')">HAIB1-03-01</th>
+                                <th :class="[shelfOccupy['HAIB1-02-01'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-02-01'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-02-01')">HAIB1-02-01</th>
+                                <th :class="[shelfOccupy['HAIB1-01-01'] ? 'bg-danger' : 'bg-success',selectedBox['HAIB1-01-01'] ? 'box-shadow-dark' : '']"
+                                    @click="fillingBox('HAIB1-01-01')">HAIB1-01-01</th>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
 @stop
@@ -65,13 +100,40 @@
                     ide:"",
                 },
                 errors:{},
+                shelfOccupy:{},
+                selectedBox:{},
             },
             mounted(){
+                @foreach($storages as $storage)this.$set(this.shelfOccupy,"{{$storage->station->code}}",true);@endforeach
                 this.codeFocus();
                 this.globalClick();
                 this.createBefore();
             },
             methods:{
+                //选中填充料箱
+                fillingBox(ideCode){
+                    this.$set(this.selectedBox,ideCode,this.selectedBox[ideCode] ? !this.selectedBox[ideCode] : true);
+                },
+                //提交填充料箱
+                submitBox(){
+                    window.tempTip.setDuration(3000);
+                    if (JSON.stringify(this.selectedBox)==='{}'){window.tempTip.show("未选中格口");return;}
+                    window.tempTip.confirm("确定选中格口已无料箱存在?",()=>{
+                        let boxes = [];
+                        for (let key in this.selectedBox)boxes.push(key);
+                        window.tempTip.postBasicRequest("{{url('store/inStorage/resetCacheShelf')}}",{boxes:boxes},res=>{
+                            for (let i=0;i<res.boxes.length;i++){
+                                this.$set(this.shelfOccupy,res.boxes[i],false);
+                                this.$set(this.selectedBox,res.boxes[i],false);
+                            }
+                            if (res.data){
+                                window.tempTip.show(res.data);
+                                return;
+                            }
+                            return "手动补充成功";
+                        },true);
+                    })
+                },
                 //聚焦 白名单
                 codeFocus(){
                     if (!this.permissionList.includes(document.activeElement.id)) document.getElementById("barCode").focus();

+ 61 - 81
resources/views/transport/waybill/index.blade.php

@@ -42,6 +42,7 @@
                 </div>
             </span>
             @can('运输管理-运单-图片上传')<button class="btn btn-sm btn-outline-info" data-target="#batchUploadImg" data-toggle="modal">批量上传图片</button>@endcan
+            @can('运输管理-运单-图片删除')<button class="btn btn-sm btn-outline-danger" @click="deleteImg()">批量删除图片</button>@endcan
             @if($uriType=='' || $uriType=='专线')
                 @can('运输管理-运单-按日计算专线费')
                     <button class="btn btn-sm btn-outline-success tooltipTarget" data-target="#dailyBilling" data-toggle="modal"
@@ -140,14 +141,15 @@
                     <td class="td-warm"><span>@{{waybill.other_charge}}</span></td>
                     <td class="td-warm"><span>@{{waybill.other_charge_remark}}</span></td>
                     <td class="td-warm">
-                        <div align="center" @mouseleave="removeCommonImg('common_img_'+waybill.id)" @mouseenter="commonImg('img_'+waybill.id,waybill.url,waybill.suffix)">
-                            <img v-if="waybill.url" :id="'img_'+waybill.id"  :src="waybill.url+'-thumbnail.'+waybill.suffix"
-                                {{--:data-src="waybill.url+'-thumbnail.'+waybill.suffix" src="{{url('icon/img404-thumbnail.jpg')}}"--}}>
-                            @can('运输管理-运单-图片上传')<div v-if="!waybill.url">
-                                <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(waybill.waybill_number)" value="上传照片 "/>
-                                <input type="file" @change="submitFile($event,waybill.waybill_number)" :id="waybill.waybill_number"
-                                       style="display: none" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
+                        <div align="center" @mouseleave="removeCommonImg('common_img_'+waybill.id)" @mouseenter="commonImg('img_'+waybill.id,waybill.uploadFiles)">
+                            @can('运输管理-运单-图片上传')<div>
+                            <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(waybill.waybill_number)" value="上传照片 "/>
+                            <input multiple type="file" @change="submitFile($event,i)" :id="waybill.waybill_number"
+                                   style="display: none" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
                             </div>@endcan
+                            <div :id="'img_'+waybill.id">
+                                <img v-for="uploadFile in waybill.uploadFiles"  :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
+                            </div>
                         </div>
                     </td>
                     <td class="td-cool"><span>@{{waybill.ordering_remark}}</span></td>
@@ -296,14 +298,14 @@
         let vue = new Vue({
             el:'#list',
             data:{
+                imgPrefix:"{{asset("/storage")}}",
                 waybills:[
                         @foreach($waybills as $waybill)
                     {
                         id:'{{$waybill->id}}',
                         created_at:'{{$waybill->created_at}}',
                         updated_at:'{{$waybill->updated_at}}',
-                        url:'{{$waybill->uploadFile ? asset('/storage'.$waybill->uploadFile->url) : ''}}',
-                        suffix:'{{$waybill->uploadFile ? $waybill->uploadFile->type : ''}}',
+                        uploadFiles:{!! $waybill->uploadFiles !!},
                         status:'{{$waybill->status}}',
                         type:'{{$waybill->type}}',
                         end_date:'{{($waybill->order&&$waybill->order->wms_status=='订单完成') ? $waybill->order->wms_edittime:'-'}}',
@@ -415,7 +417,7 @@
                             placeholder:['承运商','定位或多选承运商'],data:this.logistics},
                     ],
                     [
-                        {name:'source_bill',type:'input',tip: '可支持多上游单号:可在左侧增加百分号(%)进行模糊搜索',placeholder: '上游单号'},
+                        {name:'source_bill',type:'input',tip: '可支持多客户订单号:可在左侧增加百分号(%)进行模糊搜索',placeholder: '客户订单号'},
                         {name:'recipient',type:'input',tip: '可支持多收货人姓名:可在左侧增加百分号(%)进行模糊搜索',placeholder: '收货人姓名'},
                         {name:'recipient_mobile',type:'input',tip: '可支持多收货人电话:可在左侧增加百分号(%)进行模糊搜索',placeholder: '收货人电话'},
                         {name:'car_owner_info',type:'input',tip: '车辆信息:可在左侧增加百分号(%)进行模糊搜索',placeholder: '车辆信息'},
@@ -528,7 +530,7 @@
                         {name:'operating',value: '操作记录', class:"td-warm"},
                         {name:'type',value: '运单类型', class:"td-warm"},
                         {name:'owner',value: '货主', class:"td-warm"},
-                        {name:'source_bill',value: '上游单号', class:"td-warm"},
+                        {name:'source_bill',value: '客户订单号', class:"td-warm"},
                         {name:'wms_bill_number',value: 'WMS订单号', class:"td-warm"},
                         {name:'order_status',value: '订单状态', class:"td-warm"},
                         {name:'end_date',value: '完结时间', class:"td-warm"},
@@ -695,50 +697,35 @@
                 certiimg(waybill_number){
                     $('#'+waybill_number).click();
                 },
-                submitFile(e,waybill_number){
-                    let file=e.target.files[0];
-                    if (file.size >=5242880){
-                        tempTip.setDuration(3000);
-                        tempTip.show("图片大小不能超过5MB!");
-                        return;
-                    }
-                    let _this=this;
+                submitFile(e,index){
+                    let files=e.target.files;
+                    window.tempTip.setDuration(3000);
+                    if (files.length===0){window.tempTip.show("未选定图片!");return;}
                     let formData=new FormData();
-                    formData.append("file",file);
-                    formData.append("waybill_number",waybill_number);
-                    axios.post('{{url('transport/waybill/upload')}}',formData)
-                        .then(function (response) {
-                            if (!response.data.success){
-                                tempTip.setDuration(4000);
-                                tempTip.show(response.data.error);
-                                return;
-                            }
-                            _this.waybills.some(function (waybill) {
-                                if (waybill.waybill_number===waybill_number){
-                                    waybill.url=response.data.data.url;
-                                    waybill.suffix=response.data.data.type;
-                                    tempTip.setDuration(3000);
-                                    tempTip.showSuccess("上传成功!");
-                                    return true;
-                                }
-                            });
-                        }).catch(function (err) {
-                        tempTip.setDuration(4000);
-                        tempTip.show("网络错误:"+err);
-                    })
+                    for (let i=0;i<files.length;i++){
+                        if (files[i].size >=5242880){window.tempTip.show("图片大小不能超过5MB!");return;}
+                        formData.append("files[]",files[i]);
+                    }
+                    formData.append("id",this.waybills[index].id);
+                    window.tempTip.postBasicRequest('{{url('transport/waybill/upload')}}',formData,res=>{
+                        if (this.waybills[index].uploadFiles.length===0) this.$set(this.waybills[index],'uploadFiles',res);
+                        else this.$set(this.waybills[index],'uploadFiles',this.waybills[index].uploadFiles.concat(res));
+                        return "上传成功";
+                    },false,true);
                 },
-                commonImg(id,url,suffix){
+                commonImg(id,uploadFiles){
+                    let div = "";
+                    let isBtn = '@can('运输管理-运单-图片删除') true @endcan ';
+                    for(let i=0;i<uploadFiles.length;i++){
+                        let btn = isBtn ? "<button type='button' class='btn btn-sm btn-danger' onclick='vue.btnDeleteImg(this)' data-url='"+uploadFiles[i].url+"' value='"+id+"' style='position: relative;float: right;margin-top: -30px;' >删除</button>" : "";
+                        let href = this.imgPrefix+uploadFiles[i].url+'-bulky.'+uploadFiles[i].type;
+                        let src = this.imgPrefix+uploadFiles[i].url+'-common.'+uploadFiles[i].type;
+                        div += "<div><a target='_blank' href='"+href+"'><img alt='#' src='"+src+"' style='position: relative;' ></a>"+btn+"</div>"
+                    }
                     $('#'+id).after(
-                        "<div id=\"common_"+id+"\" style='position: absolute;padding-top: 2px;z-index: 99'>" +
-                        "<div style='position:absolute'>"+
-                        "<div >"+
-                        "<a target='_blank' href='"+url+'-bulky.'+suffix+"'>" +
-                        "<img src=\""+url+'-common.'+suffix+"\" style='position: relative;left:-50px;' >" +
-                        "</a>" +
-                        "</div>"+
-                        @can('运输管理-运单-图片删除')"<button type='button' class='btn btn-sm btn-danger' onclick='vue.btnDeleteImg(this)' value='"+id+"' style='position: relative;float: right;margin-right: 51px;margin-top: -30px;' >删除</button>" +@endcan
-                            "</div>"+
-                        "</div>");
+                        "<div id=\"common_"+id+"\" style='position: absolute;padding-bottom: 2px;z-index: 99'>" +
+                        "<div style='position:absolute;left: -50px' class='overflow-y-scrollbar-200'>"+div+
+                        "</div></div>");
                 },
                 removeCommonImg(id){
                     $('#'+id).remove();
@@ -746,41 +733,36 @@
                 btnDeleteImg(e){
                     let idstr = $(e).val();
                     let id =  idstr.substr( idstr.indexOf('_')+1);
+                    let url = e.getAttribute("data-url");
                     if (!confirm('确定要删除所选图片吗?'))return;
-                    this.destroyImg([id]);
+                    this.destroyImg(id,url);
                 },
                 deleteImg(){
                     if (checkData.length <= 0) {
-                        tempTip.setDuration(2000);
-                        tempTip.showSuccess('没有勾选任何记录');
+                        window.tempTip.setDuration(2000);
+                        window.tempTip.showSuccess('没有勾选任何记录');
                         return;
                     }
                     if (!confirm('确定要删除所选图片吗?'))return;
                     this.destroyImg(checkData);
                 },
-                destroyImg(id){
-                    let _this = this;
-                    axios.post('{{url('transport/waybill/deleteImg')}}',{'ids':id})
-                        .then(function (response) {
-                            if (!response.data.success){
-                                tempTip.setDuration(4000);
-                                tempTip.show("删除失败");
-                                return;
-                            }
-                            id.forEach(function (id) {
-                                _this.waybills.some(function (waybill) {
-                                    if (waybill.id===id){
-                                        waybill.url='';
-                                        return true;
-                                    }
-                                });
+                destroyImg(id,url = null){
+                    window.tempTip.postBasicRequest('{{url('transport/waybill/deleteImg')}}',{id:id,url:url},()=>{
+                        if (url){
+                            this.waybills.some((waybill,i)=>{
+                                if (waybill.id===id){
+                                    waybill.uploadFiles.some((file,j)=>{
+                                        if (file.url === url){this.$delete(this.waybills[i].uploadFiles,j);return true;}
+                                    });
+                                    return true;
+                                }
                             });
-
-                            tempTip.setDuration(3000);
-                            tempTip.showSuccess("删除成功!");
-                        }).catch(function (err) {
-                        tempTip.setDuration(4000);
-                        tempTip.show("网络错误:"+err);
+                        }else{
+                            this.waybills.forEach((waybill,i)=>{
+                                if (id.includes(waybill.id))this.$set(this.waybills[i],'uploadFiles',[]);
+                            });
+                        }
+                        return "删除成功";
                     });
                 },
                 // 运输收费修改
@@ -1086,16 +1068,14 @@
                         let errors = res.errors;
                         if (errors.length>0)this.batchUploadError =  errors;
                         result.forEach(r=>{
-                            this.waybills.some(waybill=> {
+                            this.waybills.some((waybill,i)=> {
                                 if (waybill.id==r.id){
-                                    waybill.url="/storage"+r.upload_file.url;
-                                    waybill.suffix=r.upload_file.type;
+                                    this.$set(this.waybills[i],'uploadFiles',r.upload_files);
                                     return true;
                                 }
                             });
                             this.size = 0;
                         });
-                        this.$forceUpdate();
                         return "上传成功";
                     },true);
                 },

+ 1 - 0
routes/apiLocal.php

@@ -138,6 +138,7 @@ Route::group(['prefix'=>'control'],function () {
     Route::post('panel/menu/laborReportsUserGroupsCountApi','ControlPanelController@laborReportsUserGroupsCountApi');
     Route::post('panel/menu/weightApi','ControlPanelController@weightApi');
     Route::post('panel/menu/exceptionTypeApi','ControlPanelController@exceptionTypeApi');
+    Route::post('panel/menu/orderPackageReceivedSyncRecordApi','ControlPanelController@orderPackageReceivedSyncRecordApi');
 });
 
 /** 耗材 */

+ 7 - 0
routes/web.php

@@ -416,6 +416,7 @@ Route::group(['prefix'=>'store'],function(){
         Route::get('index','StoreController@storage');
         Route::get('cacheRackStorage','StoreController@cacheRackStorage');
         Route::post('putShelf','StorageController@putShelf');
+        Route::post('resetCacheShelf','StorageController@resetCacheShelf');
     });
     Route::group(['prefix'=>'fast'],function() {
         Route::resource('storeItem','StoreItemController');
@@ -458,6 +459,7 @@ Route::group(['prefix'=>'store'],function(){
         Route::post('delivery','DeliveryAppointmentController@checkAppointment');
         Route::post('cancel','DeliveryAppointmentController@cancel');
         Route::post('unloading','DeliveryAppointmentController@unloading');
+        Route::post('signIn','DeliveryAppointmentController@signIn');
         Route::any('export','DeliveryAppointmentController@export');
         Route::post('getExhibitionList','DeliveryAppointmentController@getExhibitionList');
         Route::post('getKey','DeliveryAppointmentController@getKey');
@@ -749,6 +751,9 @@ Route::group(['prefix'=>'finance'],function(){
     Route::get('billConfirmation','CustomerController@financeBillConfirmation');
     Route::post('updateBillReport','CustomerController@updateBillReport');
     Route::post('billConfirm','CustomerController@billConfirm');
+//    Route::group(['prefix'=>'settlementBills'],function(){
+//        Route::resource('ownerSundryFeeDetails', 'OwnerSundryFeeDetailsController', ['only' => ['index', 'create', 'store', 'update', 'edit','destroy']]);
+//    });
 });
 
 /** 客户 */
@@ -810,6 +815,7 @@ Route::group(['prefix'=>'customer'],function(){
     });
     Route::resource('customer', 'CustomerBaseController');
 
+    Route::resource('ownerSundryFeeDetails', 'OwnerSundryFeeDetailsController', ['only' => ['index', 'create', 'store', 'update', 'edit','destroy']]);
 });
 
 /** 站管理 */
@@ -870,3 +876,4 @@ Route::group(['prefix'=>'procurement'],function () {
 Route::group(['prefix'=>'demand'],function (){
     Route::get('/','DemandController@index');
 });
+

+ 1 - 1
tests/Feature/LogisticZopSyncTest.php

@@ -39,7 +39,7 @@ class LogisticZopSyncTest extends TestCase
 
     public function test_get()
     {
-        LogisticZopSync::dispatch('75600189836589');
+        LogisticZopSync::dispatch('75600256515921');
     }
 
 

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно