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

Merge remote-tracking branch 'origin/master'

ANG YU 5 лет назад
Родитель
Сommit
3c6440cb6b
100 измененных файлов с 4418 добавлено и 419 удалено
  1. 1 1
      app/Commodity.php
  2. 65 0
      app/Console/Commands/CreateOwnerAreaReport.php
  3. 82 0
      app/Console/Commands/CreateOwnerBillReport.php
  4. 14 9
      app/Console/Commands/CreateOwnerReport.php
  5. 3 0
      app/Console/Kernel.php
  6. 0 1
      app/Events/GuardAuditEvent.php
  7. 5 0
      app/Http/Controllers/CarTypesController.php
  8. 4 0
      app/Http/Controllers/CitiesController.php
  9. 7 3
      app/Http/Controllers/CommodityController.php
  10. 50 22
      app/Http/Controllers/CustomerBaseController.php
  11. 323 11
      app/Http/Controllers/CustomerController.php
  12. 0 84
      app/Http/Controllers/JobTypeController.php
  13. 14 5
      app/Http/Controllers/LaborReportController.php
  14. 57 33
      app/Http/Controllers/OrderIssueController.php
  15. 9 2
      app/Http/Controllers/OrderTrackingController.php
  16. 16 6
      app/Http/Controllers/PersonnelController.php
  17. 866 17
      app/Http/Controllers/PriceModelController.php
  18. 57 23
      app/Http/Controllers/ProcessMethodController.php
  19. 4 0
      app/Http/Controllers/ProvincesController.php
  20. 104 50
      app/Http/Controllers/TestController.php
  21. 5 0
      app/Http/Controllers/UnitsController.php
  22. 4 4
      app/Http/Controllers/UserDutyCheckController.php
  23. 44 22
      app/Http/Controllers/UserOwnerGroupController.php
  24. 4 2
      app/Http/Controllers/api/thirdPart/goodscan/PackageController.php
  25. 18 13
      app/Http/Controllers/api/thirdPart/haiq/StorageController.php
  26. 2 1
      app/Http/Controllers/api/thirdPart/weight/PackageController.php
  27. 108 0
      app/Imports/ExpressImport.php
  28. 1 1
      app/Imports/OrderIssueImport.php
  29. 253 0
      app/Imports/OrderTrackingImport.php
  30. 135 0
      app/Imports/OwnerPriceDirectLogisticDetailImport.php
  31. 187 0
      app/Imports/OwnerPriceLogisticDetailImport.php
  32. 30 22
      app/LaborReport.php
  33. 1 1
      app/LaborReportStatus.php
  34. 5 0
      app/Logistic.php
  35. 1 0
      app/OracleBasSKU.php
  36. 11 4
      app/OrderIssue.php
  37. 5 0
      app/OrderPackage.php
  38. 20 0
      app/OrderTracking.php
  39. 41 0
      app/Owner.php
  40. 17 7
      app/OwnerAreaReport.php
  41. 2 1
      app/OwnerBillReport.php
  42. 0 1
      app/OwnerFeeDetail.php
  43. 1 0
      app/OwnerInStorageRule.php
  44. 13 1
      app/OwnerOutStorageRule.php
  45. 11 1
      app/OwnerPriceDirectLogistic.php
  46. 20 5
      app/OwnerPriceExpress.php
  47. 2 2
      app/OwnerPriceExpressProvince.php
  48. 24 0
      app/OwnerPriceLogistic.php
  49. 14 0
      app/OwnerPriceOperation.php
  50. 1 0
      app/OwnerReport.php
  51. 10 0
      app/OwnerStoragePriceModelOwner.php
  52. 23 0
      app/Providers/AppServiceProvider.php
  53. 47 0
      app/Services/CommodityService.php
  54. 28 0
      app/Services/CustomerService.php
  55. 189 0
      app/Services/FeatureService.php
  56. 14 15
      app/Services/LaborReportService.php
  57. 37 22
      app/Services/OrderIssueService.php
  58. 0 1
      app/Services/OrderPackageService.php
  59. 7 4
      app/Services/OrderService.php
  60. 37 0
      app/Services/OrderTrackingService.php
  61. 85 0
      app/Services/OwnerAreaReportService.php
  62. 58 0
      app/Services/OwnerBillReportService.php
  63. 58 0
      app/Services/OwnerFeeDetailService.php
  64. 57 0
      app/Services/OwnerOutStorageRuleService.php
  65. 111 0
      app/Services/OwnerPriceDirectLogisticService.php
  66. 130 0
      app/Services/OwnerPriceExpressService.php
  67. 139 0
      app/Services/OwnerPriceLogisticService.php
  68. 253 0
      app/Services/OwnerPriceOperationService.php
  69. 0 5
      app/Services/OwnerReportService.php
  70. 31 1
      app/Services/OwnerService.php
  71. 66 0
      app/Services/OwnerStoragePriceModelService.php
  72. 30 0
      app/Services/ProcessMethodService.php
  73. 4 0
      app/Services/ShopService.php
  74. 29 0
      app/Services/UserOwnerGroupService.php
  75. 0 5
      app/User.php
  76. 1 0
      config/users.php
  77. 13 0
      database/factories/LogisticFactory.php
  78. 27 0
      database/factories/OrderTrackingFactory.php
  79. 3 3
      database/factories/OwnerBillReportFactory.php
  80. 39 0
      database/factories/OwnerFeeDetailFactory.php
  81. 17 0
      database/factories/OwnerInStorageRuleFactory.php
  82. 20 0
      database/factories/OwnerOutStorageRuleFactory.php
  83. 16 0
      database/factories/OwnerPriceExpressFactory.php
  84. 17 0
      database/factories/OwnerPriceOperationFactory.php
  85. 22 0
      database/factories/OwnerStoragePriceModelFactory.php
  86. 16 0
      database/factories/ProcessMethodFactory.php
  87. 15 0
      database/factories/ShopFactory.php
  88. 12 0
      database/factories/UnitFactory.php
  89. 1 0
      database/migrations/2020_10_20_143953_create_owner_reports_table.php
  90. 2 0
      database/migrations/2020_10_26_142753_create_owner_area_reports_table.php
  91. 0 1
      database/migrations/2020_10_26_165012_create_owner_fee_details_table.php
  92. 1 0
      database/migrations/2020_10_27_103741_create_owner_bill_reports_table.php
  93. 2 2
      database/migrations/2020_10_27_142647_create_owner_storage_price_model_table.php
  94. 1 0
      database/migrations/2020_10_27_175452_create_owner_price_operations_table.php
  95. 3 2
      database/migrations/2020_10_28_105613_create_owner_out_storage_rules_table.php
  96. 2 1
      database/migrations/2020_10_28_105639_create_owner_in_storage_rules_table.php
  97. 2 2
      database/migrations/2020_10_28_162458_create_owner_price_expresses_table.php
  98. 20 0
      database/migrations/2020_10_28_170858_save_customer_authority_data.php
  99. 31 0
      database/migrations/2020_11_02_095633_create_owner_storage_price_model_owner_table.php
  100. 31 0
      database/migrations/2020_11_03_095611_create_owner_price_operation_owner_table.php

+ 1 - 1
app/Commodity.php

@@ -9,7 +9,7 @@ use App\Traits\ModelTimeFormat;
 class Commodity extends Model
 {
     use ModelTimeFormat;
-    protected $fillable=['name','sku','owner_id','created_at','length','width','height','volumn',"type"];
+    protected $fillable=['name','sku','owner_id','created_at','length','width','height','volumn',"type","pack"];
     protected $appends=['barcode'];
 //    protected $appends=['barcode','owner_name','owner_code'];
 

+ 65 - 0
app/Console/Commands/CreateOwnerAreaReport.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OwnerAreaReport;
+use App\Services\OwnerService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CreateOwnerAreaReport extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'createOwnerAreaReport';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'create owner area report';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * TODO 25号生成盘点面积记录,记录留空由人工填写
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        /** @var OwnerService $ownerService */
+        $ownerService = app('OwnerService');
+        $chunks = ($ownerService->get([],["ownerStoragePriceModels"],false,true))->chunk(50);
+        $month = date('Y-m-d');
+        foreach ($chunks as $owners){
+            $date = date('Y-m-d H:i:s');
+            $createOwnerAreaReport = [];
+            foreach ($owners as $owner){
+                if (!$owner->ownerStoragePriceModels)continue;
+                foreach ($owner->ownerStoragePriceModels as $model){
+                    $createOwnerAreaReport[] = [
+                        "owner_id"              => $owner->id,
+                        "counting_month"        => $month,
+                        "user_owner_group_id"   => $owner->user_owner_group_id,
+                        "created_at"            => $date,
+                        "owner_storage_price_model_id"  => $model->id,
+                    ];
+                }
+            }
+            DB::table("owner_area_reports")->insert($createOwnerAreaReport);
+        }
+    }
+}

+ 82 - 0
app/Console/Commands/CreateOwnerBillReport.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OwnerAreaReport;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CreateOwnerBillReport extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'createOwnerBillReport';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'create owner bill report';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 1号生成账单确认,确认金额由人工填写 原始金额默认为:即时账单月记录金额+仓储计费与面积计算金额
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $year = (int)date('Y');
+        $month = (int)date('m');
+        if ($month == 1){
+            $year--;
+            $lastMonth = '12';
+        }else $lastMonth = ($month-1) < 10 ? "0".($month-1) : ($month-1);
+        $bills = DB::select(DB::raw("select owner_id,SUM(work_fee)+SUM(logistic_fee) as total from owner_fee_details where worked_at like ? GROUP BY owner_id"),[$year."-".$lastMonth."%"]);
+
+        $areas = OwnerAreaReport::query()->with("ownerStoragePriceModel")->where("counting_month","like",$year."-".$lastMonth."%")->get();
+        $map = [];
+        foreach($areas as $area){
+            if (isset($map[$area->owner_id."_".$area->counting_month])){
+                if (!$area->ownerStoragePriceModel)continue;
+                $map[$area->owner_id."_".$area->counting_month] += app('OwnerStoragePriceModelService')
+                    ->calculationAmount($area->ownerStoragePriceModel,$area->accounting_area,$area->owner_id,$area->counting_month);
+            }else{
+                if (!$area->ownerStoragePriceModel)continue;
+                $map[$area->owner_id."_".$area->counting_month] = app('OwnerStoragePriceModelService')
+                    ->calculationAmount($area->ownerStoragePriceModel,$area->accounting_area,$area->owner_id,$area->counting_month);
+            }
+        }
+
+        $chunks = array_chunk($bills,50);
+        foreach ($chunks as $bills){
+            $date = date('Y-m-d H:i:s');
+            $createOwnerBillReport = [];
+            foreach ($bills as $bill){
+                $key = $bill->owner_id."_".$year."-".$lastMonth;
+                $total = $bill->total;
+                if (isset($map[$key]))$total += $map[$key];
+                $createOwnerBillReport[] = [
+                    "owner_id"          => $bill->owner_id,       //项目ID
+                    "counting_month"    => $year."-".$lastMonth."-01", //结算月
+                    "initial_fee"       => $total,    //原始账单金额
+                    "created_at"        => $date,
+                ];
+            }
+            DB::table("owner_bill_reports")->insert($createOwnerBillReport);
+        }
+    }
+}

+ 14 - 9
app/Console/Commands/CreateOwnerReport.php

@@ -58,18 +58,20 @@ class CreateOwnerReport extends Command
         $lastDay = date("d",strtotime("$year-$lastMonth +1 month -1 day"));
 
         //获取上月面积与报表
-        $areas = OwnerAreaReport::query()->with(['owner'=>function($query){
-            $query->select('id',"code");
-        }])->where("counting_month","like",$year."-".$lastMonth."%")->get();
+        $areas = OwnerAreaReport::query()->select("id","owner_id","counting_month",DB::raw("SUM(accounting_area) total,YEAR(counting_month) y,MONTH(counting_month) m"))
+            ->with(['owner'=>function($query){
+                $query->select('id',"code");
+            }])->where("counting_month","like",$year."-".$lastMonth."%")
+            ->groupBy("y","m","owner_id")->get();
         $reports = OwnerReport::query()->where("counting_month","like",$year."-".$lastMonth."%")->orWhere("counting_month","like",$historyYear."-".$historyMonth."%")->get();
         $bills = OwnerBillReport::query()->where("counting_month","like",$year."-".$lastMonth."%")->get();
 
         //日均单量统计
-        $query = DB::raw("select  count(*) c,CUSTOMERID from DOC_ORDER_HEADER where EDITTIME >= to_date('$year-$lastMonth-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and EDITTIME <= to_date('$year-$lastMonth-$lastDay 23:59:59','yyyy-mm-dd hh24:mi:ss') group by CUSTOMERID");
+        $query = DB::raw("select  count(*) c,CUSTOMERID from DOC_ORDER_HEADER where EDITTIME >= to_date('".$year."-".$lastMonth."-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and EDITTIME <= to_date('".$year."-".$lastMonth."-".$lastDay." 23:59:59','yyyy-mm-dd hh24:mi:ss') group by CUSTOMERID");
         $orderStatistic = DB::connection("oracle")->select($query);
         $map = [];
         foreach ($orderStatistic as $item){
-            $map[$item->customerid] = round($item->c / $lastDay,2);
+            $map[$item->customerid] = $item->c;
         }
 
         //已存在的报表记录
@@ -95,18 +97,21 @@ class CreateOwnerReport extends Command
         ]];
         $createReports = [];
         foreach ($areas as $area){
+            $total = $area->owner ? ($map[$area->owner->code] ?? 0) : 0;
             if ($reportMap[$area->owner_id."_".$area->counting_month] ?? false){
                 $updateReports[] = [
                     "id"=>$reportMap[$area->owner_id."_".$area->counting_month],
-                    "daily_average_order_amount"=>$area->owner ? ($map[$area->owner->code] ?? 0) : 0,
-                    "current_month_counting_area"=>$area->accounting_area ?? 0,
+                    "total" =>$total,
+                    "daily_average_order_amount"=>round($total / $lastDay,2),
+                    "current_month_counting_area"=>$area->total ?? 0,
                     "owner_bill_report_id" => $billMap[$area->owner_id."_".$area->counting_month] ?? 0,
                 ];
             }else $createReports[] = [
                 "owner_id"=>$area->owner_id,
                 "counting_month"=>$area->counting_month."-01",
-                "daily_average_order_amount"=>$area->owner ? ($map[$area->owner->code] ?? 0) : 0,
-                "current_month_counting_area"=>$area->accounting_area ?? 0,
+                "total" =>$total,
+                "daily_average_order_amount"=>round($total / $lastDay,2),
+                "current_month_counting_area"=>$area->total ?? 0,
                 "owner_bill_report_id" => $billMap[$area->owner_id."_".$area->counting_month] ?? 0,
                 "last_month_counting_area" => $historyReportMap[$area->owner_id."_".($historyYear."-".$historyMonth)] ?? 0,
             ];

+ 3 - 0
app/Console/Kernel.php

@@ -36,6 +36,9 @@ class Kernel extends ConsoleKernel
 //        $schedule->command('FluxOrderFix')->cron('* * * * *');
         $schedule->command('WASSyncWMSOrderInformation')->everyMinute();
         $schedule->command('syncLogCacheTask')->everyMinute();
+        $schedule->command('createOwnerReport')->monthlyOn(1);
+        $schedule->command('createOwnerBillReport')->monthlyOn(1);
+        $schedule->command('createOwnerAreaReport')->monthlyOn(25);
     }
 
     /**

+ 0 - 1
app/Events/GuardAuditEvent.php

@@ -2,7 +2,6 @@
 
 namespace App\Events;
 
-use App\LaborReport;
 use App\UserDutyCheck;
 use Illuminate\Broadcasting\Channel;
 use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

+ 5 - 0
app/Http/Controllers/CarTypesController.php

@@ -66,6 +66,11 @@ class CarTypesController extends Controller
         return ['success'=>$result];
     }
 
+    public function get()
+    {
+        return CarType::query()->select("id","name","model")->get();
+    }
+
     protected  function validatorCarType(Request $request,$id){
         if ($id){$name=$id;}
         $validator=Validator::make($request->input(),[

+ 4 - 0
app/Http/Controllers/CitiesController.php

@@ -80,4 +80,8 @@ class CitiesController extends Controller
         ]);
         return $validator;
     }
+
+    public function get(){
+        return City::query()->select("id","name","province_id")->get();
+    }
 }

+ 7 - 3
app/Http/Controllers/CommodityController.php

@@ -217,7 +217,7 @@ class CommodityController extends Controller
         $commodities = $commodityService->getOwnerCommodities(['owner_id' => $owner_id, 'sku'=>$skus]);
         $updateCommodities = [];
         $updateCommodities[] = [
-            'id', 'sku', 'name', 'length', 'width', 'height', 'volumn',
+            'id', 'sku', 'name', 'length', 'width', 'height', 'volumn',"pack"
         ];
         $barcodeMap = [];
         $commoditiesId = [];
@@ -228,7 +228,8 @@ class CommodityController extends Controller
             $trimSku = rtrim($wms->sku,"*");
             if (($commodity->sku != $trimSku) || ($commodity->length != $wms->skulength)
                 || ($commodity->width != $wms->skuwidth) || ($commodity->name != $wms->descr_c)
-                || ($commodity->height != $wms->skuhigh) || ($commodity->volumn != $wms->cube)){
+                || ($commodity->height != $wms->skuhigh) || ($commodity->volumn != $wms->cube)
+                || ($commodity->pack === null)){
                 $updateCommodities[] = [
                     'id'=>$commodity->id,
                     'sku'=>$trimSku,
@@ -236,7 +237,8 @@ class CommodityController extends Controller
                     'length' => $wms->skulength,
                     'width' => $wms->skuwidth,
                     'height' => $wms->skuhigh,
-                    'volumn' => $wms->cube
+                    'volumn' => $wms->cube,
+                    "pack"  => $wms->packid == 'STANDARD' ? 0 : explode("/",$wms->packid)[1],
                 ];
             }
             if ($wms->alternate_sku1){
@@ -298,6 +300,7 @@ class CommodityController extends Controller
                 'width' => $wms->skuwidth,
                 'height' => $wms->skuhigh,
                 'volumn' => $wms->cube,
+                "pack"  => $wms->packid == 'STANDARD' ? 0 : explode("/",$wms->packid)[1],
                 "created_at" => $today,
             ];
             $barcodeMap[$wms->sku] = [];
@@ -337,6 +340,7 @@ class CommodityController extends Controller
                             'width' => $goods['width'],
                             'height' => $goods['height'],
                             'volumn' => $goods['volumn'],
+                            "pack" => $goods["pack"],
                         ];
                         unset($createCommodities[$barcodeIndex[$code->code]]);
                         break;

+ 50 - 22
app/Http/Controllers/CustomerBaseController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Validator;
 
 class CustomerBaseController extends Controller
 {
@@ -16,7 +17,8 @@ class CustomerBaseController extends Controller
     public function index()
     {
         if(!Gate::allows('客户-查询')){ return redirect('denied');  }
-        return response()->view('maintenance.customer.index');
+        $customers = app('CustomerService')->paginate();
+        return response()->view('maintenance.customer.index',compact("customers"));
     }
 
     /**
@@ -33,56 +35,82 @@ class CustomerBaseController extends Controller
     /**
      * Store a newly created resource in storage.
      *
-     * @param  \Illuminate\Http\Request  $request
-     * @return \Illuminate\Http\Response
+     * @param  Request  $request
+     * @return Response
      */
     public function store(Request $request)
     {
-        //
-    }
-
-    /**
-     * Display the specified resource.
-     *
-     * @param  int  $id
-     * @return \Illuminate\Http\Response
-     */
-    public function show($id)
-    {
-        //
+        if(!Gate::allows('客户-录入')){ return redirect('denied');  }
+        $this->validator($request->input())->validate();
+        app('CustomerService')->create([
+            "code"=>$request->input("code"),
+            "name"=>$request->input("name"),
+            "company_name"=>$request->input("company_name"),
+        ]);
+        return response()->redirectTo("maintenance/customer")->with("successTip","成功创建客户“".$request->input("name")."”");
     }
 
     /**
      * Show the form for editing the specified resource.
      *
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return Response
      */
     public function edit($id)
     {
-        //
+        if(!Gate::allows('客户-编辑')){ return redirect('denied');  }
+        $customer = app('CustomerService')->find($id);
+        return response()->view('maintenance.customer.create',compact("customer"));
     }
 
     /**
      * Update the specified resource in storage.
      *
-     * @param  \Illuminate\Http\Request  $request
+     * @param  Request  $request
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return Response
      */
     public function update(Request $request, $id)
     {
-        //
+        if(!Gate::allows('客户-编辑')){ return redirect('denied');  }
+        $this->validator($request->input(),$id)->validate();
+        $result = app('CustomerService')->update(["id"=>$id],[
+            "code"=>$request->input("code"),
+            "name"=>$request->input("name"),
+            "company_name"=>$request->input("company_name"),
+        ]);
+        if ($result == 1){
+            return response()->redirectTo("maintenance/customer")->with("successTip","成功修改客户“".$request->input("name")."”的信息");
+        }
+        return response()->view("exception.default",["code"=>"509"]);
     }
 
     /**
      * Remove the specified resource from storage.
      *
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return array
      */
     public function destroy($id)
     {
-        //
+        if(!Gate::allows('客户-删除')){ return ["success"=>false,"data"=>"无权操作!"];  }
+        $result = app('CustomerService')->destroy($id);
+        if ($result == 1)return ["success"=>true];
+        return ["success"=>false,"data"=>"删除了“".$result."”行"];
+    }
+
+    private function validator(array $params, $id = null)
+    {
+        return Validator::make($params,[
+            'code'=>['required',$id?"unique:customers,code,$id":'unique:customers,code','max:20'],
+            'name'=>['required','max:20'],
+        ],[
+            'required'=>':attribute 为必填项',
+            'max'=>':attribute 字符过多或输入值过大',
+            'unique'=>':attribute 已存在',
+        ],[
+            'code'=>'客户代码',
+            'name'=>'客户名称',
+        ]);
     }
 }

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

@@ -2,14 +2,19 @@
 
 namespace App\Http\Controllers;
 
+use App\Owner;
+use App\Services\OwnerAreaReportService;
+use App\Services\OwnerBillReportService;
 use App\Services\OwnerReportService;
 use App\Services\OwnerService;
 use Exception;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
+use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Http;
+use Illuminate\Support\Facades\Validator;
 
 class CustomerController extends Controller
 {
@@ -30,12 +35,13 @@ class CustomerController extends Controller
         $customers = app('CustomerService')->getSelection();
         $owners = app('OwnerService')->getSelection();
         $reports = app("OwnerReportService")->paginate($request->input(),$withs);
-        return response()->view('customer.project.report',compact("reports","ownerGroups","customers","owners"));
+        $params = $request->input();
+        return response()->view('customer.project.report',compact("reports","ownerGroups","customers","owners","params"));
     }
 
     public function projectReportExport(Request $request)
     {
-        if(!Gate::allows('客户管理-项目-报表')){ return '没有权限';  }
+        if(!Gate::allows('客户管理-项目-报表')){ return redirect('denied');  }
         /** @var OwnerReportService $service */
         $service = app('OwnerReportService');
         $withs = ["ownerBillReport","owner"=>function($query){
@@ -82,31 +88,337 @@ class CustomerController extends Controller
         if(!Gate::allows('客户管理-项目-查询')){ return redirect('denied');  }
         /** @var OwnerService $service */
         $service = app('OwnerService');
-        $customers = $service->get(['customer_id'=>true],['customer']);
-        return response()->view('customer.project.index');
+        $owners = $service->paginate(['customer_id'=>true],['customer',"userOwnerGroup","ownerStoragePriceModels","ownerAreaReport"=>function($query){
+            $month = date('Y-m');
+            /** @var Builder $query */
+            $query->where("counting_month","like",$month."%");
+        }]);
+        return response()->view('customer.project.index',compact("owners"));
+    }
+
+    public function projectIndexExport(Request $request)
+    {
+        if(!Gate::allows('客户管理-项目-查询')){ return redirect('denied');  }
+        /** @var OwnerService $service */
+        $service = app('OwnerService');
+        $withs = ['customer',"userOwnerGroup","ownerStoragePriceModels","ownerAreaReport"=>function($query){
+            $month = date('Y-m');
+            /** @var Builder $query */
+            $query->where("counting_month","like",$month."%");
+        }];
+        $params = $request->input();
+        $params['customer_id']=true;
+        if ($request->checkAllSign ?? false) unset($params['checkAllSign']);
+        else $params = ["id"=>$request->data ?? ''];
+        $owners = $service->get($params,$withs);
+        $column = ["客户","税率","项目","货主代码","合同号","创建日期","销售名称","公司全称","联系人","联系电话","项目小组","用仓类型","当月结算面积","月单量预警","是否激活","项目描述"];
+        $list = [];
+        foreach ($owners as $owner){
+            $list[] = [
+                $owner->customer ? $owner->customer->name : '',
+                $owner->tax_rate,
+                $owner->name,
+                $owner->code,
+                $owner->contract_number,
+                $owner->created_at,
+                $owner->salesman,
+                $owner->customer ? $owner->customer->company_name : '',
+                $owner->linkman,
+                $owner->phone_number,
+                $owner->userOwnerGroup ? $owner->userOwnerGroup->name : '',
+                implode(",",array_unique(array_column(($owner->ownerStoragePriceModels)->toArray(),"using_type"))),
+                $owner->ownerAreaReport ? $owner->ownerAreaReport->accounting_area : '',
+                $owner->waring_line_on,
+                $owner->deleted_at ? '否' : '是',
+                $owner->description
+            ];
+        }
+        $post = Http::post(config('go.export.url'),['type'=>'base','data'=>json_encode(["row"=>$column,"list"=>$list],JSON_UNESCAPED_UNICODE)]);
+        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',
+        ]);
     }
 
     public function projectCreate()
     {
         if(!Gate::allows('客户管理-项目-录入')){ return redirect('denied');  }
-        return response()->view('customer.project.create');
+        $customers = app('CustomerService')->getSelection();
+        $ownerGroups = app('UserOwnerGroupService')->getSelection();
+        $storagePriceModels = app('OwnerStoragePriceModelService')->getSelection(["id","counting_type","using_type","minimum_area","price","unit_id"],["unit"=>function($query){$query->select("id","name");}]);
+        $owner = null;
+        return response()->view('customer.project.create',compact("customers","ownerGroups","storagePriceModels","owner"));
+    }
+
+    public function seekOwner(Request $request)
+    {
+        $params = $request->input();
+        $params["customer_id"] = true;
+        $owner = app('OwnerService')->first($params,["customer_id"=>"null"]);
+        if ($owner)return ["success"=>true,"data"=>$owner];
+        else return ["success"=>false];
+    }
+
+    public function projectStore(Request $request)
+    {
+        if(!Gate::allows('客户管理-项目-录入')){ return redirect('denied');  }
+        $this->validator($request->input())->validate();
+        $params = $request->input();
+        if ($params["id"]){
+            /** @var Owner $owner */
+            $owner = app('OwnerService')->find($params["id"]);
+            app('OwnerService')->update($owner,[
+                "customer_id"           => $params["customer_id"],
+                "tax_rate"              => $params["tax_rate"],
+                "contract_number"       => $params["contract_number"],
+                "salesman"              => $params["salesman"],
+                "linkman"               => $params["linkman"],
+                "phone_number"          => $params["phone_number"],
+                "user_owner_group_id"   => $params["owner_group_id"],
+                "waring_line_on"        => $params["waring_line_on"],
+                "description"           => $params["description"],
+            ],[
+                "ownerStoragePriceModels" => explode(',',$params["owner_storage_price_model_id"])
+            ]);
+            $msg = "成功更新“".$owner->name."”的信息!";
+        }else{
+            $owner = app('OwnerService')->create([
+                "name"                  => $params["name"],
+                "code"                  => $params["code"],
+                "customer_id"           => $params["customer_id"],
+                "tax_rate"              => $params["tax_rate"],
+                "contract_number"       => $params["contract_number"],
+                "salesman"              => $params["salesman"],
+                "linkman"               => $params["linkman"],
+                "phone_number"          => $params["phone_number"],
+                "user_owner_group_id"   => $params["owner_group_id"],
+                "waring_line_on"        => $params["waring_line_on"],
+                "description"           => $params["description"],
+            ],[
+                "ownerStoragePriceModels" => explode(',',$params["owner_storage_price_model_id"])
+            ]);
+            $msg = "成功创建“".$owner->name."”项目!";
+        }
+        return response()->redirectTo('customer/project/index')->with('successTip',$msg);
+    }
+
+    //获取货主下所有相关计费模型
+    public function getOwnerPriceModel(Request $request)
+    {
+        $owner = new Owner();
+        $owner->id = $request->id;
+        $owner->load(["ownerPriceOperations","ownerPriceExpresses","ownerPriceLogistics","ownerPriceDirectLogistics"]);
+        return ["success"=>true,"data"=>["ownerPriceOperations"=>$owner->ownerPriceOperations,
+            "ownerPriceExpresses"=>$owner->ownerPriceExpresses,
+            "ownerPriceLogistics"=>$owner->ownerPriceLogistics,
+            "ownerPriceDirectLogistics"=>$owner->ownerPriceDirectLogistics]];
+    }
+
+    public function projectEdit($id)
+    {
+        if(!Gate::allows('客户管理-项目-编辑')){ return redirect('denied');  }
+        /** @var Owner $owner */
+        $owner = app('OwnerService')->find($id);
+        $owner->owner_storage_price_model_id = $owner->getOwnerStoragePriceModelIds();
+        $customers = app('CustomerService')->getSelection();
+        $ownerGroups = app('UserOwnerGroupService')->getSelection();
+        $storagePriceModels = app('OwnerStoragePriceModelService')->getSelection(["id","counting_type","using_type","minimum_area","price","unit_id"],["unit"=>function($query){$query->select("id","name");}]);
+        return response()->view('customer.project.create',compact("customers","ownerGroups","storagePriceModels",'owner'));
     }
 
-    public function projectArea()
+    public function projectArea(Request $request)
     {
         if(!Gate::allows('客户管理-项目-面积')){ return redirect('denied');  }
-        return response()->view('customer.project.area');
+        $areas = app('OwnerAreaReportService')->paginate($request->input(),["owner"=>function($query){$query->with(["customer","ownerStoragePriceModels"]);}]);
+        $ownerGroups = app('UserOwnerGroupService')->getSelection();
+        $customers = app('CustomerService')->getSelection();
+        $owners = app('OwnerService')->getSelection();
+        $params = $request->input();
+        return response()->view('customer.project.area',compact("areas","ownerGroups","customers","owners","params"));
     }
 
-    public function financeInstantBill()
+    public function updateArea(Request $request)
+    {
+        if(!Gate::allows('客户管理-项目-面积-编辑')){ return ["success"=>false,'data'=>"无权操作!"];  }
+        if (!($request->id ?? false) || !($request->area ?? false)) return ["success"=>false,'data'=>"传递错误!"];
+        $values = $request->area ?? null;
+        if (!$values)return ["success"=>true,"data"=>$values];
+        foreach ($values as $column=>$value){
+            if ($value && (!is_numeric($value) || $value<0))return ["success"=>false,'data'=>$column."非数字或小于0!"];
+        }
+        $accounting_area = ((int)$values["area_on_tray"]*205) + ((int)$values["area_on_half_tray"]*1.8) + ((int)$values["area_on_flat"]*1.3);
+        $values["accounting_area"] = $accounting_area;
+        if (app('OwnerAreaReportService')->update(["id"=>$request->id],$values))
+            return ["success"=>true,"data"=>$values];
+        return ["success"=>false,"data"=>"未知错误!"];
+    }
+
+    public function projectAreaExport(Request $request)
+    {
+        if(!Gate::allows('客户管理-项目-面积')){ return redirect('denied');  }
+        $params = $request->input();
+        if ($request->checkAllSign)unset($params['checkAllSign']);
+        else $params = ["id"=>$request->data];
+        /** @var OwnerAreaReportService $serves */
+        $serves = app('OwnerAreaReportService');
+        $areas = $serves->get($params,["owner"=>function($query){$query->with(["customer","ownerStoragePriceModels","userOwnerGroup"]);}]);
+
+        $column = ["状态","项目组","客户","子项目","结算月","录入时间","用仓类型","货物整托","货物半托","平面区面积","结算面积"];
+        $list = [];
+        foreach ($areas as $area){
+            $list[] = [
+                $area->status,
+                $area->owner ? ($area->owner->userOwnerGroup ? $area->owner->userOwnerGroup->name : '') : '',
+                $area->owner ? ($area->owner->customer ? $area->owner->customer->name : '') : '',
+                $area->owner ? $area->owner->name : '',
+                $area->counting_month,
+                $area->updated_at,
+                $area->owner ? implode(",",array_unique(array_column(($area->owner->ownerStoragePriceModels)->toArray(),"using_type"))) : '',
+                $area->area_on_tray,
+                $area->area_on_half_tray,
+                $area->area_on_flat,
+                $area->accounting_area,
+            ];
+        }
+
+        $post = Http::post(config('go.export.url'),['type'=>'base','data'=>json_encode(["row"=>$column,"list"=>$list],JSON_UNESCAPED_UNICODE)]);
+        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',
+        ]);
+    }
+
+    public function financeInstantBill(Request $request)
     {
         if(!Gate::allows('客户管理-财务-即时账单')){ return redirect('denied');  }
-        return response()->view('customer.finance.instantBill');
+        $params = $request->input();
+        $shops = app('ShopService')->getSelection();
+        $customers = app('CustomerService')->getSelection();
+        $owners = app('OwnerService')->getSelection();
+        $details = app('OwnerFeeDetailService')->paginate($params,["owner"=>function($query){$query->with("customer");},"shop","processMethod","logistic"]);
+        return response()->view('customer.finance.instantBill',compact("details","params","shops","customers","owners"));
     }
 
-    public function financeBillConfirmation()
+    public function financeInstantBillExport(Request $request)
+    {
+        if(!Gate::allows('客户管理-财务-即时账单')){ return redirect('denied');  }
+        $params = $request->input();
+        if ($request->checkAllSign)unset($params['checkAllSign']);
+        else $params = ["id"=>$request->data];
+        $sql = app('OwnerFeeDetailService')->getSql($params);
+
+        $row = ["客户", "项目", "作业时间", "类型","店铺", "单号(发/收/退/提)", "收件人", "收件人电话", "商品数量",
+            "物流/快递单号", "体积", "重量", "承运商", "操作费", "物流费", "合计"];
+        $column = ["customer_name", "owner_name", "worked_at", "type","shop_name", "operation_bill", "consignee_name", "consignee_phone", "commodity_amount",
+            "logistic_bill", "volume", "weight", "logistic_name", "work_fee", "logistic_fee", "total"];
+        $rule = ["work_fee"=>"mysqlDate"];
+
+        $post = Http::post(config('go.export.url'),['type'=>'unify','sql'=>$sql, 'connection'=>'mysql',
+            'row'=>json_encode($row,JSON_UNESCAPED_UNICODE), 'column'=>json_encode($column), 'rule'=>json_encode($rule)]);
+        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',
+        ]);
+    }
+
+    public function financeBillConfirmation(Request $request)
     {
         if(!Gate::allows('客户管理-财务-账单确认')){ return redirect('denied');  }
-        return response()->view('customer.finance.billConfirmation');
+        $params = $request->input();
+        $ownerGroups = app('UserOwnerGroupService')->getSelection();
+        $customers = app('CustomerService')->getSelection();
+        $owners = app('OwnerService')->getSelection();
+        $bills = app('OwnerBillReportService')->paginate($params,["owner"=>function($query){
+            /** @var Builder $query */
+            $query->with(["customer","userOwnerGroup"]);
+        }]);
+        return response()->view('customer.finance.billConfirmation',compact("params","owners","ownerGroups","customers","bills"));
+    }
+
+    public function financeBillConfirmationExport(Request $request)
+    {
+        if(!Gate::allows('客户管理-财务-账单确认')){ return redirect('denied');  }
+        $params = $request->input();
+        if ($request->checkAllSign)unset($params['checkAllSign']);
+        else $params = ["id"=>$request->data];
+        /** @var OwnerBillReportService $serves */
+        $serves = app('OwnerBillReportService');
+        $bills = $serves->get($params,["owner"=>function($query){
+            /** @var Builder $query */
+            $query->with(["customer","userOwnerGroup"]);
+        }]);
+
+        $column = ["项目小组","客户","子项目","结算月","录入日期","原始账单金额","确认账单金额","差额","状态"];
+        $list = [];
+        foreach ($bills as $bill){
+            $list[] = [
+                $bill->owner ? ($bill->owner->userOwnerGroup ? $bill->owner->userOwnerGroup->name : '') : '',
+                $bill->owner ? ($bill->owner->customer ? $bill->owner->customer->name : '') : '',
+                $bill->owner ? $bill->owner->name : '',
+                $bill->counting_month,
+                $bill->updated_at,
+                $bill->initial_fee,
+                $bill->confirm_fee,
+                $bill->difference,
+                $bill->confirmed == '是' ? '已确认' : '未确认',
+            ];
+        }
+
+        $post = Http::post(config('go.export.url'),['type'=>'base','data'=>json_encode(["row"=>$column,"list"=>$list],JSON_UNESCAPED_UNICODE)]);
+        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',
+        ]);
+    }
+
+    public function updateBillReport(Request $request)
+    {
+        if(!Gate::allows('客户管理-财务-账单确认-编辑')){ return ["success"=>false,'data'=>"无权操作!"];  }
+        if (!$request->confirm_fee || !is_numeric($request->confirm_fee) || $request->confirm_fee<0)return ["success"=>false,"data"=>"非法金额参数"];
+        $date = date('Y-m-d H:i:s');
+        app('OwnerBillReportService')->update(["id"=>$request->id],["confirm_fee"=>$request->confirm_fee,"difference"=>DB::raw($request->confirm_fee.'- initial_fee'),"updated_at"=>$date]);
+        return ["success"=>true,"data"=>$date];
+    }
+
+    public function billConfirm(Request $request)
+    {
+        if(!Gate::allows('客户管理-财务-账单确认-完结')){ return ["success"=>false,'data'=>"无权操作!"];  }
+        if (!($request->id ?? false))return["success"=>false,"data"=>"非法参数"];
+        app('OwnerBillReportService')->update(["id"=>$request->id],["confirmed"=>"是"]);
+        return ["success"=>true];
+    }
+
+    private function validator(array $params){
+        $id = $params['id'] ?? null;
+        $validator=Validator::make($params,[
+            'id' => ['required_without_all:code,name'],
+            'code'=>['required','max:50',$id ? "unique:owners,code,$id":'unique:owners,code'],
+            'name'=>['required','max:50'],
+            'customer_id'=>['required'],
+            'owner_group_id'=>['required'],
+            'tax_rate' => ['required','numeric'],
+        ],[
+            'required'=>':attribute 为必填项',
+            'unique'=>':attribute 已存在',
+        ],[
+            'code'=>'项目代码',
+            'name'=>'项目名称',
+            'customer_id'=>'客户',
+            'owner_group_id'=>'工作组',
+            'tax_rate' => '税率'
+        ]);
+        return $validator;
     }
 }

+ 0 - 84
app/Http/Controllers/JobTypeController.php

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

+ 14 - 5
app/Http/Controllers/LaborReportController.php

@@ -122,12 +122,12 @@ class LaborReportController extends Controller
             'status'=>'已入场',
         ]);
         $laborReportStatus->save();
-        app('LogService')->log(__METHOD__,"门卫打卡审核创建当前临时工报表状态".__FUNCTION__,json_encode($laborReportStatus),Auth::user()['id']);
+        app('LogService')->log(__METHOD__,"门卫打卡审核修改当前临时工报表状态".__FUNCTION__,json_encode($laborReportStatus),Auth::user()['id']);
         $userDutyCheck=UserDutyCheck::find($userDutyCheckId);
         $userDutyCheck->verify_user_id=Auth::user()['id'];
         $userDutyCheck->update();
-        event(new GuardAuditEvent($userDutyCheck));
         app('LogService')->log(__METHOD__,"门卫打卡审核".__FUNCTION__,json_encode($userDutyCheck),Auth::user()['id']);
+        event(new GuardAuditEvent($userDutyCheck));
         return ["success"=>true,"data"=>$userDutyCheck->verify_user_id];
     }
     //打卡组长审核
@@ -153,7 +153,11 @@ class LaborReportController extends Controller
         $laborReport->group_user_id=Auth::user()['id'];
         $laborReport->verify_at=date('Y-m-d H:i:s');
         $laborReport->update();
-        $laborReport->setRemarkAttribute($remark,$id);
+        /**
+         * @var LaborReportService $laborReportService
+         */
+        $laborReportService=app(LaborReportService::class);
+        $laborReportService->addOrUpdateRemark($remark,$id);
         $laborReport->verifyPerson=Auth::user()['name'];
         app('LogService')->log(__METHOD__,"打卡组长审核并添加相应备注".__FUNCTION__,json_encode($laborReport),Auth::user()['id']);
         event(new TeamAuditEvent($laborReport));
@@ -262,8 +266,9 @@ class LaborReportController extends Controller
     //回收站
     function recycle(Request $request){
         if(!Gate::allows('人事管理-临时工报表-删除')){ return redirect('/');  }
+        $paginateParams=$request->input();
         $laborReports=LaborReport::query()->with(['user','userDutyCheck','userWorkgroup','laborCompany'])->onlyTrashed()->paginate($request->paginate??50);
-        return view('personnel.laborReport.recycle',compact('laborReports'));
+        return view('personnel.laborReport.recycle',compact('laborReports','paginateParams'));
     }
 
     //回收站恢复
@@ -281,7 +286,11 @@ class LaborReportController extends Controller
             return ['success'=>false,'fail_info'=>'参数异常'];
         }
         $laborReport=LaborReport::find($laborReportId);
-        $laborReport->setRemarkAttribute($laborReportRemark,$laborReportId);
+        /**
+         * @var LaborReportService $laborReportService
+         */
+        $laborReportService=app(LaborReportService::class);
+        $laborReportService->addOrUpdateRemark($laborReportRemark,$laborReportId);
         app('LogService')->log(__METHOD__,'添加或者修改临时工报表备注'.__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         return ['success'=>true,'status'=>$laborReport];
     }

+ 57 - 33
app/Http/Controllers/OrderIssueController.php

@@ -101,7 +101,7 @@ class OrderIssueController extends Controller
 
     public function batchImport(Request $request)
     {
-        if (!Gate::allows('订单管理-订单问题件生成')) {
+        if (!Gate::allows('订单管理-问题件-导入-Excel导入')) {
             return redirect(url('/'));
         }
         $file = $request->file('file');
@@ -155,7 +155,7 @@ class OrderIssueController extends Controller
 
     public function excelImport()
     {
-        if (!Gate::allows('订单管理-订单问题件生成')) {
+        if (!Gate::allows('订单管理-问题件-导入')) {
             return redirect(url('/'));
         }
         return view('order.issue.import');
@@ -172,6 +172,10 @@ class OrderIssueController extends Controller
         /** @var OrderIssueService $orderIssueService */
         $orderIssueService = app(OrderIssueService::class);
         $exits_orderNos = $orderIssueService->校验问题件是否存在_WMS订单号_返回存在的订单号($request->input('orderNos'));
+        $count = OracleDOCOrderHeader::query()->with('oracleBASCode')->whereIn('OrderNo',$request['orderNos'])->whereHas('oracleBASCode',function($query){
+            $query->whereNotIn('codename_c',['完全装箱','订单完成','完全发运','分配完成']);
+        })->count();
+        if($count>0)return ['success'=>false,'fail_info'=>'勾选的订单中有没有完成的订单,请取消勾选'];
         if(count($exits_orderNos)>0){
             return ['success'=>false,'fail_info'=>'标记问题件存在已有订单号','exitsOrderNos' =>$exits_orderNos];
         }
@@ -497,7 +501,7 @@ class OrderIssueController extends Controller
 
     public function importPasteDataApi(Request $request)
     {
-        if (!Gate::allows('订单管理-订单问题件生成'))
+        if (!Gate::allows('订单管理-问题件-导入-文本导入'))
             return ['success'=>false,'fail_info'=>'没有对应权限'];
         $rows = $request->input('rows');
         $logistic_numbers = [];
@@ -516,7 +520,11 @@ class OrderIssueController extends Controller
 //            $string= preg_replace('/[\s,\,\,]+/','*++*',$str);
 //            $items = explode('*++*',$string);
             $items=[];
+
             preg_match('/^(\w*?)[\s,,;;]([\x{4e00}-\x{9fa5}]*?)[\s,,;;](.*?)[\s,,;;](\w*?)$/u', $str, $items);
+            if(count($items) == 0){
+                preg_match('/^(\w*?)[\s,,;;]([\x{4e00}-\x{9fa5}]*?)[\s,,;;](.*?)$/u', $str, $items);
+            }
             array_shift($items);
             $head = '第'.($i+1).'行';
             if(count($items)<count($rows)-1){
@@ -583,7 +591,7 @@ class OrderIssueController extends Controller
                 $result_explain = $map['result_explain'];
                 $type = $map['type'];
                 $custom_code = $map['custom_code'] ?? null;
-                $service->createOrderIssue($logistic_number, $type, $result_explain,'导入未处理',$custom_code);
+                $service->createOrderIssue($logistic_number, $type, $result_explain,'导入未处理',$custom_code,$request['hiddenTag'] ?? null);
             }
             return ['success'=>true];
         } catch (Exception $e) {
@@ -626,39 +634,39 @@ class OrderIssueController extends Controller
             $orderPacakges = $order_issue->order->packages ?? collect();
             $logistic_numbers = '';$order_sku  = '';$order_sku_name  = '';$order_sku_amount  = '';
             $orderPacakges->each(function($package,$index)use(&$logistic_numbers,&$order_sku,&$order_sku_name,&$order_sku_amount){
-                $logistic_numbers.=$package->logistic_number."\r\n";
+                if(!str_starts_with('null',$package->logistic_number))$logistic_numbers.=$package->logistic_number.",\r\n";
                 $package->commodities->each(function($commodities)use(&$order_sku,&$order_sku_name,&$order_sku_amount){
                     $commodity = $commodities->commodity ?? '';
-                    $order_sku.= ($commodity->sku ?? '')."\r\n";
-                    $order_sku_name.= ($commodity->name ?? '')."\r\n";
-                    $order_sku_amount.= ($commodities->amount ?? '')."\r\n";
+                    $order_sku.= ($commodity->sku ?? '').",\r\n";
+                    $order_sku_name.= ($commodity->name ?? '').",\r\n";
+                    $order_sku_amount.= ($commodities->amount ?? '').",\r\n";
                 });
             });
             $rejected_Bill_remark = $order_issue->rejectedBill->remark ?? '';
             $rejected_name = ''; $rejected_barcode = '';$rejected_amount = '';
             if($order_issue->rejectedBill){
                 $order_issue->rejectedBill->items(function($item)use(&$rejected_name,&$rejected_barcode, &$rejected_amount){
-                    $rejected_name.= $item->name_goods."\r\n";
-                    $rejected_barcode.= $item->barcode_goods."\r\n";
-                    $rejected_amount.= $item->amount."\r\n";
+                    $rejected_name.= $item->name_goods.",\r\n";
+                    $rejected_barcode.= $item->barcode_goods.",\r\n";
+                    $rejected_amount.= $item->amount.",\r\n";
                 });
             }
 
             $log_type = ''; $log_content = '';$log_user = '';
             $order_issue->logs->each(function($log)use(&$log_type, &$log_content,&$log_user){
-                $log_type.=$log->type."\r\n";
-                $log_content.=$log->content."\r\n";
-                $log_user.=$log->user->name."\r\n";
+                $log_type.=$log->type.",\r\n";
+                $log_content.=$log->content.",\r\n";
+                $log_user.=$log->user->name.",\r\n";
             });
             $send_order = $order_issue->secondOrder ??  new Order();
             $send_order_numbers = '';$send_order_sku ='';$send_order_name ='';$send_order_amount = '';
             $send_order->packages->each(function($package)use(&$send_order_numbers ,&$send_order_sku ,&$send_order_name ,&$send_order_amount ){
-                $send_order_numbers.=($package->logistic_number)."\r\n";
+                $send_order_numbers.=($package->logistic_number).",\r\n";
                 $package->commodities->each(function ($commodities)use( &$send_order_sku ,&$send_order_name ,&$send_order_amount ){
                     $commodity = $commodities->commodity;
-                    $send_order_sku.=$commodity->sku."\r\n";
-                    $send_order_name.=$commodity->name."\r\n";
-                    $send_order_amount.=$commodities->amount."\r\n";
+                    $send_order_sku.=$commodity->sku.",\r\n";
+                    $send_order_name.=$commodity->name.",\r\n";
+                    $send_order_amount.=$commodities->amount.",\r\n";
                 });
             });
 
@@ -675,22 +683,22 @@ class OrderIssueController extends Controller
                 $order->district,               // 区
                 $order->address,                // 收货人地址
 
-                $logistic_numbers,              //原始运单号
-                $order_sku,                     //原始商品
-                $order_sku_name,                //原始商品名称
-                $order_sku_amount,              //原始商品数量
+                rtrim($logistic_numbers,",\r\n"),              //原始运单号
+                rtrim($order_sku,",\r\n"),                     //原始商品
+                rtrim($order_sku_name,",\r\n"),                //原始商品名称
+                rtrim($order_sku_amount,",\r\n"),              //原始商品数量
 
                 //'退单备注','退单商品名','退单商品条码','退单商品数量','退单状态',
-                $rejected_Bill_remark,                                          // 退单备注
-                $rejected_name,        // 退单商品名
-                $rejected_barcode ,    // 退单商品条码
-                $rejected_amount,      // 退单商品数量
+                rtrim($rejected_Bill_remark,",\r\n"),                                          // 退单备注
+                rtrim($rejected_name,",\r\n"),        // 退单商品名
+                rtrim($rejected_barcode,",\r\n") ,    // 退单商品条码
+                rtrim($rejected_amount,",\r\n"),      // 退单商品数量
                 $order_issue->rejecting_status ,                                // 退单状态
 
                 // '操作类型','情况说明','问题类别',
-                $log_type,                        //操作类型
-                $log_content,                     //情况说明
-                $log_user,                        //操作者
+                rtrim($log_type,",\r\n"),                        //操作类型
+                rtrim($log_content,",\r\n"),                     //情况说明
+                rtrim($log_user,",\r\n"),                        //操作者
 
                 // '情况说明','问题类别',
                 $order_issue->result_explain,                               // 情况说明
@@ -699,10 +707,10 @@ class OrderIssueController extends Controller
                 // '二次订单号','二次承运商','二次运单号','二次商品条码','二次商品名','二次商品数量',
                 $order_issue->secondOrder->client_code ?? '',                //二次订单号
                 $order_issue->secondOrder->logistic->name ?? '',             //二次承运商
-                $send_order_numbers ,                                        //二次运单号
-                $send_order_sku,                                             // 二次商品条码
-                $send_order_name,                                            // 二次商品名
-                $send_order_amount,                                          // 二次商品数量
+                rtrim($send_order_numbers,",\r\n") ,                                        //二次运单号
+                rtrim($send_order_sku,",\r\n"),                                             // 二次商品条码
+                rtrim($send_order_name,",\r\n"),                                            // 二次商品名
+                rtrim($send_order_amount,",\r\n"),                                          // 二次商品数量
 
                 //'最终状态', '承运商赔偿金额', '承运商快递减免', '宝时赔偿金额', '宝时快递减免','事故责任方'
                 $order_issue->final_status??'',
@@ -742,4 +750,20 @@ class OrderIssueController extends Controller
         $service = app('OrderIssueService');
         return  $service->recoverOrderIssue($request['ids']);
     }
+
+    public function financeConfirmApi(Request $request)
+    {
+        if (!Gate::allows('订单管理-问题件-财务确认')) {
+            return ['success'=>false,'error'=>'没有对应权限'];
+        }
+        try {
+            $bool = OrderIssue::query()->whereIn('id', $request['ids'])->update(['finance_confirm' => '是']);
+            if($bool==false)return ['success'=>false,'error'=>'财务确认失败'];
+            app('LogService')->log(__METHOD__, __FUNCTION__,'财务确认'. json_encode($request->getContent()), Auth::user()['id']);
+            return ['success'=>true];
+        } catch (Exception $e) {
+            app('LogService')->log(__METHOD__,'Error'. __FUNCTION__,'财务确认 Error'. json_encode($request->getContent()).' || '.json_encode($e->getMessage()).' || '.json_encode($e->getTraceAsString()), Auth::user()['id']);
+            return ['success'=>false,'error'=>$e->getMessage()];
+        }
+    }
 }

+ 9 - 2
app/Http/Controllers/OrderTrackingController.php

@@ -11,6 +11,7 @@ use App\Services\OwnerService;
 use App\UploadFile;
 use Exception;
 use Illuminate\Http\Request;
+use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Http;
 use Intervention\Image\Facades\Image;
@@ -21,11 +22,14 @@ class OrderTrackingController extends Controller
 
     public function index(Request $request)
     {
+        /**
+         * @var OrderTrackingService $service
+         */
         if (!Gate::allows('订单管理-跟踪'))
             return redirect(url('/'));
         $owners =  app(OwnerService::class)->getAuthorizedOwners();
-        /** @var OrderTrackingService $service */
         $service = app('OrderTrackingService');
+        $service->fillInOrderTracking();
         $trackOrders = $service->paginate($request->input());
         $trackOrders->map(function($trackOrder){
             if($trackOrder->uploadFile){
@@ -157,7 +161,7 @@ class OrderTrackingController extends Controller
         $order_client_code_temp = '';
         $row_count = 0;
         foreach ($orderTrackings as $index=> $orderTracking) {
-            $logistic =  $orderTracking->commodities->package->order->logistic->name;
+            $logistic =  $orderTracking->commodities->package->order->logistic->name ?? '';
             if($order_client_code_temp==''){
                 $order_client_code_temp=$orderTracking->order_client_code;
                 $row_count=1;
@@ -190,6 +194,9 @@ class OrderTrackingController extends Controller
             if($logistic=='新杰物流'||$logistic=='新杰物流到付'){
                 $logistic_number = $orderTracking->order_client_code;
             }
+            if(str_starts_with('null',$logistic_number)){
+                $logistic_number = '';
+            }
             $list[]=[
                 $orderTracking->owner->name ?? '',
                 $order_client_code,

+ 16 - 6
app/Http/Controllers/PersonnelController.php

@@ -33,6 +33,7 @@ class PersonnelController extends Controller
         $user_id=$request->input('user_id');
         $checked_at=$request->input('checked_at');
         $type=$request->input('type');
+        $remark=$request->input('remark');
         $userDutyCheck=new UserDutyCheck([
             'user_id'=>$user_id,
             'checked_at'=>$checked_at,
@@ -40,27 +41,26 @@ class PersonnelController extends Controller
             'source'=>'补入',
         ]);
         $checkedAtDate=Carbon::parse($checked_at)->format('Y-m-d');
-//        $userDutyCheckImport=UserDutyCheck::where('user_id',$user_id)->where('checked_at','like',$checkedAtDate.'%')->where('type','登入')->orderBy('id','desc')->first();
-//        if ($userDutyCheckImport&&$userDutyCheck->type=='登入')return ['result'=>true,'data'=>'已存在进场记录!'];
-//        $userDutyCheckExport=UserDutyCheck::where('user_id',$user_id)->where('checked_at','like',$checkedAtDate.'%')->where('type','登出')->orderBy('id','desc')->first();
-//        if ($userDutyCheckExport&&$userDutyCheck->type=='登出')return ['result'=>true,'data'=>'已存在出场记录!'];
         $userDutyCheckBefore=UserDutyCheck::where('user_id',$user_id)->where('checked_at','like',$checkedAtDate.'%')->orderBy('id','desc')->first();
         if ($userDutyCheckBefore['type']=='登入'&&$userDutyCheck->type=='登入')return ['result'=>true,'data'=>'已存在进场记录!'];
         if ($userDutyCheckBefore['type']=='登出'&&$userDutyCheck->type=='登出')return ['result'=>true,'data'=>'已存在出场记录!'];
         if ($type=='登出')$userDutyCheck->verify_user_id=Auth::user()['id'];
         $userDutyCheck->save();
         app('LogService')->log(__METHOD__,"录入补卡".__FUNCTION__,json_encode($userDutyCheck),Auth::user()['id']);
-        $errorMessage=$this->makeOrUpdateLaborReport($userDutyCheck);
+        $errorMessage=$this->makeOrUpdateLaborReport($userDutyCheck,$remark);
         if ($errorMessage)return $errorMessage;
         return ['success'=>true,'data'=>$userDutyCheck];
     }
     //补卡创建或修改临时工报表
-    public function makeOrUpdateLaborReport($userDutyCheck){
+    public function makeOrUpdateLaborReport($userDutyCheck,$remark){
         $checkedAtDate=Carbon::parse($userDutyCheck->checked_at)->format('Y-m-d');
         $laborReport=LaborReport::where('user_id',$userDutyCheck->user_id)->where('created_at','like',$checkedAtDate.'%')->orderBy('id','desc')->first();
         $laborReportService = app('LaborReportService');
         if (!$laborReport&&$userDutyCheck->type=='登入'){
             $newReport=$userDutyCheck->makeEnteringRecord();
+            /** @var LaborReportService $laborReportService */
+            $laborReportService=app(LaborReportService::class);
+            $laborReportService->addOrUpdateRemark($remark,$newReport->id);
             app('LogService')->log(__METHOD__,"进场创建临时工报表记录__".__FUNCTION__,json_encode([$userDutyCheck]));
             if ($newReport) event(new ImportEvent($newReport));
         }
@@ -74,6 +74,10 @@ class PersonnelController extends Controller
             }
             if ($laborReportYesterday){
                 $exportReport=$laborReportService->exportReplenishToCreateLaborReportData($laborReportYesterday,$userDutyCheck);
+                if ($exportReport->remark) $remark=$exportReport->remark.','.$remark;
+                /** @var LaborReportService $laborReportService */
+                $laborReportService=app(LaborReportService::class);
+                $laborReportService->addOrUpdateRemark($remark,$exportReport->id);
                 app('LogService')->log(__METHOD__,"补退场卡修改临时工报表记录__".__FUNCTION__,json_encode([$laborReportYesterday,$userDutyCheck]));
                 if ($exportReport) event(new ExportEvent($exportReport));
             }
@@ -83,6 +87,10 @@ class PersonnelController extends Controller
                 return ['result'=>true,'data'=>'该临时工还未退组,暂不可补退场卡!'];
             }
             $exportReport=$laborReportService->exportReplenishToCreateLaborReportData($laborReport,$userDutyCheck);
+            if ($exportReport->remark) $remark=$exportReport->remark.','.$remark;
+            /** @var LaborReportService $laborReportService */
+            $laborReportService=app(LaborReportService::class);
+            $laborReportService->addOrUpdateRemark($remark,$exportReport->id);
             app('LogService')->log(__METHOD__,"补退场卡修改临时工报表记录__".__FUNCTION__,json_encode([$laborReport,$userDutyCheck]));
             if ($exportReport) event(new ExportEvent($exportReport));
         }
@@ -91,6 +99,8 @@ class PersonnelController extends Controller
 
 
 
+
+
     //任务审核
     public function storeMissionAudit(Request $request){
         if(!Gate::allows('人事管理-任务审核')){ return redirect(url('/'));  }

+ 866 - 17
app/Http/Controllers/PriceModelController.php

@@ -2,61 +2,910 @@
 
 namespace App\Http\Controllers;
 
+use App\Imports\ExpressImport;
+use App\Imports\OwnerPriceDirectLogisticDetailImport;
+use App\Imports\OwnerPriceLogisticDetailImport;
+use App\Owner;
+use App\OwnerOutStorageRule;
+use App\OwnerPriceDirectLogistic;
+use App\OwnerPriceExpress;
+use App\OwnerPriceExpressProvince;
+use App\OwnerPriceLogistic;
+use App\OwnerPriceOperation;
+use App\Services\common\ExportService;
+use App\Services\OwnerOutStorageRuleService;
+use App\Services\OwnerPriceOperationService;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Validator;
+use Maatwebsite\Excel\Facades\Excel;
 
 class PriceModelController extends Controller
 {
-    public function storeIndex()
+    public function storageIndex(Request $request)
     {
         if(!Gate::allows('计费模型-仓储')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.storage.index');
+        $models = app('OwnerStoragePriceModelService')->paginate($request->input("id"),["unit"]);
+        return response()->view('maintenance.priceModel.storage.index',compact("models"));
     }
 
-    public function storeCreate()
+    public function storageCreate()
     {
         if(!Gate::allows('计费模型-仓储-录入')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.storage.create');
+        $units = app('UnitService')->getSelection();
+        return response()->view('maintenance.priceModel.storage.create',compact("units"));
     }
 
-    public function operationIndex(){
+    public function storageStore(Request $request)
+    {
+        if(!Gate::allows('计费模型-仓储-录入')){ return redirect('denied');  }
+        $this->storageValidator($request->input())->validate();
+        app('OwnerStoragePriceModelService')->create($request->input());
+        return response()->redirectTo('maintenance/priceModel/storage')->with('successTip',"创建成功!");
+    }
+
+    public function storageEdit($id)
+    {
+        if(!Gate::allows('计费模型-仓储-编辑')){ return redirect('denied');  }
+        $model = app('OwnerStoragePriceModelService')->find($id);
+        $units = app('UnitService')->getSelection();
+        return response()->view('maintenance.priceModel.storage.create',compact("units","model"));
+    }
+
+    public function storageUpdate(Request $request)
+    {
+        if(!Gate::allows('计费模型-仓储-编辑')){ return redirect('denied');  }
+        app('OwnerStoragePriceModelService')->update(["id"=>$request->input("id")],[
+            "counting_type" => $request->input("counting_type"),
+            "using_type"    => $request->input("using_type"),
+            "minimum_area"  => $request->input("minimum_area"),
+            "price"         => $request->input("price"),
+            "discount_type" => $request->input("discount_type"),
+            "discount_value"=> $request->input("discount_value"),
+            "unit_id"       => $request->input("unit_id"),
+        ]);
+        return response()->redirectTo('maintenance/priceModel/storage')->with('successTip',"更新成功!");
+    }
+
+    public function storageDestroy($id)
+    {
+        app("OwnerStoragePriceModelService")->destroy($id);
+        return ["success"=>true];
+    }
+
+    private function storageValidator(array $params)
+    {
+        return Validator::make($params,[
+            'counting_type'=>['required'],
+            'using_type'=>['required'],
+            'minimum_area'=>['nullable','numeric','min:0'],
+            'discount_value'=>['nullable','numeric','min:0'],
+            'price'=>['required','numeric','min:0'],
+            'discount_type'=>['required'],
+            'unit_id'=>['required','integer'],
+        ],[
+            'required'=>':attribute 为必填项',
+            'min'=>':attribute 不得小于0',
+            'integer'=>':attribute 未选择',
+        ],[
+            'counting_type' =>"计费类型",
+            'using_type'    =>"用仓类型",
+            'minimum_area'  =>"最低起租面积",
+            'price'         =>"单价",
+            'discount_type' =>"减免类型",
+            'discount_value'=>"减免值",
+            'unit_id'       =>"单位",
+        ]);
+    }
+
+    public function operationIndex(Request $request){
         if(!Gate::allows('计费模型-作业-查询')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.operation.index');
+        $features = app("FeatureService")->getMapArray();
+        OwnerPriceOperation::$features = $features;
+        $models = app('OwnerPriceOperationService')->paginate($request->input(),["ownerPriceOperationOwners","ownerInStorageRule"=>function($query){$query->with("unit");}])->append("featureFormat");
+        $owners = app("OwnerService")->getSelection();
+        return response()->view('maintenance.priceModel.operation.index',compact("models","owners"));
+    }
+
+    /* 获取出库模型规则 */
+    public function operationGetOutStorageRule(Request $request)
+    {
+        if(!Gate::allows('计费模型-作业-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        /** @var OwnerOutStorageRuleService $service */
+        $service = app('OwnerOutStorageRuleService');
+        $ownerOutStorageRules = $service->get(["owner_price_operation_id"=>$request->input("id")],["unit"],true)->append("featureFormat");
+        return ["success"=>true,"data"=>$ownerOutStorageRules];
+    }
+    /* 修改出库模型规则 */
+    public function updateOutStorageRule(Request $request)
+    {
+        if(!Gate::allows('计费模型-作业-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
+        /** @var OwnerOutStorageRuleService $service */
+        $service = app('OwnerOutStorageRuleService');
+        $row = $service->update(["id"=>$request->input("id")],[
+            "amount"=>$request->input("amount"),
+            "unit_id"=>$request->input("unit_id"),
+            "priority"=>$request->input("priority"),
+            "unit_price"=>$request->input("unit_price")]);
+        if ($row == 1) return ["success"=>true];
+        return ["success"=>false,"data"=>"受影响数据数为:".$row];
+    }
+
+    public function createOutStorageRule(Request $request)
+    {
+        if(!Gate::allows('计费模型-作业-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
+        /** @var OwnerOutStorageRuleService $service */
+        $service = app('OwnerOutStorageRuleService');
+        switch ($request->input("strategy")){
+            case "起步":
+                $c = $service->isExist(["owner_price_operation_id"=>$request->input("owner_price_operation_id"),"strategy"=>"起步"]);
+                if ($c > 0)return ["success"=>false,"data"=>"已存在起步策略"];
+                break;
+            case "默认":
+                $c = $service->isExist(["owner_price_operation_id"=>$request->input("owner_price_operation_id"),"strategy"=>"默认"]);
+                if ($c > 0)return ["success"=>false,"data"=>"已存在默认策略"];
+                break;
+        }
+        $data = $service->create($request->input());
+        $data->load("unit");
+        return ["success"=>true,"data"=>$data];
+    }
+    public function getFeatures(Request $request)
+    {
+        return ["success"=>true,"data"=>app("FeatureService")->translationFeature($request->input("feature"))];
+    }
+
+    public function addFeature(Request $request)
+    {
+        if(!Gate::allows('计费模型-作业-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $id = $request->input("id");
+        $features = $request->input("features");
+        if (!$id || !$features)return ["success"=>false,"data"=>"非法参数"];
+        $result = app("FeatureService")->analysisFeature($features);
+        $feature = $result["feature"];
+        $stack = [];
+        if ($feature && ($feature[0]=='|' || $feature[0]=='&'))$feature=substr($feature,1);
+        for ($i=0;$i<strlen($feature);$i++){
+            if ($feature[$i] == '(')array_unshift($stack,'(');
+            if ($feature[$i] == ')'){
+                if (count($stack) == 0)return ["success"=>false,"data"=>"组标记错误,起始与结束标记必须对应"];
+                array_shift($stack);
+            }
+        }
+        if (count($stack) > 0)return ["success"=>false,"data"=>"组标记错误,起始与结束标记必须对应"];
+        $row = app('OwnerOutStorageRuleService')->update(["id"=>$id],["feature"=>$feature]);
+        if ($row != 1)return ["success"=>false,"data"=>"影响了“".$row."”行"];
+        OwnerOutStorageRule::$features = $result["map"];
+        $rule = app('OwnerOutStorageRuleService')->find($id)->append("featureFormat");
+        return ["success"=>true,"data"=>["featureFormat"=>$rule->featureFormat,"feature"=>$feature]];
+    }
+
+    public function getFeature(Request $request)
+    {
+        $features = $request->input("features");
+        if (!$features)return ["success"=>false,"data"=>"非法参数"];
+        $result = app("FeatureService")->analysisFeature($features);
+        $feature = $result["feature"];
+        $stack = [];
+        if ($feature && ($feature[0]=='|' || $feature[0]=='&'))$feature=substr($feature,1);
+        for ($i=0;$i<strlen($feature);$i++){
+            if ($feature[$i] == '(')array_unshift($stack,'(');
+            if ($feature[$i] == ')'){
+                if (count($stack) == 0)return ["success"=>false,"data"=>"组标记错误,起始与结束标记必须对应"];
+                array_shift($stack);
+            }
+        }
+        if (count($stack) > 0)return ["success"=>false,"data"=>"组标记错误,起始与结束标记必须对应"];
+        return ["success"=>true,"data"=>$feature];
+    }
+
+    public function operationDestroy($id)
+    {
+        if(!Gate::allows('计费模型-作业-删除')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $row = app("OwnerPriceOperationService")->destroy($id);
+        if ($row == 1)return ["success"=>true];
+        return ["success"=>false,"data"=>"影响了“".$row."”行"];
     }
 
     public function operationCreate(){
         if(!Gate::allows('计费模型-作业-录入')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.operation.create');
+        $owners = app("OwnerService")->getSelection();
+        $units = app('UnitService')->getSelection();
+        return response()->view('maintenance.priceModel.operation.create',compact("owners","units"));
     }
 
-    public function expressIndex(){
+    public function operationStore(Request $request)
+    {
+        if(!Gate::allows('计费模型-作业-录入')){ return redirect('denied');  }
+        $request->offsetSet("rules",json_decode($request->input("rules"),true));
+        $request->offsetSet("owner_id",explode(',',$request->input("owner_id")));
+        $this->operationValidator($request->input())->validate();
+
+        //录入主表
+        /** @var OwnerPriceOperationService $service */
+        $service = app("OwnerPriceOperationService");
+        $ownerPriceOperation = $service->create([
+            "operation_type" => $request->input("operation_type"),
+            "strategy" => $request->input("strategy"),
+            "name" => $request->input("name"),
+            "priority" => $request->input("priority"),
+            "remark" => $request->input("remark"),
+            "feature" => $request->input("feature"),
+        ]);
+        //录入子表
+        if ($request->input("operation_type") == '入库') $service->insertRule([
+            "owner_price_operation_id" => $ownerPriceOperation->id,
+            "amount" => $request->input("rules")[0]["amount"],
+            "unit_id" => $request->input("rules")[0]["unit_id"],
+            "unit_price" => $request->input("rules")[0]["unit_price"],
+        ],"入库");
+        else{
+            $insert = [];
+            foreach ($request->input("rules") as $rule){
+                $insert[] = [
+                    "owner_price_operation_id" => $ownerPriceOperation->id,
+                    "amount" => $rule["amount"],
+                    "unit_id" => $rule["unit_id"],
+                    "unit_price" => $rule["unit_price"],
+                    "strategy" => $rule["strategy"],
+                    "feature" => $rule["feature"],
+                    "priority" => $rule["priority"],
+                ];
+            }
+            $service->insertRule($insert);
+        }
+        //录入中间表
+        /** @var OwnerPriceOperation $model */
+        if ($request->input("owner_id"))$model->ownerPriceOperationOwners()->sync($request->input("owner_id"));
+        return response()->redirectTo("maintenance/priceModel/operation")->with("successTip","创建“".$request->input("name")."”成功");
+    }
+
+    public function operationEdit($id)
+    {
+        if(!Gate::allows('计费模型-作业-编辑')){ return redirect('denied');  }
+        $model = app('OwnerPriceOperationService')->find($id,true,["ownerPriceOperationOwners"]);
+        $owners = app("OwnerService")->getSelection();
+        $units = app('UnitService')->getSelection();
+        return response()->view('maintenance.priceModel.operation.create',compact("owners","units","model"));
+    }
+
+    public function operationUpdate($id,Request $request)
+    {
+        if(!Gate::allows('计费模型-作业-编辑')){ return redirect('denied');  }
+        $request->offsetSet("rules",json_decode($request->input("rules"),true));
+        $request->offsetSet("owner_id",explode(',',$request->input("owner_id")));
+        $this->operationValidator($request->input(),$id)->validate();
+
+        /** @var OwnerPriceOperationService $service */
+        $service = app("OwnerPriceOperationService");
+
+        $model = $service->find($id);
+        $service->findUpdate($model,[
+            "name" => $request->input("name"),
+            "priority" => $request->input("priority"),
+            "remark" => $request->input("remark"),
+            "feature" => $request->input("feature"),
+        ]);
+        $service->destroyRule($id, $model->operation_type);
+        //录入子表
+        if ($request->input("operation_type") == '入库') $service->insertRule([
+            "owner_price_operation_id" => $model->id,
+            "amount" => $request->input("rules")[0]["amount"],
+            "unit_id" => $request->input("rules")[0]["unit_id"],
+            "unit_price" => $request->input("rules")[0]["unit_price"],
+        ],"入库");
+        else{
+            $insert = [];
+            foreach ($request->input("rules") as $rule){
+                $insert[] = [
+                    "owner_price_operation_id" => $model->id,
+                    "amount" => $rule["amount"],
+                    "unit_id" => $rule["unit_id"],
+                    "unit_price" => $rule["unit_price"],
+                    "strategy" => $rule["strategy"],
+                    "feature" => $rule["feature"],
+                    "priority" => $rule["priority"],
+                ];
+            }
+            $service->insertRule($insert);
+        }
+        //录入中间表
+        /** @var OwnerPriceOperation $model */
+        if ($request->input("owner_id"))$model->ownerPriceOperationOwners()->sync($request->input("owner_id"));
+        return response()->redirectTo("maintenance/priceModel/operation")->with("successTip","修改“".$request->input("name")."”成功");
+    }
+
+    private function operationValidator(array $params, $id= null)
+    {
+        return Validator::make($params,[
+            //required_with:id
+            'operation_type'=>['required'],
+            'owner_id'=>[function ($attribute, $value, $fail)use($params,$id) {
+                if ($params["strategy"] == '默认'){
+                    $owners = Owner::query()->whereIn("id",$value)->withCount(["ownerPriceOperations"=>function($query)use($params,$id){
+                        if ($id)$query->where('id',"!=",$id);
+                        $query->where("strategy","默认")->where("operation_type",$params["operation_type"]);
+                    }])->get();
+                    $err = [];
+                    foreach ($owners as $owner){
+                        if ($owner->owner_price_operations_count > 0)$err[] = $owner->name;
+                    }
+                    if (count($err)>0)$fail("(".implode(',',$err).') 已经绑定'.$params["operation_type"].'的默认策略');
+                }
+            }],
+            'strategy'=>['required'],
+            'name'=>['required',$id?"unique:owner_price_operations,name,$id":'unique:owner_price_operations,name'],
+            'priority'=>['required','integer','min:0','max:100'],
+            'rules.*.strategy'=>['required_if:operation_type,出库'],
+            'rules.*.amount'=>['required',"integer"],
+            'rules.*.unit_id'=>['required','integer'],
+            'rules.*.unit_price'=>['required','numeric',"min:0"],
+            'rules.*.priority'=>['required_if:operation_type,出库','integer','min:0','max:100'],
+        ],[
+            'required'=>':attribute 为必填项',
+            'min'=>':attribute 不得小于0',
+            'integer'=>':attribute 必须为整数',
+            'numeric'=>':attribute 必须为数字',
+            'max'=>':attribute 超出最大值',
+            'required_if'=>':attribute 操作类型为出库时不得为空',
+        ],[
+            'operation_type' =>"操作类型",
+            'strategy'    =>"计费策略",
+            'name'  =>"名称",
+            'priority' =>"优先级",
+        ]);
+    }
+
+    public function expressIndex(Request $request){
         if(!Gate::allows('计费模型-快递-查询')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.express.index');
+        $models = app('OwnerPriceExpressService')->paginate($request->input("id"));
+        return response()->view('maintenance.priceModel.express.index',compact("models"));
+    }
+
+    public function expressGetDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-快递-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $model = new OwnerPriceExpress();
+        $model->id = $request->input("id");
+        $model->load(["details"=>function($query){$query->with("province");}]);
+        return ["success"=>true,"data"=>$model->details];
+    }
+
+    public function expressUpdateDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-快递-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $detail = $request->input("detail");
+        if ($detail["id"]){
+            app('OwnerPriceExpressService')->updateDetail(["id"=>$detail["id"]],[
+                "additional_weight_price" => $detail["additional_weight_price"],
+                "initial_weight_price" => $detail["initial_weight_price"],
+            ]);
+        }else{
+            $row = app('OwnerPriceExpressService')->isExistDetail(["owner_price_express_id"=>$request->input("id"),"province_id"=>$detail["province_id"]]);
+            if ($row>0)return ["success"=>false,"data"=>"已存在该省份计费模型"];
+            /** @var OwnerPriceExpressProvince $detail */
+            $detail = app('OwnerPriceExpressService')->createDetail([
+                "owner_price_express_id" =>  $request->input("id"),
+                "province_id" => $detail["province_id"],
+                "additional_weight_price" => $detail["additional_weight_price"],
+                "initial_weight_price" => $detail["initial_weight_price"],
+            ]);
+            $detail->load("province");
+        }
+        return ["success"=>true,"data"=>$detail];
+    }
+
+    public function expressDestroyDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-快递-删除')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $id = $request->input("id");
+        if (!$id)return ["success"=>false,"data"=>"非法参数"];
+        app("OwnerPriceExpressService")->destroyDetail($id);
+        return ["success"=>true];
+    }
+
+    public function expressImport(Request $request){
+        if(!Gate::allows('计费模型-快递-录入')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $fileSuffix=$request->file('file')->getClientOriginalExtension();
+        if ($fileSuffix != 'xlsx' && $fileSuffix != 'xls' && $fileSuffix != 'csv')
+            return ['success'=>false,'data'=>'不支持该文件类型'];
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
+        $fileSuffix = ucwords($fileSuffix);
+        /** @var OwnerPriceExpress $model */
+        $model = app('OwnerPriceExpressService')->find($request->input("id"),["details"]);
+        Excel::import(new ExpressImport($model),$request->file('file')->path(),null,$fileSuffix);
+        if (Cache::has('express'))return Cache::pull('express');
+
+        return ["success"=>false,"data"=>"导入发生错误,数据无响应"];
     }
 
     public function expressCreate(){
         if(!Gate::allows('计费模型-快递-录入')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.express.create');
+        $logistics = app("LogisticService")->getSelection();
+        $owners = app("OwnerService")->getSelection();
+        return response()->view('maintenance.priceModel.express.create',compact("logistics","owners"));
+    }
+
+    public function expressStore(Request $request)
+    {
+        if(!Gate::allows('计费模型-快递-录入')){ return redirect('denied');  }
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $request->offsetSet("logistic_id",explode(",",$request->input("logistic_id")));
+        $this->expressValidator($request->input())->validate();
+        /** @var OwnerPriceExpress $model */
+        $model = app("OwnerPriceExpressService")->create([
+            "name" => $request->input("name"),
+            "initial_weight" => $request->input("initial_weight"),
+            "additional_weight" => $request->input("additional_weight"),
+        ]);
+        $model->owners()->sync($request->input("owner_id"));
+        $model->logistics()->sync($request->input("logistic_id"));
+        return response()->redirectTo("maintenance/priceModel/express")->with("successTip","录入“".$request->input("name")."”成功");
+    }
+
+    public function expressEdit($id)
+    {
+        if(!Gate::allows('计费模型-快递-编辑')){ return redirect('denied');  }
+        /** @var OwnerPriceExpress $model */
+        $model = app('OwnerPriceExpressService')->find($id)->append(["owner_id","logistic_id"]);
+        $owners = app("OwnerService")->getSelection();
+        $logistics = app('LogisticService')->getSelection();
+        return response()->view('maintenance.priceModel.express.create',compact("owners","logistics","model"));
+    }
+
+    public function expressUpdate($id,Request $request)
+    {
+        if(!Gate::allows('计费模型-快递-编辑')){ return redirect('denied');  }
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $request->offsetSet("logistic_id",explode(",",$request->input("logistic_id")));
+        $this->expressValidator($request->input(),$id)->validate();
+        /** @var OwnerPriceExpress $model */
+        app("OwnerPriceExpressService")->update(["id"=>$id],[
+            "name" => $request->input("name"),
+            "initial_weight" => $request->input("initial_weight"),
+            "additional_weight" => $request->input("additional_weight"),
+        ]);
+        $model = new OwnerPriceExpress();
+        $model->id = $id;
+        $model->owners()->sync($request->input("owner_id"));
+        $model->logistics()->sync($request->input("logistic_id"));
+        return response()->redirectTo("maintenance/priceModel/express")->with("successTip","修改“".$request->input("name")."”成功");
+    }
+
+    private function expressValidator(array $params, $id=null)
+    {
+        return Validator::make($params,[
+            'name'=>['required',$id?"unique:owner_price_expresses,name,$id":'unique:owner_price_expresses,name'],
+            'initial_weight'=>['required','numeric','min:0'],
+            'additional_weight'=>['required','numeric','min:0'],
+            'owner_id'=>[function ($attribute, $value, $fail)use($id) {
+                $owners = app("OwnerPriceExpressService")->getExistOwnerName($value,$id);
+                if ($owners)$fail("(".implode(',',$owners).') 已经绑定计费模型');
+            }],
+            'logistic_id'=>[function ($attribute, $value, $fail)use($id) {
+                $logistics = app("OwnerPriceExpressService")->getExistLogisticName($value,$id);
+                if ($logistics)$fail("(".implode(',',$logistics).') 已经绑定计费模型');
+            }],
+        ],[
+            'required'=>':attribute 为必填项',
+            'unique' => ':attribute 已存在',
+        ],[
+            'name' =>"名称",
+            'initial_weight'  =>"首重",
+            'additional_weight'  =>"续重",
+        ]);
     }
 
-    public function logisticIndex(){
+    public function expressDestroy($id)
+    {
+        if(!Gate::allows('计费模型-快递-删除')){ return ["success"=>false,"data"=>"无权操作"]; };
+        app("OwnerPriceExpressService")->destroy($id);
+        return ["success"=>true];
+    }
+
+    public function logisticIndex(Request $request)
+    {
         if(!Gate::allows('计费模型-物流-查询')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.logistic.index');
+        $models = app("OwnerPriceLogisticService")->paginate($request->input("id"))->append(["unit_range_json","other_unit_range_json"]);
+        return response()->view('maintenance.priceModel.logistic.index',compact("models"));
     }
 
-    public function logisticCreate(){
+    public function logisticCreate()
+    {
+        if(!Gate::allows('计费模型-物流-录入')){ return redirect('denied');  }
+        $owners = app("OwnerService")->getSelection();
+        $logistics = app('LogisticService')->getSelection();
+        $units = app('UnitService')->getSelection();
+        return response()->view('maintenance.priceModel.logistic.create',compact("owners","logistics","units"));
+    }
+
+    public function logisticStore(Request $request)
+    {
         if(!Gate::allows('计费模型-物流-录入')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.logistic.create');
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $request->offsetSet("logistic_id",explode(",",$request->input("logistic_id")));
+        $this->logisticValidator($request->input())->validate();
+        /** @var OwnerPriceLogistic $model */
+        $model = app("OwnerPriceLogisticService")->create([
+            "name" => $request->input("name"),
+            "pick_up_price" => $request->input("pick_up_price"),
+            "fuel_price" => $request->input("fuel_price"),
+            "service_price" => $request->input("service_price"),
+            "unit_id" => $request->input("unit_id"),
+            "unit_range" => $request->input("unit_range"),
+            "other_unit_id" => $request->input("other_unit_id"),
+            "other_unit_range" => $request->input("other_unit_range"),
+        ]);
+        $model->owners()->sync($request->input("owner_id"));
+        $model->logistics()->sync($request->input("logistic_id"));
+        return response()->redirectTo("maintenance/priceModel/logistic")->with("successTip","创建“".$request->input("name")."”成功");
+    }
+
+    public function logisticEdit($id)
+    {
+        if(!Gate::allows('计费模型-物流-编辑')){ return redirect('denied');  }
+        $owners = app("OwnerService")->getSelection();
+        $logistics = app('LogisticService')->getSelection();
+        $units = app('UnitService')->getSelection();
+        $model = app("OwnerPriceLogisticService")->find($id)->append(["owner_id","logistic_id"]);
+        return response()->view('maintenance.priceModel.logistic.create',compact("owners","logistics","units","model"));
+    }
+
+    public function logisticUpdate($id, Request $request)
+    {
+        if(!Gate::allows('计费模型-物流-编辑')){ return redirect('denied');  }
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $request->offsetSet("logistic_id",explode(",",$request->input("logistic_id")));
+        $this->logisticValidator($request->input(),$id)->validate();
+        app("OwnerPriceLogisticService")->update(["id"=>$id],[
+            "name" => $request->input("name"),
+            "pick_up_price" => $request->input("pick_up_price"),
+            "fuel_price" => $request->input("fuel_price"),
+            "service_price" => $request->input("service_price"),
+            "unit_id" => $request->input("unit_id"),
+            "unit_range" => $request->input("unit_range"),
+            "other_unit_id" => $request->input("other_unit_id"),
+            "other_unit_range" => $request->input("other_unit_range"),
+        ]);
+        $model = new OwnerPriceLogistic();
+        $model->id = $id;
+        $model->owners()->sync($request->input("owner_id"));
+        $model->logistics()->sync($request->input("logistic_id"));
+        return response()->redirectTo("maintenance/priceModel/logistic")->with("successTip","修改“".$request->input("name")."”成功");
+    }
+
+    public function logisticGetDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-物流-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $model = new OwnerPriceLogistic();
+        $model->id = $request->input("id");
+        $model->load(["details"=>function($query){
+            /** @var Builder $query */
+            $query->with(["unit","province","city"]);
+        }]);
+        return ["success"=>true,"data"=>$model->details];
+    }
+
+    public function expressExport($id)
+    {
+        if(!Gate::allows('计费模型-快递-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $model = app("OwnerPriceExpressService")->find($id,[
+            "owners","logistics","details"=>function($query){
+                /** @var Builder $query */
+                $query->with("province");
+            }]);
+        $row = ["客户","首重","续重","承运商"];
+        $list = [[
+            implode(",",array_column($model->owners->toArray(),"name")),
+            $model->initial_weight,
+            $model->additional_weight,
+            implode(",",array_column($model->logistics->toArray(),"name")),
+        ],[
+            "价格名称","省","首重价格","续重价格",
+        ]];
+        foreach ($model->details as $detail){
+            $list[] = [
+                $model->name,
+                $detail->province ? $detail->province->name : '',
+                $detail->initial_weight_price,
+                $detail->additional_weight_price,
+            ];
+        }
+        return app(ExportService::class)->json($row,$list,"快递计费模型");
+    }
+
+    public function logisticImport(Request $request)
+    {
+        if(!Gate::allows('计费模型-物流-录入')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $fileSuffix=$request->file('file')->getClientOriginalExtension();
+        if ($fileSuffix != 'xlsx' && $fileSuffix != 'xls' && $fileSuffix != 'csv')
+            return ['success'=>false,'data'=>'不支持该文件类型'];
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
+        $fileSuffix = ucwords($fileSuffix);
+        /** @var OwnerPriceLogistic $model */
+        $model = app('OwnerPriceLogisticService')->find($request->input("id"),["unit","otherUnit","details"]);
+        Excel::import(new OwnerPriceLogisticDetailImport($model),$request->file('file')->path(),null,$fileSuffix);
+        if (Cache::has('logistic'))return Cache::pull('logistic');
+
+        return ["success"=>false,"data"=>"导入发生错误,数据无响应"];
+    }
+
+    public function logisticExport($id)
+    {
+        if(!Gate::allows('计费模型-物流-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $model = app("OwnerPriceLogisticService")->find($id,[
+            "owners","logistics","unit","otherUnit","details"=>function($query){
+                /** @var Builder $query */
+                $query->with(["province","unit","city"]);
+            }]);
+        $row = ["客户","价格名称",
+            "单位一区间/".($model->unit ? $model->unit->name : ''),
+            "单位二区间/".($model->otherUnit ? $model->otherUnit->name : ''),
+            "提货费","燃油附加费","信息服务费","创建时间","承运商"];
+        $range = "";
+        foreach (explode(",",$model->unit_range) as $str){
+            $range .= $str."\r\n";
+        }
+        $otherRange = "";
+        foreach (explode(",",$model->other_unit_range) as $str){
+            $otherRange .= $str."\r\n";
+        }
+        $list = [[
+            implode(",",array_column($model->owners->toArray(),"name")),
+            $model->name,
+            $range,
+            $otherRange,
+            $model->pick_up_price,
+            $model->fuel_price,
+            $model->service_price,
+            $model->created_at,
+            implode(",",array_column($model->logistics->toArray(),"name")),
+        ],[
+            "单位","区间","省份","市","单价","送货费","起始计费","起始计数","费率"
+        ]];
+        foreach ($model->details as $detail){
+            $list[] = [
+                $detail->unit ? $detail->unit->name : '',
+                $detail->range,
+                $detail->province ? $detail->province->name : '',
+                $detail->city ? $detail->city->name : '',
+                $detail->unit_price,
+                $detail->delivery_fee,
+                $detail->initial_fee,
+                $detail->initial_amount,
+                $detail->rate ? $detail->rate."%" : '',
+            ];
+        }
+        return app(ExportService::class)->json($row,$list,"物流计费模型");
+    }
+
+    public function logisticUpdateDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-物流-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $detail = $request->input("detail");
+        if ($detail["id"]){
+            app('OwnerPriceLogisticService')->updateDetail(["id"=>$detail["id"]],[
+                "unit_price" => $detail["unit_price"],
+                "delivery_fee" => $detail["delivery_fee"],
+                "initial_fee" => $detail["initial_fee"],
+                "initial_amount" => $detail["initial_amount"],
+                "rate" => $detail["rate"],
+            ]);
+        }else{
+            $row = app('OwnerPriceLogisticService')->isExistDetail([
+                "owner_price_logistic_id"=>$request->input("id"),
+                "unit_id"=>$detail["unit_id"],
+                "range"=>$detail["range"],
+                "province_id"=>$detail["province_id"],
+                "city_id"=>$detail["city_id"],
+            ]);
+            if ($row>0)return ["success"=>false,"data"=>"已存在该计费模型"];
+            /** @var OwnerPriceExpressProvince $detail */
+            $detail = app('OwnerPriceLogisticService')->createDetail([
+                "owner_price_logistic_id"=>$request->input("id"),
+                "unit_id"=>$detail["unit_id"],
+                "range"=>$detail["range"],
+                "province_id"=>$detail["province_id"],
+                "city_id"=>$detail["city_id"],
+                "unit_price" => $detail["unit_price"],
+                "delivery_fee" => $detail["delivery_fee"],
+                "initial_fee" => $detail["initial_fee"],
+                "initial_amount" => $detail["initial_amount"],
+                "rate" => $detail["rate"],
+            ]);
+            $detail->load("province","unit","city");
+        }
+        return ["success"=>true,"data"=>$detail];
     }
 
-    public function directLogisticIndex(){
+    public function logisticDestroyDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-物流-删除')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $id = $request->input("id");
+        if (!$id)return ["success"=>false,"data"=>"非法参数"];
+        app("OwnerPriceLogisticService")->destroyDetail($id);
+        return ["success"=>true];
+    }
+
+    private function logisticValidator(array $params,$id = null)
+    {
+        return Validator::make($params,[
+            'name'=>['required',$id?"unique:owner_price_logistics,name,$id":'unique:owner_price_logistics,name'],
+            'pick_up_price'=>['nullable','numeric','min:0'],
+            'fuel_price'=>['nullable','numeric','min:0'],
+            'service_price'=>['nullable','numeric','min:0'],
+            'unit_id'=>['required'],
+            'unit_range'=>['required',function ($attribute, $value, $fail) {
+                $bool = app("OwnerPriceLogisticService")->checkRange($value);
+                if (!$bool)$fail("格式错误,值必须为连续的且最后一个值不允许封闭");
+            }],
+            'other_unit_id'=>['required'],
+            'other_unit_range'=>['required',function ($attribute, $value, $fail) {
+                $bool = app("OwnerPriceLogisticService")->checkRange($value);
+                if (!$bool)$fail("格式错误,值必须为连续的且最后一个值不允许封闭");
+            }],
+        ],[
+            'required'=>':attribute 为必填项',
+            'unique' => ':attribute 已存在',
+            'numeric' => ':attribute 必须为数字',
+            'min' => ':attribute 不得为负',
+        ],[
+            'name' =>"名称",
+            'pick_up_price'  =>"提货费",
+            'fuel_price'  =>"燃油附加费",
+            'service_price'  =>"信息服务费",
+            'unit_id'  =>"单位一",
+            'unit_range'  =>"区间值",
+            'other_unit_id'  =>"单位二",
+            'other_unit_range'  =>"区间值",
+        ]);
+    }
+
+    public function directLogisticIndex(Request $request){
         if(!Gate::allows('计费模型-直发-查询')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.directLogistic.index');
+        $models = app("OwnerPriceDirectLogisticService")->paginate($request->input("id"));
+        return response()->view('maintenance.priceModel.directLogistic.index',compact("models"));
     }
 
     public function directLogisticCreate(){
         if(!Gate::allows('计费模型-直发-录入')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.directLogistic.create');
+        $owners = app("OwnerService")->getSelection();
+        return response()->view('maintenance.priceModel.directLogistic.create',compact("owners"));
+    }
+
+    public function directLogisticStore(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-录入')){ return redirect('denied');  }
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $this->directLogisticValidator($request->input())->validate();
+        /** @var OwnerPriceDirectLogistic $model */
+        $model = app("OwnerPriceDirectLogisticService")->create([
+            "name" => $request->input("name"),
+            "base_km" => $request->input("base_km"),
+        ]);
+        $model->owners()->sync($request->input("owner_id"));
+        return response()->redirectTo("maintenance/priceModel/directLogistic")->with("successTip","创建“".$request->input("name")."”成功");
+    }
+
+    public function directLogisticDestroy($id)
+    {
+        if(!Gate::allows('计费模型-直发-删除')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $row = app("OwnerPriceDirectLogisticService")->destroy($id);
+        if ($row == 1)return ["success"=>true];
+        return ["success"=>false,"data"=>"影响了“".$row."”行"];
+    }
+
+    public function directLogisticEdit($id)
+    {
+        if(!Gate::allows('计费模型-直发-编辑')){ return redirect('denied');  }
+        $owners = app("OwnerService")->getSelection();
+        $model = app("OwnerPriceDirectLogisticService")->find($id)->append("owner_id");
+        return response()->view('maintenance.priceModel.directLogistic.create',compact("model","owners"));
+    }
+
+    public function directLogisticUpdate($id, Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-编辑')){ return redirect('denied');  }
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $this->directLogisticValidator($request->input(),$id)->validate();
+        app("OwnerPriceDirectLogisticService")->update(["id"=>$id],[
+            "name" => $request->input("name"),
+            "base_km" => $request->input("base_km"),
+        ]);
+        $model = new OwnerPriceDirectLogistic();
+        $model->id = $id;
+        $model->owners()->sync($request->input("owner_id"));
+        return response()->redirectTo("maintenance/priceModel/directLogistic")->with("successTip","修改“".$request->input("name")."”成功");
+    }
+
+    public function directLogisticGetDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $model = new OwnerPriceDirectLogistic();
+        $model->id = $request->input("id");
+        $model->load(["details"=>function($query){
+            /** @var Builder $query */
+            $query->with("carType");
+        }]);
+        return ["success"=>true,"data"=>$model->details];
+    }
+
+    public function directLogisticImport(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-录入')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $fileSuffix=$request->file('file')->getClientOriginalExtension();
+        if ($fileSuffix != 'xlsx' && $fileSuffix != 'xls' && $fileSuffix != 'csv')
+            return ['success'=>false,'data'=>'不支持该文件类型'];
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
+        $fileSuffix = ucwords($fileSuffix);
+        $model = new OwnerPriceDirectLogistic();
+        $model->id = $request->input("id");
+        $model->load("details");
+        Excel::import(new OwnerPriceDirectLogisticDetailImport($model),$request->file('file')->path(),null,$fileSuffix);
+        if (Cache::has('directLogistic'))return Cache::pull('directLogistic');
+
+        return ["success"=>false,"data"=>"导入发生错误,数据无响应"];
+    }
+
+    public function directLogisticUpdateDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $detail = $request->input("detail");
+        if ($detail["id"]){
+            app('OwnerPriceDirectLogisticService')->updateDetail(["id"=>$detail["id"]],[
+                "base_fee" => $detail["base_fee"],
+                "additional_fee" => $detail["additional_fee"],
+            ]);
+        }else{
+            $row = app('OwnerPriceDirectLogisticService')->isExistDetail([
+                "owner_price_direct_logistic_id"=>$request->input("id"),
+                "car_type_id"=>$detail["car_type_id"],
+            ]);
+            if ($row>0)return ["success"=>false,"data"=>"已存在该计费模型"];
+            /** @var OwnerPriceExpressProvince $detail */
+            $detail = app('OwnerPriceDirectLogisticService')->createDetail([
+                "owner_price_direct_logistic_id"=>$request->input("id"),
+                "car_type_id"=>$detail["car_type_id"],
+                "base_fee" => $detail["base_fee"],
+                "additional_fee" => $detail["additional_fee"],
+            ]);
+            $detail->load("carType");
+        }
+        return ["success"=>true,"data"=>$detail];
+    }
+
+    public function directLogisticDestroyDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-删除')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $id = $request->input("id");
+        if (!$id)return ["success"=>false,"data"=>"非法参数"];
+        app("OwnerPriceDirectLogisticService")->destroyDetail($id);
+        return ["success"=>true];
+    }
+
+    private function directLogisticValidator(array $params, $id= null)
+    {
+        return Validator::make($params,[
+            'name'=>['required',$id?"unique:owner_price_direct_logistics,name,$id":'unique:owner_price_direct_logistics,name'],
+            'base_km'=>['required','numeric','min:0'],
+            'owner_id'=>[function ($attribute, $value, $fail)use($id) {
+                $owners = app("OwnerPriceDirectLogisticService")->getExistOwnerName($value,$id);
+                if ($owners)$fail("(".implode(',',$owners).') 已经绑定直发计费模型');
+            }],
+        ],[
+            'required'=>':attribute 为必填项',
+            'unique' => ':attribute 已存在',
+            'numeric' => ':attribute 必须为数字',
+            'min' => ':attribute 不得为负',
+        ],[
+            'name' =>"名称",
+            'base_km'  =>"起步公里数",
+        ]);
     }
 
 }

+ 57 - 23
app/Http/Controllers/ProcessMethodController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Validator;
 
 class ProcessMethodController extends Controller
 {
@@ -16,7 +17,8 @@ class ProcessMethodController extends Controller
     public function index()
     {
         if(!Gate::allows('作业类型-查询')){ return redirect('denied');  }
-        return response()->view("maintenance.processMethod.index");
+        $methods = app('ProcessMethodService')->paginate();
+        return response()->view("maintenance.processMethod.index",compact("methods"));
     }
 
     /**
@@ -27,62 +29,94 @@ class ProcessMethodController extends Controller
     public function create()
     {
         if(!Gate::allows('作业类型-录入')){ return redirect('denied');  }
-        return response()->view("maintenance.processMethod.create");
+        $units = app('UnitService')->getSelection();
+        return response()->view("maintenance.processMethod.create",compact("units"));
     }
 
     /**
      * Store a newly created resource in storage.
      *
-     * @param  \Illuminate\Http\Request  $request
-     * @return \Illuminate\Http\Response
+     * @param  Request  $request
+     * @return Response
      */
     public function store(Request $request)
     {
-        //
-    }
-
-    /**
-     * Display the specified resource.
-     *
-     * @param  int  $id
-     * @return \Illuminate\Http\Response
-     */
-    public function show($id)
-    {
-        //
+        if(!Gate::allows('作业类型-录入')){ return redirect('denied');  }
+        $this->validator($request->input())->validate();
+        app('ProcessMethodService')->create([
+            "name"=>$request->input("name"),
+            "unit_id"=>$request->input("unit_id"),
+            "unit_price"=>$request->input("unit_price"),
+        ]);
+        return response()->redirectTo("maintenance/processMethod")->with("successTip","成功创建项目组“".$request->input("name")."”");
     }
 
     /**
      * Show the form for editing the specified resource.
      *
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return Response
      */
     public function edit($id)
     {
-        //
+        if(!Gate::allows('作业类型-编辑')){ return redirect('denied');  }
+        $method = app('ProcessMethodService')->find($id);
+        $units = app('UnitService')->getSelection();
+        return response()->view('maintenance.processMethod.create',compact("method","units"));
     }
 
     /**
      * Update the specified resource in storage.
      *
-     * @param  \Illuminate\Http\Request  $request
+     * @param  Request  $request
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return Response
      */
     public function update(Request $request, $id)
     {
-        //
+        if(!Gate::allows('作业类型-编辑')){ return redirect('denied');  }
+        $this->validator($request->input(),$id)->validate();
+        $result = app('ProcessMethodService')->update(["id"=>$id],[
+            "name"=>$request->input("name"),
+            "unit_id"=>$request->input("unit_id"),
+            "unit_price"=>$request->input("unit_price"),
+        ]);
+        if ($result == 1){
+            return response()->redirectTo("maintenance/processMethod")->with("successTip","成功修改项目组“".$request->input("name")."”的信息");
+        }
+        return response()->view("exception.default",["code"=>"509"]);
     }
 
     /**
      * Remove the specified resource from storage.
      *
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return array
      */
     public function destroy($id)
     {
-        //
+        if(!Gate::allows('作业类型-删除')){ return ["success"=>false,"data"=>"无权操作!"];  }
+        $result = app('ProcessMethodService')->destroy($id);
+        if ($result == 1)return ["success"=>true];
+        return ["success"=>false,"data"=>"删除了“".$result."”行"];
+    }
+
+    private function validator(array $params, $id = null)
+    {
+        return Validator::make($params,[
+            'name'=>['required',$id?"unique:process_methods,name,$id":'unique:process_methods,name','max:20'],
+            "unit_id" => ["nullable",'numeric'],
+            "unit_price" => ["nullable",'numeric','min:0'],
+        ],[
+            'required'=>':attribute 为必填项',
+            'max'=>':attribute 字符过多或输入值过大',
+            'unique'=>':attribute 已存在',
+            'numeric'=>':attribute 必须为数字',
+            'min'=>':attribute 数值过小',
+        ],[
+            'name'=>'作业类型名称',
+            'unit_id'=>'作业类型单位',
+            'unit_price'=>'作业类型单价',
+        ]);
     }
 }

+ 4 - 0
app/Http/Controllers/ProvincesController.php

@@ -77,4 +77,8 @@ class ProvincesController extends Controller
         ]);
         return $validator;
     }
+
+    public function get(){
+        return Province::query()->select("id","name")->get();
+    }
 }

+ 104 - 50
app/Http/Controllers/TestController.php

@@ -4,24 +4,15 @@ namespace App\Http\Controllers;
 
 
 use App\Authority;
-use App\Batch;
-use App\City;
 use App\Commodity;
 use App\CommodityBarcode;
 use App\Events\CancelOrder;
+use App\Imports\OrderTrackingImport;
 use App\InventoryAccount;
-use App\Events\ResetProcessStatisticStartDateEvent;
-use App\InventoryAccountMission;
-use App\InventoryCompare;
-use App\InventoryDailyLog;
+use App\LaborReport;
 use App\Log;
 use App\Logistic;
-use App\LogisticTiming;
 use App\OracleActAllocationDetails;
-use App\OracleBasCode;
-use App\OracleBasSKU;
-use App\OracleDOCASNDetail;
-use App\OracleDOCASNHeader;
 use App\OracleDOCOrderHeader;
 use App\OracleDocOrderPackingSummary;
 use App\OracleDOCWaveDetails;
@@ -30,33 +21,19 @@ use App\OrderBin;
 use App\OrderCommodity;
 use App\OrderIssue;
 use App\OrderPackage;
-use App\OrderPackageCommodities;
-use App\OrderTracking;
-use App\OrderTrackingOwner;
 use App\Owner;
 use App\Package;
 use App\Process;
 use App\ProcessDaily;
-use App\ProcessesContent;
 use App\ProcessStatistic;
-use App\Province;
 use App\RejectedBill;
 use App\RejectedBillItem;
 use App\Services\CacheService;
-use App\Services\CityService;
-use App\Services\CommodityService;
 use App\Services\common\BatchUpdateService;
 use App\Services\common\DataHandlerService;
-use App\Services\common\ExportService;
 use App\Services\InventoryCompareService;
-use App\Services\LogService;
-use App\Services\OracleActAllocationDetailService;
-use App\Services\OracleBasCustomerService;
 use App\Services\OracleDocAsnHerderService;
 use App\Services\OracleDOCOrderHeaderService;
-use App\Services\OrderIssuePerformanceService;
-use App\Services\OrderIssueService;
-use App\Services\OrderPackageCommoditiesService;
 use App\Services\OrderPackageService;
 use App\Services\OrderService;
 use App\Services\OrderTrackingOwnerService;
@@ -64,24 +41,17 @@ use App\Services\OrderTrackingService;
 use App\Services\OwnerService;
 use App\Services\StoreService;
 use App\Services\WarehouseService;
-use App\Store;
-use App\StoreCheckingReceive;
-use App\StoreCheckingReceiveItem;
 use App\Unit;
 use App\User;
 use App\Warehouse;
-use App\Waybill;
 use Carbon\Carbon;
-use Exception;
-use Facade\Ignition\QueryRecorder\Query;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Facades\Http;
-use Illuminate\Support\Facades\Redis;
 use Illuminate\Support\Str;
+use Maatwebsite\Excel\Facades\Excel;
 use Ramsey\Collection\Collection;
 use Zttp\Zttp;
 
@@ -120,27 +90,47 @@ class TestController extends Controller
         }
     }
     public function test4(){
-        $row = [];
-        for ($i=0;$i<50;$i++){
-            $row[] = "表头-".Str::random(5);
+        DB::beginTransaction();
+        Unit::query()->lockForUpdate()->where("id",14)->first();
+        for($i=0;$i<=100;$i++){
+            sleep(1);
+            var_dump($i);
         }
-        $list = [];
-        for ($i=0;$i<3000;$i++){
-            $line = [];
-            for($j=0;$j<50;$j++){
-                $line[] = Str::random(3)."\r\n".Str::random(3);
+    }
+
+    public function updateLaborRemark(){
+        $laborReports=LaborReport::query()->with(['remarks'=>function($query){
+            return $query->whereNotNull('mark');
+        }])->get();
+        $updateParams = [[
+            'id','remark','updated_at'
+        ]];
+        $updated_at=Carbon::now()->toDateTimeString();
+        foreach ($laborReports as $laborReport){
+            if ($laborReport->remarks){
+                $updateParams[] = [
+                    'id'=>$laborReport->id,
+                    'remark'=>$laborReport->remarks->mark,
+                    'updated_at'=>$updated_at,
+                ];
             }
-            $list[] = $line;
         }
-        return app(ExportService::class)->json($row,$list,"测试记录");
+        if(count($updateParams) > 1){
+            app(BatchUpdateService::class)->batchUpdate('labor_reports',$updateParams);
+        }
     }
-
     public function test2(){
-        $a = Unit::query()->first();
+        $b = Logistic::query()->first();
+        $a = OrderPackage::query()->with("order")->first();
+        $a->bulk = 521;
+        $a->save();
+        if (!$a->order) $a->order = new Order();
+        dd($a);
+        if (!$a->order->logistic)$a->order->logistic = $b;
+        dd($a->order->logistic);
+        dd($a);
+        $a->save();
         dd($a);
-        /** @var Process $process */
-        $process = Process::query()->first();
-        event(new ResetProcessStatisticStartDateEvent($process));
     }
 
     function packageFromLog(Request $request)
@@ -168,8 +158,6 @@ class TestController extends Controller
                 $uploaded += 1;
         });
         dd($uploaded . '/' . $count);
-
-
     }
 
     function wmsSql()
@@ -1068,4 +1056,70 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
         echo $i;
     }
 
+    public function orderTrackingImportTest(Request $request)
+    {
+        $file = $request->file('file');
+        ini_set('max_execution_time',4000);
+        ini_set('memory_limit', '1024M');
+        $extension = $request->file()['file']->getClientOriginalExtension();
+        $extension[0] = strtoupper($extension[0]);
+        Excel::import(new OrderTrackingImport(), $request->file('file')->path(), null, $extension);
+    }
+
+    public function testImp()
+    {
+        $client_no = null;
+        $items = null;
+        $order=(new OrderTrackingImport())->getOrder($client_no,$items);
+        if($order['id']) echo 'yes1';
+
+
+        $order = Order::query()->create([
+            'code'=>'null'.Str::uuid(),'client_code' => 'asdfdfdg','web_order_number' => 'sadfdsf'
+        ]);
+        dd($order);
+//        $order=(new OrderTrackingImport())->getOrder('92024765871-SDO130000986796QX',$items);
+//        if($order['id']) echo 'yes2';
+    }
+
+//    public function deleteOrderInfo()
+//    {
+//        $orders = Order::query()->where('created_at', '>', '2020-11-17 18:00:00')->where('code', 'like', 'null%')->get();
+//        $order_ids = data_get($orders, '*.id');unset($orders);
+//        Order::query()->whereIn('id',$order_ids)->delete();
+//
+//        if(count($order_ids)==0)return;
+//        $packages = OrderPackage::query()->whereIn('order_id', $order_ids)->get();
+//        $packages_ids = data_get($packages, '*.id');unset($packages);
+//        OrderPackage::query()->whereIn('id',$packages_ids)->delete();
+//
+//        if(count($packages_ids)==0)return;
+//        $commoodities = OrderPackageCommodities::query()->whereIn('order_package_id',$packages_ids)->get();
+//        $commooditie_ids = data_get($commoodities, '*.id');unset($commoodities);
+//        OrderPackageCommodities::query()->whereIn('id',$commooditie_ids)->delete();
+//
+//        if(count($commooditie_ids)==0)return;
+//        $tackings = OrderTracking::query()->whereIn('order_package_commodity_id',$commooditie_ids )->get();
+//        $tacking_ids = data_get($tackings, '*.id');unset($tackings);
+//        OrderTracking::query()->whereIn('id',$tacking_ids)->delete();
+//    }
+//    public function destroyOrders_()
+//    {
+//        $orders = Order::query()->where('created_at', '>', '2020-11-17 17:00:00')
+//            ->where('code', 'like', 'null%')
+//            ->where('owner_id',71)->get();
+//        $orderIds = data_get($orders,'*.id');
+//        $orderPackages=OrderPackage::query()->whereIn('order_id',$orderIds)->get();
+//        $orderPackageIds = data_get($orderPackages,'*.id');
+//        OrderPackageCommodities::query()->whereIn('order_package_id',$orderPackageIds)->delete();
+//        OrderPackage::query()->whereIn('order_id',$orderIds)->delete();
+//        Order::query()->whereIn('id',$orderIds)->delete();
+//
+//        $orderTrackings=OrderTracking::query()->where('id','>',1780)->where('created_at','0000-00-00 00:00:00')->get();
+//        $orderTrackingIds = data_get($orderTrackings,'*.id');
+//        OrderTracking::query()->whereIn('id',$orderTrackingIds)->delete();
+//
+//        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode(['$orderIds'=>$orderIds,'$orderPackages'=>$orderPackages,'$orderPackageIds'=>$orderPackageIds,'$orderTrackingIds'=>$orderTrackingIds,]));
+//
+//    }
 }

+ 5 - 0
app/Http/Controllers/UnitsController.php

@@ -79,4 +79,9 @@ class UnitsController extends Controller
         ]);
         return $validator;
     }
+
+    public function getUnits()
+    {
+        return ["success"=>true,"data"=>app("UnitService")->getSelection()];
+    }
 }

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

@@ -80,7 +80,7 @@ class UserDutyCheckController extends Controller
         $this->validator($request)->validate();
         $userDetail = UserDetail::where('mobile_phone', $mobile_phone)->first();
         if (!$userDetail) return redirect('personnel/checking-in/userDutyCheck/createUserDetail/' . $mobile_phone)->with("importAndExportQRCodeType", $importAndExportQRCodeType);
-        if (Cache::has('dutyCheckTokenUser_' . $userDetail->user_id)) return "<h1 style='color: red;text-align:center'>请使用原有设备进行打卡,如无法使用原有设备请联系管理人员解绑设备!</h1>";
+        if (Cache::has('dutyCheckTokenUser_'.$userDetail->user_id)) return "<h1 style='color: red;text-align:center'>请使用原有设备进行打卡,如无法使用原有设备请联系管理人员解绑设备!</h1>";
         if($importAndExportQRCodeType=='import') return redirect('personnel/checking-in/userDutyCheck/updateUserLaborCompanies/' . $userDetail->mobile_phone)->with("importAndExportQRCodeType", $importAndExportQRCodeType);
         $userDutyCheck=$this->importAndExportDutyCheck($userDetail->user_id, $importAndExportQRCodeType);
         if ($userDutyCheck && $userDutyCheck->isNotImport == true) return "<h1 style='color: darkred;text-align:center'>当前还未入场,不可出场!</h1>";
@@ -196,7 +196,7 @@ class UserDutyCheckController extends Controller
         if ($errorMessage) return $errorMessage;
         $laravelEchoPrefix = config('database.redis.options.prefix');
         return response()->view('personnel/checking-in/importAndExportSuccess',['full_name'=>$userDetail->full_name,'checked_at'=>$userDutyCheck->checked_at,'type'=>$userDutyCheck->type,'laravelEchoPrefix'=>$laravelEchoPrefix])
-            ->cookie('userLaborToken', $userLaborToken, config('users.token_check_in_expire_minutes'), '/');
+            ->cookie('userLaborToken', $userLaborToken, config('users.cookie_expire_minutes'), '/');
     }
 
     public function updateValidator(Request $request)
@@ -256,7 +256,7 @@ class UserDutyCheckController extends Controller
         Controller::logS(__METHOD__,"录入临时工,用户,对应工作组,打卡记录".__FUNCTION__,json_encode($userDetail));
         $laravelEchoPrefix = config('database.redis.options.prefix');
         return response()->view('personnel/checking-in/importAndExportSuccess',['full_name'=>$userDetail->full_name,'checked_at'=>$userDutyCheck->checked_at,'type'=>$userDutyCheck->type,'laravelEchoPrefix'=>$laravelEchoPrefix])
-            ->cookie('userLaborToken',$userLaborToken,config('users.token_check_in_expire_minutes'),'/');
+            ->cookie('userLaborToken',$userLaborToken,config('users.cookie_expire_minutes'),'/');
 
     }
 
@@ -334,7 +334,7 @@ class UserDutyCheckController extends Controller
         }
         if ($userLaborToken){
             return response()->view('personnel/checking-in/success', ['group_name' => $group_name ?? '', 'full_name' => $userDetail->full_name, 'check_in_at' => $newLaborReport->check_in_at, 'laravelEchoPrefix' => $laravelEchoPrefix])
-                ->cookie('userLaborToken',$userLaborToken,config('users.token_check_in_expire_minutes'),'/');
+                ->cookie('userLaborToken',$userLaborToken,config('users.cookie_expire_minutes'),'/');
         }else{
             return response()->view('personnel/checking-in/success', ['group_name' => $group_name ?? '', 'full_name' => $userDetail->full_name, 'check_in_at' => $newLaborReport->check_in_at, 'laravelEchoPrefix' => $laravelEchoPrefix]);
         }

+ 44 - 22
app/Http/Controllers/UserOwnerGroupController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Validator;
 
 class UserOwnerGroupController extends Controller
 {
@@ -16,7 +17,8 @@ class UserOwnerGroupController extends Controller
     public function index()
     {
         if(!Gate::allows('项目组-查询')){ return redirect('denied');  }
-        return response()->view("maintenance.userOwnerGroup.index");
+        $groups = app('UserOwnerGroupService')->paginate();
+        return response()->view("maintenance.userOwnerGroup.index",compact("groups"));
     }
 
     /**
@@ -33,56 +35,76 @@ class UserOwnerGroupController extends Controller
     /**
      * Store a newly created resource in storage.
      *
-     * @param  \Illuminate\Http\Request  $request
-     * @return \Illuminate\Http\Response
+     * @param  Request  $request
+     * @return Response
      */
     public function store(Request $request)
     {
-        //
-    }
-
-    /**
-     * Display the specified resource.
-     *
-     * @param  int  $id
-     * @return \Illuminate\Http\Response
-     */
-    public function show($id)
-    {
-        //
+        if(!Gate::allows('项目组-录入')){ return redirect('denied');  }
+        $this->validator($request->input())->validate();
+        app('UserOwnerGroupService')->create([
+            "name"=>$request->input("name"),
+        ]);
+        return response()->redirectTo("maintenance/userOwnerGroup")->with("successTip","成功创建项目组“".$request->input("name")."”");
     }
 
     /**
      * Show the form for editing the specified resource.
      *
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return Response
      */
     public function edit($id)
     {
-        //
+        if(!Gate::allows('项目组-编辑')){ return redirect('denied');  }
+        $group = app('UserOwnerGroupService')->find($id);
+        return response()->view('maintenance.userOwnerGroup.create',compact("group"));
     }
 
     /**
      * Update the specified resource in storage.
      *
-     * @param  \Illuminate\Http\Request  $request
+     * @param  Request  $request
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return Response
      */
     public function update(Request $request, $id)
     {
-        //
+        if(!Gate::allows('项目组-编辑')){ return redirect('denied');  }
+        $this->validator($request->input(),$id)->validate();
+        $result = app('UserOwnerGroupService')->update(["id"=>$id],[
+            "name"=>$request->input("name"),
+        ]);
+        if ($result == 1){
+            return response()->redirectTo("maintenance/userOwnerGroup")->with("successTip","成功修改项目组“".$request->input("name")."”的信息");
+        }
+        return response()->view("exception.default",["code"=>"509"]);
     }
 
     /**
      * Remove the specified resource from storage.
      *
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return array
      */
     public function destroy($id)
     {
-        //
+        if(!Gate::allows('项目组-删除')){ return ["success"=>false,"data"=>"无权操作!"];  }
+        $result = app('UserOwnerGroupService')->destroy($id);
+        if ($result == 1)return ["success"=>true];
+        return ["success"=>false,"data"=>"删除了“".$result."”行"];
+    }
+
+    private function validator(array $params, $id = null)
+    {
+        return Validator::make($params,[
+            'name'=>['required',$id?"unique:user_owner_groups,name,$id":'unique:user_owner_groups,name','max:20'],
+        ],[
+            'required'=>':attribute 为必填项',
+            'max'=>':attribute 字符过多或输入值过大',
+            'unique'=>':attribute 已存在',
+        ],[
+            'name'=>'项目组名称',
+        ]);
     }
 }

+ 4 - 2
app/Http/Controllers/api/thirdPart/goodscan/PackageController.php

@@ -113,7 +113,8 @@ class PackageController
     public function updateOrderPackage(&$orderPackage,$params,$measuringMachine) //更新包裹信息 前往处理活动波次
     {
         $edges=$this->getEdges($params);
-        $req_date=$params['time']??Carbon::now();
+//        $req_date=$params['time']??Carbon::now();
+        $req_date=Carbon::now();
         $orderPackage->weight=$params['weight'];
         $orderPackage->measuring_machine_id=$measuringMachine->id;
         $orderPackage->length=$edges[0];
@@ -244,7 +245,8 @@ class PackageController
      */
     public function getOrderPackage($requestInput,$measuringMachine,$order)
     {
-        $weighed_at =$requestInput['time']??Carbon::now();
+//        $weighed_at =$requestInput['time']??Carbon::now();
+        $weighed_at =Carbon::now();
         $edges=$this->getEdges($requestInput);
         OrderPackage::query()->create([
             'order_id'=>$order->id,

+ 18 - 13
app/Http/Controllers/api/thirdPart/haiq/StorageController.php

@@ -21,33 +21,38 @@ class StorageController
         $bin = [
             "taskCode" => "TEST-BS2010100001",//任务编号 全局唯一
             "binCode" => "TEST-BIN01",//料箱编码
-            //"toWorkStation" => "TEST-HQ01",//出库工作站
-            //"fromWorkStation" => "TEST-HQ01",//回库工作站
             "fromLocCode" => "HAIB1-02-01",//源库位编码
             "toLocCode" => "HAIB1-02-01",//目标库位编码 出库填多个,表示这些库位都可以支持
             "sequence" => -1,//出库顺序 -1表示没有顺序,只有移库出库时需要指定顺序,其他可为-1
             "stockInfo" => [$stockInfo],//商品信息
         ];
-        $this->request = [[
+        /*$this->request = [[
             "groupCode" => 1,//组号/波次号 一组任务需要一起完成,再开始下一组任务;没有组任务的限制默认传-1或空
             "taskMode" => 3,//任务模式 值 1 (输送线入库)值 2 (输送线出库)值 3(货架到缓存货架)值4(货架到流利货架)
             "priority" => 99,//优先级 1-2147483647 1最低
             "sequenceFlag" => -1,//是否需要有序 1:需要有序 0:不需要有序
             "bins" => [$bin],//可执行货箱任务
+        ]];*/
+        $this->request = [[
+            "taskMode"      => 8,
+            "bins"=>[[
+                "taskCode"  =>"TEST-BS2011160004",
+                "binCode"   => "TESTBINCODE-0",
+                "fromLocCode" => "BIN-IN1",
+                //"toLocCode" => "BIN-OUT1",
+            ]],
+            "groupCode"     => 4,
+            "priority"      => 20,
+            "sequenceFlag"  => -1,
         ]];
     }
 
     public function relocate(Request $request){
-        $req = [[
-            "groupCode"=> "test_code2",
-            "priority"=> 1,
-            "taskMode"=> 1,
-            "bins"=> [[
-                "binCode"=> "test_bin_1",
-                "fromLocCode"=> "HAIB1-02-01"
-            ]],
-        ]];
-        $response = Http::post(config('api.haiq.storage.relocate'),$req);
+        $response = Http::post(config('api.haiq.storage.relocate'),$this->request);return $response;
+        if (!$response->ok()){
+            app('LogService')->log(__METHOD__,"haiq-请求失败,路径异常","REQUEST:".json_encode($this->request)." | RESPONSE:".$response);
+            return ['success'=>false,"data"=>"接口异常"];
+        }
         if (($response["code"] ?? false) && $response["code"] != 200){
             app('LogService')->log(__METHOD__,"haiq-料箱出库失败","REQUEST:".json_encode($this->request)." | RESPONSE:".$response);
             return ['success'=>false,"data"=>$response["errMsg"]];

+ 2 - 1
app/Http/Controllers/api/thirdPart/weight/PackageController.php

@@ -168,7 +168,8 @@ class PackageController extends Controller
         foreach ($requestInitial->all() as $k=>$v){
             $request[strtolower($k)]=$v;
         }
-        $reqDate=isset($request['time'])?$request['time']:Carbon::now();
+//        $reqDate=isset($request['time'])?$request['time']:Carbon::now();
+        $reqDate=Carbon::now();
         $errors=$this->validatorWeight($request)->errors();
 
         if (count($errors)>0){

+ 108 - 0
app/Imports/ExpressImport.php

@@ -0,0 +1,108 @@
+<?php
+
+namespace App\Imports;
+
+use App\OwnerPriceExpress;
+use App\OwnerPriceExpressProvince;
+use App\Province;
+use App\Services\common\BatchUpdateService;
+use App\Services\LogService;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Cache;
+use Maatwebsite\Excel\Concerns\ToCollection;
+use Maatwebsite\Excel\Concerns\WithHeadingRow;
+use Maatwebsite\Excel\Imports\HeadingRowFormatter;
+
+HeadingRowFormatter::default('none');
+class ExpressImport implements ToCollection,WithHeadingRow
+{
+    protected $express;
+    public function __construct(OwnerPriceExpress $express = null)
+    {
+        $this->express = $express;
+    }
+
+    /**
+    * @param Collection $collection
+    * @return bool
+    */
+    public function collection(Collection $collection)
+    {
+        if (!$this->express){
+            Cache::put("express",["success"=>false, "data"=>"不存在父级"],86400);
+            return false;
+        }
+        $row = $collection->first();
+        $header = [
+            "省","首重价格","续重价格"
+        ];
+        foreach ($header as $str){
+            if (!isset($row[$str])){
+                Cache::put("express",["success"=>false, "data"=>"表头不存在“".$str."”"],86400);
+                return false;
+            }
+        }
+
+        //省份map
+        $map = [];
+        $provinces = Province::query()->get();
+        foreach ($provinces as $province){
+            $map[$province->name] = $province->id;
+        }
+
+        //已存在的计费
+        $existDetails = [];
+        foreach ($this->express->details as $detail){
+            $existDetails[$detail->province_id] = $detail->id;
+        }
+
+        //导入的数据整理,存在更新
+        $id = $this->express->id;
+        $errors = [];
+        $insert = [];
+        $update = [["id","initial_weight_price","additional_weight_price","updated_at"]];
+        $date = date('Y-m-d H:i:s');
+        foreach ($collection as $index => $item){
+            if (!isset($map[$item["省"]])){
+                $errors[] = "第“".($index+2)."”行未知省份";
+                continue;
+            }
+            if (!is_numeric($item["首重价格"]) || $item["首重价格"] <= 0){
+                $errors[] = "第“".($index+2)."”行非法首重价格";
+                continue;
+            }
+            if (!is_numeric($item["续重价格"]) || $item["续重价格"] <= 0){
+                $errors[] = "第“".($index+2)."”行非法续重价格";
+                continue;
+            }
+            if (isset($existDetails[$map[$item["省"]]])){
+                $update[] = [
+                    "id" => $existDetails[$map[$item["省"]]],
+                    "initial_weight_price" => $item["首重价格"],
+                    "additional_weight_price" => $item["续重价格"],
+                    "updated_at" => $date,
+                ];
+                continue;
+            }
+            $insert[] = [
+                "owner_price_express_id" => $id,
+                "province_id" => $map[$item["省"]],
+                "initial_weight_price" => $item["首重价格"],
+                "additional_weight_price" => $item["续重价格"],
+                "created_at" => $date,
+            ];
+        }
+        if (count($update) > 1){
+            app(BatchUpdateService::class)->batchUpdate("owner_price_express_provinces",$update);
+            LogService::log(__METHOD__,"快递计费导入修改",json_encode($update));
+        }
+        if (count($insert) > 0){
+            OwnerPriceExpressProvince::query()->insert($insert);
+            LogService::log(__METHOD__,"快递计费导入录入",json_encode($insert));
+        }
+
+        $this->express->load(["details"=>function($query){$query->with("province");}]);
+        Cache::put("express",["success"=>true,"data"=>$this->express->details,"errors"=>$errors],86400);
+        return true;
+    }
+}

+ 1 - 1
app/Imports/OrderIssueImport.php

@@ -113,7 +113,7 @@ class OrderIssueImport implements ToCollection, WithHeadingRow, WithMultipleShee
 
     /**
      * 该方法是实现上传文件只选中 第一个表
-     * ExcelImprot 默认是有多少个分表就执行多少次的分表
+     * ExcelImport 默认是有多少个分表就执行多少次的分表
      * @return OrderIssueImport[]|array
      */
     public function sheets(): array

+ 253 - 0
app/Imports/OrderTrackingImport.php

@@ -0,0 +1,253 @@
+<?php
+
+namespace App\Imports;
+
+use App\Commodity;
+use App\OracleBasSKU;
+use App\OracleDOCOrderHeader;
+use App\Order;
+use App\OrderPackage;
+use App\OrderPackageCommodities;
+use App\OrderTracking;
+use App\Owner;
+use App\Package;
+use App\Services\CommodityService;
+use App\Services\common\DataHandlerService;
+use App\Services\OracleDOCOrderHeaderService;
+use App\Services\OrderService;
+use App\Services\OrderTrackingService;
+use App\Shop;
+use Carbon\Carbon;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Str;
+use Maatwebsite\Excel\Concerns\ToCollection;
+
+class OrderTrackingImport implements ToCollection
+{
+
+    public $shops = [];
+    public $commodities = [];
+    public $bas_skus =[];
+    public $owner = null;
+    public $order = [];
+    public $orderPackages = [];
+    public $order_is = [];
+    /**
+     * @param Collection $collection
+     */
+    public function collection(Collection $collection)
+    {
+        /**
+         * @var OrderTrackingService $service
+         * @var OrderService $orderService
+         * @var DataHandlerService $dataHandlerService
+         * @var Order $order
+         * @var OrderPackage $package
+         * @var Commodity $commodity
+         */
+        $service = app('OrderTrackingService');
+        $owner = Owner::query()->where('name','安桥主品')->first();
+        $this->owner = $owner;
+        $collection->shift();
+        // 1 450 3 400
+        $array =  $collection->chunk(450);
+        foreach ($array as $item_arr) {
+            $inner_params = [];
+            foreach ($item_arr as $items) {
+                $order = $this->getOrder($items[1], $items);
+                $orderPackageCommodities = $this->getOrderPackageCommodities($items);
+                $bas_sku = $this->getBasSku((string)$items[6]);
+                $gross_weight = round(($bas_sku->grossweight ?? 0) * $orderPackageCommodities->amount, 2);
+                $bulk = round(($bas_sku->cube ?? 0) * $orderPackageCommodities->amount, 2);
+                $inner_params[] = [
+                    'order_package_commodity_id' => $orderPackageCommodities->id,
+                    'owner_id' => $owner->id,
+                    'web_order_number' => $items[2],
+                    'order_client_code' => $order->client_code,
+                    'gross_weight' => $gross_weight,
+                    'bulk' => $bulk,
+                ];
+            }
+            $this->order = [];
+            $this->bas_skus = [];
+            $this->shops = [];
+            $this->order = [];
+            $this->orderPackages = [];
+            try {
+                OrderTracking::query()->insert($inner_params);
+                app('LogService')->log(__METHOD__,__FUNCTION__,'批量创建 OrderTracking'.' || '.json_encode($inner_params));
+            } catch (\Exception $e) {
+                app('LogService')->log(__METHOD__,'ERROR '.__FUNCTION__,'批量创建 OrderTracking ERROR'.json_encode($e->getMessage()).json_encode($e->getTraceAsString()).' || '.' || '.json_encode($inner_params));
+            } finally {
+                unset($inner_params,$item_arr);
+            }
+        }
+
+    }
+
+    public function getOrderPackageCommodities($items){
+        /**
+         * @var OrderService $orderService
+         */
+        $orderService = app('OrderService');
+        $packages = $this->getPackage($items[1],$items);
+        $packages = collect($packages);
+        if(!$packages||$packages->isEmpty()){
+            app('LogService')->log(__METHOD__,__FUNCTION__,'导入空值:'.json_encode($packages));
+        };
+        $orderPackageCommodities = null;
+        if(count($packages)>1){
+            $bool = false;
+            foreach ($packages as $package) {
+                foreach (($package->commodities ?? []) as $commodities) {
+                    if (isset($commodities->commodity) && $bool == false) {
+                        if ($commodities->commodity->sku == $items[6] && $commodities->amount == $items[8]) {
+                            $package->commodities = $package->commodities->filter(function($item)use($commodities){
+                                return $item->id != $commodities->id;
+                            });
+                            return $commodities;
+                        }
+                    }
+                }
+            }
+        }elseif(count($packages)==1){
+            $bool = false;
+            foreach ($packages as $package) {
+                foreach (($package->commodities ?? []) as $commodities) {
+                    if (isset($commodities->commodity) && $bool == false) {
+                        if ($commodities->commodity->sku == $items[6] && $commodities->amount == $items[8]) {
+                            $package->commodities = $package->commodities->filter(function($item)use($commodities){
+                                return $item->id != $commodities->id;
+                            });
+                            $this->orderPackages[$items[1]] = $packages;
+                            return $commodities;
+                        }
+                    }
+                }
+            }
+        }
+
+        if ($orderPackageCommodities == null) {
+            $package = $packages->first();
+            if(!$package){
+                $order=$this->order[$items[1]];
+                $package=$order->package;
+            }
+            $commodity = $this->getCommodity((string)$items[6], $items);
+            $orderPackageCommodities = OrderPackageCommodities::query()->create(['order_package_id' => $package['id'], 'commodity_id' => $commodity->id, 'amount' => $items[8]]);
+        }
+        return $orderPackageCommodities;
+    }
+
+
+    public function getOrderHeader($soReference1){
+        return  $orderHeader = OracleDOCOrderHeader::query()->selectRaw(implode(',',OracleDOCOrderHeaderService::$columns))
+            ->with(['oracleBASCustomer'=>function($query){
+                $query->selectRaw('BAS_CUSTOMER.CustomerID,BAS_CUSTOMER.Customer_Type,BAS_CUSTOMER.Descr_C,BAS_CUSTOMER.Active_Flag');
+            },'oracleDOCOrderDetails'=>function($query){
+                $query->selectRaw('doc_order_details.orderNo,doc_order_details.customerid,doc_order_details.sku,doc_order_details.QtyOrdered');
+            }, 'actAllocationDetails'=>function($query){
+                $query->selectRaw('ACT_Allocation_Details.AllocationDetailsID,ACT_Allocation_Details.OrderNo,ACT_Allocation_Details.Qty_Each,ACT_Allocation_Details.PickToTraceID,ACT_Allocation_Details.CustomerID,ACT_Allocation_Details.Sku');
+            },'oracleBASCode'=>function($query){
+                $query->selectRaw('BAS_Codes.CodeID,BAS_Codes.CodeName_C,BAS_Codes.Code');
+            }])
+            ->where('DOC_Order_Header.SOReference1',$soReference1)
+            ->first();
+    }
+
+    public function getShop($name){
+        if(!empty($this->shops[$name])){
+            return $this->shops[$name];
+        }else{
+            $shop = Shop::query()->firstOrCreate(['owner_id'=>$this->owner->id,'name'=>$name]);
+            $this->shops[$name] = $shop;
+            return $shop;
+        }
+    }
+    public function getCommodity(string $sku,&$items){
+        if(!empty($this->commodities[(string)$sku])){
+            return $this->commodities[(string)$sku];
+        }else{
+            $bas_sku = $this->getBasSku((string)$sku);
+            if($bas_sku == null){
+                $commodity = Commodity::query()->firstOrCreate(['sku'=>$sku,'name'=>$items[7],'owner_id'=>$this->owner->id]);
+                $this->commodities[(string)$sku] = $commodity;
+                return $commodity;
+            }
+            $commodity = Commodity::query()->firstOrCreate(['sku'=>$bas_sku['sku'],'name'=>$bas_sku['descr_c'],'owner_id'=>$this->owner->id]);
+            $this->commodities[(string)$sku] = $commodity;
+            return $commodity;
+        }
+    }
+
+    public function getBasSku($sku){
+        if(!empty($this->bas_skus[(string)$sku])){
+            return $this->bas_skus[(string)$sku];
+        }else{
+            $bas_sku = OracleBasSKU::query()->selectRaw('BAS_SKU.sku,BAS_SKU.customerid,BAS_SKU.grossweight,BAS_SKU.cube,BAS_SKU.descr_c')->where('sku',(string)$sku)->where('customerid',$this->owner->code)->first();
+            $this->bas_skus[(string)$sku] = $bas_sku;
+            return $bas_sku;
+        }
+    }
+
+    public function getOrder($client_no,&$items){
+        /**
+         * @var OrderService $orderService
+         */
+        $orderService = app('OrderService');
+        if( !empty($this->order[$client_no])){
+            return $this->order[$client_no];
+        }
+
+        $order = Order::query()->with('packages.commodities.commodity')->where('client_code',$client_no)->first();
+        if($order){
+            $this->order[$client_no] = $order;
+//            if(!$order)app('LogService')->log(__METHOD__,__FUNCTION__,'get1:'.json_encode($order));
+            return $order;
+        }else{
+            $orderHeader = $this->getOrderHeader($client_no);
+            if($orderHeader){
+                $orderService->createOrFindOrderInfo($orderHeader);
+                $order = Order::query()->with('packages.commodities.commodity')->where('client_code',$client_no)->first();
+                if(!$order){
+                    $shop = $this->getShop($items[5]);
+                    $order = Order::query()->create([
+                        'code'=>'null'.Str::uuid(),'client_code' => $items[1],'web_order_number' => $items[2],'shop_id'=>$shop->id
+                    ]);
+                }
+                $this->order[$client_no] = $order;
+                unset($orderHeader);
+//                if(!$order)app('LogService')->log(__METHOD__,__FUNCTION__,'get2:'.json_encode($order));
+                return $order;
+            }else{
+                $shop = $this->getShop($items[5]);
+                $order = Order::query()->create([
+                    'code'=>'null'.Str::uuid(),'client_code' => $items[1],'web_order_number' => $items[2],'shop_id'=>$shop->id
+                ]);
+//                app('LogService')->log(__METHOD__,__FUNCTION__,'create1:'.json_encode($order));
+                $this->order[$client_no] = $order;
+//                if(!$order)app('LogService')->log(__METHOD__,__FUNCTION__,'get3:'.json_encode($order));
+                return $order;
+            }
+        }
+    }
+
+    public function getPackage($client_code,&$items)
+    {
+        if(!empty($this->orderPackages[$client_code])){
+            return $this->orderPackages[$client_code];
+        }else{
+            $order = $this->getOrder($client_code,$items);
+            if($order && $order->packages->count() > 0 ){
+                $this->orderPackages[$client_code] = $order->packages;
+                return $order->packages;
+            }else{
+                $package = OrderPackage::query()->create(['order_id'=>$order->id,'logistic_number'=>'null_'.Str::uuid()]);
+                $list = collect();
+                $list->push($package);
+                $this->orderPackages[$client_code] = $list;
+                return $list;
+            }
+        }
+    }
+}

+ 135 - 0
app/Imports/OwnerPriceDirectLogisticDetailImport.php

@@ -0,0 +1,135 @@
+<?php
+
+namespace App\Imports;
+
+use App\CarType;
+use App\OwnerPriceDirectLogistic;
+use App\OwnerPriceDirectLogisticCar;
+use App\Services\common\BatchUpdateService;
+use App\Services\LogService;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Cache;
+use Maatwebsite\Excel\Concerns\ToCollection;
+use Maatwebsite\Excel\Concerns\WithHeadingRow;
+use Maatwebsite\Excel\Imports\HeadingRowFormatter;
+
+HeadingRowFormatter::default('none');
+class OwnerPriceDirectLogisticDetailImport implements ToCollection,WithHeadingRow
+{
+    protected $model;
+
+    public function __construct(OwnerPriceDirectLogistic $model)
+    {
+        $this->model = $model;
+    }
+
+    /**
+    * @param Collection $collection
+    * @return bool
+    */
+    public function collection(Collection $collection)
+    {
+        if (!$this->model){
+            Cache::put("directLogistic",["success"=>false, "data"=>"不存在父级"],86400);
+            return false;
+        }
+        $row = $collection->first();
+        $additional = "续费";
+        foreach ($row as $key => $str){
+            if (mb_strpos($key,$additional) !== false){
+                $row["续费"] = $str;
+                $additional = $key;
+                break;
+            }
+        }
+        $header = [
+            "车型","起步费","续费"
+        ];
+        foreach ($header as $str){
+            if (!isset($row[$str])){
+                Cache::put("directLogistic",["success"=>false, "data"=>"表头不存在“".$str."”"],86400);
+                return false;
+            }
+        }
+        if ($row)
+
+        //车型map
+        $map = [];
+        $carTypes = CarType::query()->get();
+        foreach ($carTypes as $carType){
+            $map[$carType->name] = $carType->id;
+        }
+
+        //已存在的计费
+        $existDetails = [];
+        foreach ($this->model->details as $detail){
+            $existDetails[$detail->car_type_id] = $detail->id;
+        }
+
+        //生成列表内的重复条目
+        $existInsert = [];
+
+        //导入的数据整理,存在更新
+        $id = $this->model->id;
+        $errors = [];
+        $insert = [];
+        $update = [["id","base_fee","additional_fee"]];
+        $date = date('Y-m-d H:i:s');
+        foreach ($collection as $index => $item){
+            /* 数据校验 */
+            if (!$item["车型"]){
+                $errors[] = "第“".($index+2)."”行车型为空";
+                continue;
+            }else{
+                if (!isset($map[$item["车型"]])){
+                    $errors[] = "第“".($index+2)."”行未知车型";
+                    continue;
+                }
+                $item["车型"] = $map[$item["车型"]];
+            }
+            if (!$item["起步费"] || !is_numeric($item["起步费"]) || $item["起步费"] <= 0){
+                $errors[] = "第“".($index+2)."”行非法起步费";
+                continue;
+            }
+            if (!$item[$additional] || !is_numeric($item[$additional]) || $item[$additional] <= 0){
+                $errors[] = "第“".($index+2)."”行非法续费";
+                continue;
+            }
+
+            if (isset($existInsert[$item["车型"]])){
+                $errors[] = "第“".($index+2)."”行与第“".$existInsert[$item["车型"]]."”行重复";
+                continue;
+            }
+
+            if (isset($existDetails[$item["车型"]])){
+                $update[] = [
+                    "id" => $existDetails[$item["车型"]],
+                    "base_fee" => $item["起步费"],
+                    "additional_fee" => $item[$additional],
+                    "updated_at" => $date,
+                ];
+                continue;
+            }
+            $insert[] = [
+                "owner_price_direct_logistic_id" => $id,
+                "car_type_id" => $item["车型"],
+                "base_fee" => $item["起步费"],
+                "additional_fee" => $item[$additional],
+                "created_at" => $date,
+            ];
+            $existInsert[$item["车型"]] = $index+2;
+        }
+        if (count($update) > 1){
+            app(BatchUpdateService::class)->batchUpdate("owner_price_direct_logistic_cars",$update);
+            LogService::log(__METHOD__,"直发车计费导入修改",json_encode($update));
+        }
+        if (count($insert) > 0){
+            OwnerPriceDirectLogisticCar::query()->insert($insert);
+            LogService::log(__METHOD__,"直发车计费导入录入",json_encode($insert));
+        }
+
+        $this->model->load(["details"=>function($query){$query->with("carType");}]);
+        Cache::put("directLogistic",["success"=>true,"data"=>$this->model->details,"errors"=>$errors],86400);
+        return true;
+    }
+}

+ 187 - 0
app/Imports/OwnerPriceLogisticDetailImport.php

@@ -0,0 +1,187 @@
+<?php
+
+namespace App\Imports;
+
+use App\City;
+use App\OwnerPriceLogistic;
+use App\OwnerPriceLogisticDetail;
+use App\Province;
+use App\Services\common\BatchUpdateService;
+use App\Services\LogService;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Cache;
+use Maatwebsite\Excel\Concerns\ToCollection;
+use Maatwebsite\Excel\Concerns\WithHeadingRow;
+use Maatwebsite\Excel\Imports\HeadingRowFormatter;
+
+
+HeadingRowFormatter::default('none');
+class OwnerPriceLogisticDetailImport implements ToCollection,WithHeadingRow
+{
+    protected $logistic;
+    public function __construct(OwnerPriceLogistic $logistic = null)
+    {
+        $this->logistic = $logistic;
+    }
+
+    /**
+    * @param Collection $collection
+    * @return bool
+    */
+    public function collection(Collection $collection)
+    {
+
+        if (!$this->logistic){
+            Cache::put("logistic",["success"=>false, "data"=>"不存在父级"],86400);
+            return false;
+        }
+        $row = $collection->first();
+        $header = [
+            "计数单位","计数区间","省份","市","单价","送货费","起始计费","起始计数","费率"
+        ];
+        foreach ($header as $str){
+            if (!isset($row[$str])){
+                Cache::put("logistic",["success"=>false, "data"=>"表头不存在“".$str."”"],86400);
+                return false;
+            }
+        }
+
+        //省份map
+        $map = [];
+        $provinces = Province::query()->get();
+        foreach ($provinces as $province){
+            $map[$province->name] = $province->id;
+        }
+
+        //市map
+        $cityMap = [];
+        $cityMappingProvince = [];
+        $cities = City::query()->get();
+        foreach ($cities as $city){
+            $cityMap[$city->name] = $city->id;
+            $cityMappingProvince[$city->id] = $city->province_id;
+        }
+
+        //对比单位
+        $unit = $this->logistic->unit ? strtoupper($this->logistic->unit->name) : '';
+        $otherUnit = $this->logistic->otherUnit ? strtoupper($this->logistic->otherUnit->name) : '';
+
+        //对比区间
+        $range = [
+            $unit => explode(",",$this->logistic->unit_range),
+            $otherUnit => explode(",",$this->logistic->other_unit_range),
+        ];
+
+        //已存在的计费
+        $existDetails = [];
+        foreach ($this->logistic->details as $detail){
+            $existDetails[$detail->unit_id.'_'.$detail->range."_".$detail->province_id."_".$detail->city_id] = $detail->id;
+        }
+
+        //生成列表内的重复条目
+        $existInsert = [];
+
+        //导入的数据整理,存在更新
+        $id = $this->logistic->id;
+        $errors = [];
+        $insert = [];
+        $update = [["id","unit_price","delivery_fee","initial_fee","initial_amount","rate","updated_at"]];
+        $date = date('Y-m-d H:i:s');
+        foreach ($collection as $index => $item){
+            /* 数据校验 */
+            if (!$item["省份"]){
+                $errors[] = "第“".($index+2)."”行省份为空";
+                continue;
+            }else{
+                if ((!isset($map[$item["省份"]]) && !isset($map[mb_substr($item["省份"], 0,-1)]))){
+                    $errors[] = "第“".($index+2)."”行未知省份";
+                    continue;
+                }
+                if (isset($map[mb_substr($item["省份"], 0,-1)]))$item["省份"] = mb_substr($item["省份"], 0,-1);
+            }
+            if (!$item["计数单位"] || (strtoupper($item["计数单位"]) != $unit && strtoupper($item["计数单位"]) != $otherUnit)){
+                //$errors[] = "第“".($index+2)."”行单位不符合";
+                //continue;
+                Cache::put("logistic",["success"=>false, "data"=>"第“".($index+2)."”行单位不符合"],86400);
+                return false;
+            }
+            if (!$item["计数区间"] || array_search($item["计数区间"],$range[strtoupper($item["计数单位"])]) === false){
+                //$errors[] = "第“".($index+2)."”行非法首重价格";
+                //continue;
+                Cache::put("logistic",["success"=>false, "data"=>"第“".($index+2)."”行区间不符合"],86400);
+                return false;
+            }
+            if (!isset($cityMap[$item["市"]])){
+                $errors[] = "第“".($index+2)."”行未知城市";
+                continue;
+            }
+            if (!$item["单价"] || !is_numeric($item["单价"]) || $item["单价"] <= 0){
+                $errors[] = "第“".($index+2)."”行非法单价";
+                continue;
+            }
+            $numeric = ["送货费","起始计费","起始计数","费率"];
+            $sign = false;
+            foreach ($numeric as $column){
+                if ($item[$column] && (!is_numeric($item[$column]) || $item[$column] <= 0)){
+                    $errors[] = "第“".($index+2)."”行非法".$column;
+                    $sign = true;
+                    break;
+                }
+            }
+            if ($sign)continue;
+
+            /* 数据转换及存在校验 */
+            if ($cityMappingProvince[$cityMap[$item["市"]]] != $map[$item["省份"]]){
+                $errors[] = "第“".($index+2)."”行城市不属于该省份";
+                continue;
+            }
+            $item["省份"] = $map[$item["省份"]];
+            $item["计数单位"] = strtoupper($item["计数单位"]) == $unit ? $this->logistic->unit_id : $this->logistic->other_unit_id;
+            $item["市"] = $cityMap[$item["市"]];
+            $key = $item["计数单位"]."_".$item["计数区间"]."_".$item["省份"]."_".$item["市"];
+            if (isset($existInsert[$key])){
+                $errors[] = "第“".($index+2)."”行与第“".$existInsert[$key]."”行重复";
+                continue;
+            }
+
+            if (isset($existDetails[$key])){
+                $update[] = [
+                    "id" => $existDetails[$key],
+                    "unit_price" => $item["单价"],
+                    "delivery_fee" => $item["送货费"],
+                    "initial_fee" => $item["起始计费"],
+                    "initial_amount" => $item["起始计数"],
+                    "rate" => $item["费率"],
+                    "updated_at" => $date,
+                ];
+                continue;
+            }
+            $insert[] = [
+                "owner_price_logistic_id" => $id,
+                "unit_id" => $item["计数单位"],
+                "range" => $item["计数区间"],
+                "province_id" => $item["省份"],
+                "city_id" => $item["市"],
+                "unit_price" => $item["单价"],
+                "delivery_fee" => $item["送货费"],
+                "initial_fee" => $item["起始计费"],
+                "initial_amount" => $item["起始计数"],
+                "rate" => $item["费率"],
+                "created_at" => $date,
+            ];
+            $existInsert[$key] = $index+2;
+        }
+        if (count($update) > 1){
+            app(BatchUpdateService::class)->batchUpdate("owner_price_logistic_details",$update);
+            LogService::log(__METHOD__,"物流计费导入修改",json_encode($update));
+        }
+        if (count($insert) > 0){
+            OwnerPriceLogisticDetail::query()->insert($insert);
+            LogService::log(__METHOD__,"物流计费导入录入",json_encode($insert));
+        }
+
+        $this->logistic->load(["details"=>function($query){$query->with(["province","unit","city"]);}]);
+        Cache::put("logistic",["success"=>true,"data"=>$this->logistic->details,"errors"=>$errors],86400);
+        return true;
+    }
+}

+ 30 - 22
app/LaborReport.php

@@ -17,11 +17,11 @@ class LaborReport extends Model
     protected $fillable=[
         'id','enter_number','user_workgroup_id','user_id','name','mobile_phone','identity_number','labor_company_id',
         'check_in_at','verify_at','group_user_id','check_out_at','online_duration','working_duration','created_at','updated_at',
-        'user_duty_check_id','relax_time'
+        'user_duty_check_id','relax_time','remark'
     ];
     protected $appends = [
-        'is_exportGroup','is_export', 'exit_at','enter_at','sequence', 'amountOfJoined','remark','thisRecordOnlineTime','thisRecordWorkingTime','thisRoundRecordWorkingTime',
-        'totalOnlineTime','verifyPerson','userDutyCheckVerifyUserId','isAdult','round_check_in_at','round_check_out_at','has_group_verify_right'
+        'is_exportGroup','is_export', 'exit_at','enter_at','sequence', 'amountOfJoined',/*'remark',*/'thisRecordOnlineTime','thisRecordWorkingTime','thisRoundRecordWorkingTime',
+        'totalOnlineTime','verifyPerson','userDutyCheckVerifyUserId','isAdult','round_check_in_at','round_check_out_at','has_group_verify_right',
     ];
     protected $tempFields = [
         'temEnteringRecord',
@@ -47,12 +47,23 @@ class LaborReport extends Model
     public function laborReportStatus(){
         return $this->hasMany('App\LaborReportStatus','labor_report_id','id');
     }
+    public function 未审核(){
+        return $this->hasOne('App\LaborReportStatus','labor_report_id','id')
+            ->where('status','未审核');
+    }
+    public function 已退场(){
+        return $this->hasOne('App\LaborReportStatus','labor_report_id','id')
+            ->where('status','已退场');
+    }
+    public function remarks(){
+        return $this->hasOne('App\Sign','signable_id','id')
+            ->where('field','remark')->where('signable_type','labor_reports');
+    }
     public function getRoundCheckInAtAttribute(){
         if (!$this['check_in_at'])return null;
         $round_check_in_at=Carbon::parse($this['check_in_at'])->format('i');
         if ($round_check_in_at>=0&&$round_check_in_at<=5) return Carbon::parse($this['check_in_at'])->clone()->setMinutes(00)->setSeconds(00)->format('Y-m-d H:i:s');
         if ($round_check_in_at>5&&$round_check_in_at<=35) return Carbon::parse($this['check_in_at'])->clone()->setMinutes(30)->setSeconds(00)->format('Y-m-d H:i:s');
-        //if ($round_check_in_at==30) return Carbon::parse($this['check_in_at'])->clone()->setMinutes(30)->setSeconds(00)->format('Y-m-d H:i:s');
         if ($round_check_in_at>35&&$round_check_in_at<=59) return Carbon::parse($this['check_in_at'])->clone()->addHour()->setMinutes(00)->setSeconds(00)->format('Y-m-d H:i:s');
     }
     public function getRoundCheckOutAtAttribute(){
@@ -60,13 +71,13 @@ class LaborReport extends Model
         $round_check_out_at=Carbon::parse($this['check_out_at'])->format('i');
         if ($round_check_out_at>=0&&$round_check_out_at<25) return Carbon::parse($this['check_out_at'])->clone()->setMinutes(00)->setSeconds(00)->format('Y-m-d H:i:s');
         if ($round_check_out_at>=25&&$round_check_out_at<=55) return Carbon::parse($this['check_out_at'])->clone()->setMinutes(30)->setSeconds(00)->format('Y-m-d H:i:s');
-        //if ($round_check_out_at==30) return Carbon::parse($this['check_out_at'])->clone()->setMinutes(30)->setSeconds(00)->format('Y-m-d H:i:s');
         if ($round_check_out_at>55&&$round_check_out_at<=59) return Carbon::parse($this['check_out_at'])->clone()->addHour()->setMinutes(00)->setSeconds(00)->format('Y-m-d H:i:s');
     }
-    public function getRemarkAttribute(){
-        return $this->hasOne('App\Sign','signable_id','id')
-            ->where('field','remark')->where('signable_type','labor_reports')->value('mark');
-    }
+//    public function getRemarkAttribute(){
+////        $this->hasOne('App\Sign','signable_id','id')
+////            ->where('field','remark')->where('signable_type','labor_reports')->value('mark');
+//        return $this['remarks']?$this['remarks']['mark']:null;
+//    }
     public function getHasGroupVerifyRightAttribute(){
         if (!Gate::allows('人事管理-临时工报表')){return null; }
         if (Gate::allows('人事管理-临时工报表-管理全部组')){return true;}
@@ -75,9 +86,7 @@ class LaborReport extends Model
         if (count($userWorkgroupIds)!=0) return in_array($this['user_workgroup_id'],$userWorkgroupIds);
 
     }
-    public function setRemarkAttribute($remark,$id){
-        return Sign::updateOrCreate(['signable_type'=>'labor_reports','signable_id'=>$id,'field'=>'remark'],['mark'=>$remark]);
-    }
+
     public function getIsExportGroupAttribute(){
         return $this['check_out_at']? true:false;
     }
@@ -210,9 +219,8 @@ class LaborReport extends Model
     {
 //        $laborReportStatus=LaborReportStatus::where('labor_report_id',$this['id'])->where('status','未审核')->orderBy('id','desc')->first();
 //        if (empty($laborReportStatus))return null;
-        $laborReportStatus=$this->laborReportStatus()->where('status','未审核')->orderBy('id','desc')->first();
-        if (empty($laborReportStatus))return null;
-        return Carbon::parse($laborReportStatus['created_at'])->format('Y-m-d H:i:s');
+//        return Carbon::parse($laborReportStatus['created_at'])->format('Y-m-d H:i:s');
+        return $this['未审核']?Carbon::parse($this['未审核']['created_at'])->format('Y-m-d H:i:s'):null;
     }
 
     public function getEnteringRecordAttribute()
@@ -227,11 +235,10 @@ class LaborReport extends Model
 
     public function getExitAtAttribute()
     {
-//        $laborReportStatus=LaborReportStatus::where('labor_report_id',$this['id'])->where('status','已退场')->orderBy('id','desc')->first();
-//        if (empty($laborReportStatus))return null;
-        $laborReportStatus=$this->laborReportStatus()->where('status','已退场')->orderBy('id','desc')->first();
-        if (empty($laborReportStatus))return null;
-        return Carbon::parse($laborReportStatus['created_at'])->format('Y-m-d H:i:s');
+        //$laborReportStatus=LaborReportStatus::where('labor_report_id',$this['id'])->where('status','已退场')->orderBy('id','desc')->first();
+        //if (empty($laborReportStatus))return null;
+        //return Carbon::parse($laborReportStatus['created_at'])->format('Y-m-d H:i:s');
+        return $this['已退场']?Carbon::parse($this['已退场']['created_at'])->format('Y-m-d H:i:s'):null;
     }
 
     //创建或获取进场编号
@@ -245,8 +252,9 @@ class LaborReport extends Model
     }
 
     public function getIsExportAttribute(){
-        $laborReportStatus=LaborReportStatus::where('labor_report_id',$this['id'])->orderBy('id','desc')->first();
-        return $laborReportStatus['status']=='已退场'?true:false;
+//        $laborReportStatus=LaborReportStatus::where('labor_report_id',$this['id'])->orderBy('id','desc')->first();
+//        return $laborReportStatus['status']=='已退场'?true:false;
+        return $this['已退场']?true:false;
     }
     //出场更新临时工报表信息
     static function exitAndChangeLaborReport($laborReport,$userDutyCheck){

+ 1 - 1
app/LaborReportStatus.php

@@ -12,6 +12,6 @@ class LaborReportStatus extends Model
         'id','status','labor_report_id','created_at',
     ];
 //    public function laborReport(){
-//        return $this->hasMany('App\LaborReport','id','labor_report_id');
+//        return $this->hasOne('App\LaborReport','id','labor_report_id');
 //    }
 }

+ 5 - 0
app/Logistic.php

@@ -19,4 +19,9 @@ class Logistic extends Model
         $logistic=Logistic::where('id',$id)->first();
         return $logistic?$logistic['name']:'';
     }
+
+    public function ownerPriceExpresses()
+    {
+        return $this->belongsToMany(OwnerPriceExpress::class,"owner_price_express_logistic","logistic_id","owner_price_express_id");
+    }
 }

+ 1 - 0
app/OracleBasSKU.php

@@ -20,5 +20,6 @@ class OracleBasSKU extends Model
      * column: SKU 产品编码
      *         ALTERNATE_SKU1 产品条码
      *         Descr_C 商品名称
+     *
      * */
 }

+ 11 - 4
app/OrderIssue.php

@@ -13,10 +13,15 @@ class OrderIssue extends Model
     use SoftDeletes;
 
     protected $fillable = [
-        'order_id', 'created_at', 'rejected_bill_id', 'rejecting_status', 'result_explain','logistic_number_return',
-        'situation_explain', 'order_issue_type_id', 'second_order_id', 'is_new_rejecting','second_client_no','second_logistic_number',
-        'final_status', 'logistic_indemnity_money', 'logistic_express_remission', 'baoshi_indemnity_money', 'baoshi_express_remission', 'user_workgroup_id',
-        'custom_code','imported_status'];
+        'order_id', 'created_at', 'rejected_bill_id',
+        'rejecting_status', 'result_explain','logistic_number_return',
+        'situation_explain', 'order_issue_type_id', 'second_order_id',
+        'is_new_rejecting','second_client_no','second_logistic_number',
+        'final_status',
+        'logistic_indemnity_money', 'logistic_express_remission',
+        'baoshi_indemnity_money', 'baoshi_express_remission', 'user_workgroup_id',
+        'custom_code','imported_status','finance_confirm',
+        'hidden_tag'];
     /*
      * second_client_no 二次客户订单号
      * second_logistic_number 二次运单号 【二次运单号可以单独存在,当二次客户订单号有对应的订单信息时,显示的是二次客户订单号对应的运单号,没有的话显示二次原单号】
@@ -27,6 +32,8 @@ class OrderIssue extends Model
      * custom_code  自定义订单号 客户客服自定义
      * imported_status 导入处理
      * 退回单号
+     * finance_confirm 财务确认
+     * hidden_tag 隐藏标识
      */
     protected $appends = [
 //        'secondLogisticNumber',

+ 5 - 0
app/OrderPackage.php

@@ -255,4 +255,9 @@ class OrderPackage extends Model
         $this->tempFields['temOracleInfo']=$resultOracleObjs->first();
         return $this->tempFields['temOracleInfo'];
     }
+    public function getLogisticNumberAttribute($val)
+    {
+        if(strpos($val,'null')!==false)return '';
+        return $val;
+    }
 }

+ 20 - 0
app/OrderTracking.php

@@ -16,6 +16,26 @@ class OrderTracking extends Model
         'is_on_duty_shift','is_arrival','signed_at',
         'receive_bill_status','remark','gross_weight','bulk'];
 
+    /*
+     * order_package_commodity_id 订单商品id
+     * owner_id 货主
+     * web_order_number WEB+订单号
+     * pick_up_at 提货时间
+     * sale 销售
+     * client 客户
+     * order_client_code 订单号
+     * order_remark 订单备注
+     * pallet_total 托盘合计
+     * planning_sent_at 应送达时间
+     * is_on_duty_shift 是否赶上卡班
+     * is_arrival 到货情况
+     * signed_at 签收时间
+     * receive_bill_status
+     * remark 签收单情况
+     * gross_weight 重量
+     * bulk 体积
+     */
+
     protected $appends =[
         'ownerName','sku','packageWeight','packageBulk','orderCity','packageLogisticNumber','packageLogistic','orderClientNumber'
     ];

+ 41 - 0
app/Owner.php

@@ -71,4 +71,45 @@ class Owner extends Model
     {   //项目组
         return $this->hasOne(UserOwnerGroup::class,"id","user_owner_group_id");
     }
+    public function ownerStoragePriceModels()
+    {   //仓储计费
+        return $this->belongsToMany(OwnerStoragePriceModel::class,"owner_storage_price_model_owner","owner_id","owner_storage_price_model_id");
+    }
+    public function ownerAreaReport()
+    {   //面积报表
+        return $this->hasOne(OwnerAreaReport::class,"owner_id","id");
+    }
+    public function ownerStoragePriceModelOwners()
+    {   //仓储计费-货主 中间表
+        return $this->hasMany(OwnerStoragePriceModelOwner::class,"owner_id","id");
+    }
+    public function ownerPriceOperations()
+    {   //作业计费
+        return $this->belongsToMany(OwnerPriceOperation::class,"owner_price_operation_owner","owner_id","owner_price_operation_id");
+    }
+    public function ownerPriceExpresses()
+    {   //快递计费
+        return $this->belongsToMany(OwnerPriceExpress::class,"owner_price_express_owner","owner_id","owner_price_express_id");
+    }
+    public function ownerPriceLogistics()
+    {   //物流计费
+        return $this->belongsToMany(OwnerPriceLogistic::class,"owner_price_logistic_owner","owner_id","owner_price_logistic_id");
+    }
+    public function ownerPriceDirectLogistics()
+    {   //直发车计费
+        return $this->belongsToMany(OwnerPriceDirectLogistic::class,"owner_price_direct_logistic_owner","owner_id","owner_price_direct_logistic_id");
+    }
+
+    public function getOwnerStoragePriceModelIds($type = 'string')
+    {   //获取仓储计费的关联ID字符串或数组
+        $this->load('ownerStoragePriceModelOwners');
+        if ($type == 'string'){
+            $ids = '';
+            foreach ($this->ownerStoragePriceModelOwners as $os){
+                $ids .= $os->owner_storage_price_model_id.",";
+            }
+            return $ids;
+        }
+        return array_column(($this->ownerStoragePriceModelOwners)->toArray(),"owner_storage_price_model_id");
+    }
 }

+ 17 - 7
app/OwnerAreaReport.php

@@ -7,19 +7,29 @@ use Illuminate\Database\Eloquent\Model;
 class OwnerAreaReport extends Model
 {
     protected $fillable = [
-        "owner_id",         //货主ID
-        "counting_month",   //结算月
-        "area_on_tray",     //货物整托
-        "area_on_half_tray",//货物半托
-        "area_on_flat",     //平面区面积
-        "accounting_area",  //结算面积
-        "status"            //状态
+        "owner_id",             //货主ID
+        "counting_month",       //结算月
+        "owner_storage_price_model_id", //仓储计费ID
+        "user_owner_group_id",  //项目组ID
+        "area_on_tray",         //货物整托
+        "area_on_half_tray",    //货物半托
+        "area_on_flat",         //平面区面积
+        "accounting_area",      //结算面积
+        "status"                //状态
     ];
 
     public function owner()
     {   //货主
         return $this->hasOne(Owner::class,"id","owner_id");
     }
+    public function userOwnerGroup()
+    {   //项目组
+        return $this->hasOne(UserOwnerGroup::class,"id","user_owner_group_id");
+    }
+    public function ownerStoragePriceModel()
+    {   //仓储计费
+        return $this->hasOne(OwnerStoragePriceModel::class,"id","owner_storage_price_model_id");
+    }
 
     /* 结算月格式转换,仅截取至月
      * 引用:CreateOwnerReport

+ 2 - 1
app/OwnerBillReport.php

@@ -14,10 +14,11 @@ class OwnerBillReport extends Model
        "difference",     //差额
        "confirmed",      //确认状态
    ];
+   public $timestamps=false;
 
    public function owner()
    {   //货主
-       $this->hasOne(Owner::class,"id","owner_id");
+       return $this->hasOne(Owner::class,"id","owner_id");
    }
 
     /* 结算月格式转换,仅截取至月

+ 0 - 1
app/OwnerFeeDetail.php

@@ -9,7 +9,6 @@ class OwnerFeeDetail extends Model
 {
     protected $fillable = [
         "owner_id",         //货主ID
-        "counting_month",   //结算月
         "worked_at",        //作业时间
         "type",             //类型
         "shop_id",          //店铺ID

+ 1 - 0
app/OwnerInStorageRule.php

@@ -12,6 +12,7 @@ class OwnerInStorageRule extends Model
         "unit_id",                  //单位ID
         "unit_price",               //单价
     ];
+    public $timestamps=false;
 
     public function unit()
     {   //单位

+ 13 - 1
app/OwnerOutStorageRule.php

@@ -8,16 +8,28 @@ class OwnerOutStorageRule extends Model
 {
     protected $fillable = [
         "owner_price_operation_id",         //作业计费ID
-        "owner_price_operation_strategy",   //作业计费策略
         "strategy",                         //出库策略
         "amount",                           //起步数
         "unit_id",                          //单位ID
         "unit_price",                       //单价
         "feature",                          //特征
+        "priority",                         //优先级 值越大越高
     ];
+    public $timestamps=false;
+
+    public static $features = null;
+    public static $columnMapping = null;
 
     public function unit()
     {   //单位
         return $this->hasOne(Unit::class,"id","unit_id");
     }
+
+
+    /* 格式化依据静态参数,在调用前设置  */
+    public function getFeatureFormatAttribute()
+    {
+        if ($this->strategy == '默认')return "/";
+        return app("FeatureService")->formatFeature(self::$features,$this->feature,self::$columnMapping);
+    }
 }

+ 11 - 1
app/OwnerPriceDirectLogistic.php

@@ -3,6 +3,7 @@
 namespace App;
 
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\DB;
 
 class OwnerPriceDirectLogistic extends Model
 {
@@ -11,8 +12,17 @@ class OwnerPriceDirectLogistic extends Model
         "base_km"   //起步公里数
     ];
 
-    public function ownerPriceDirectLogisticCars()
+    public function details()
     {   //直发车计费对应车型费
         return $this->hasMany(OwnerPriceDirectLogisticCar::class,"owner_price_direct_logistic_id","id");
     }
+    public function owners()
+    {   //货主中间表
+        return $this->belongsToMany(Owner::class,"owner_price_direct_logistic_owner","owner_price_direct_logistic_id","owner_id");
+    }
+
+    public function getOwnerIdAttribute()
+    {   //获取货主ID数组
+        return array_column(DB::select(DB::raw("SELECT * FROM owner_price_direct_logistic_owner WHERE owner_price_direct_logistic_id = ?"),[$this->id]),"owner_id");
+    }
 }

+ 20 - 5
app/OwnerPriceExpress.php

@@ -3,21 +3,36 @@
 namespace App;
 
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\DB;
 
 class OwnerPriceExpress extends Model
 {
     protected $fillable = [
-        "name",                     //名称
-        "initial_weight_unit_id",   //首重单位
-        "additional_weight_unit_id",//续重单位
+        "name",             //名称
+        "initial_weight",   //首重
+        "additional_weight",//续重
     ];
 
     public function owners()
     {   //货主
-        $this->belongsToMany(Owner::class,"owner_price_express_owner","owner_price_express_id","owner_id");
+        return $this->belongsToMany(Owner::class,"owner_price_express_owner","owner_price_express_id","owner_id");
     }
     public function logistics()
     {   //物流
-        $this->belongsToMany(Logistic::class,"owner_price_express_logistic","owner_price_express_id","logistic_id");
+        return $this->belongsToMany(Logistic::class,"owner_price_express_logistic","owner_price_express_id","logistic_id");
+    }
+    public function details()
+    {   //计费详情
+        return $this->hasMany(OwnerPriceExpressProvince::class,"owner_price_express_id","id");
+    }
+
+    public function getOwnerIdAttribute()
+    {   //获取货主ID数组
+        return array_column(DB::select(DB::raw("SELECT * FROM owner_price_express_owner WHERE owner_price_express_id = ?"),[$this->id]),"owner_id");
+    }
+
+    public function getLogisticIdAttribute()
+    {   //获取快递ID数组
+        return array_column(DB::select(DB::raw("SELECT * FROM owner_price_express_logistic WHERE owner_price_express_id = ?"),[$this->id]),"logistic_id");
     }
 }

+ 2 - 2
app/OwnerPriceExpressProvince.php

@@ -15,10 +15,10 @@ class OwnerPriceExpressProvince extends Model
 
     public function ownerPriceExpress()
     {   //快递计费
-        $this->belongsTo(OwnerPriceExpress::class,"owner_price_express_id","id");
+        return $this->belongsTo(OwnerPriceExpress::class,"owner_price_express_id","id");
     }
     public function province()
     {   //省份
-        $this->hasOne(Province::class,"id","province_id");
+        return $this->hasOne(Province::class,"id","province_id");
     }
 }

+ 24 - 0
app/OwnerPriceLogistic.php

@@ -3,6 +3,7 @@
 namespace App;
 
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\DB;
 
 class OwnerPriceLogistic extends Model
 {
@@ -17,6 +18,19 @@ class OwnerPriceLogistic extends Model
         "service_price",    //信息服务费
     ];
 
+    public function getUnitRangeJsonAttribute()
+    {
+        return json_encode(explode(",",$this->unit_range));
+    }
+    public function getOtherUnitRangeJsonAttribute()
+    {
+        return json_encode(explode(",",$this->other_unit_range));
+    }
+
+    public function details()
+    {
+        return $this->hasMany(OwnerPriceLogisticDetail::class,"owner_price_logistic_id","id");
+    }
     public function unit()
     {   //单位一
         return $this->hasOne(Unit::class,"id","unit_id");
@@ -33,4 +47,14 @@ class OwnerPriceLogistic extends Model
     {   //物流
         return $this->belongsToMany(Logistic::class,"owner_price_logistic_logistic","owner_price_logistic_id","logistic_id");
     }
+
+    public function getOwnerIdAttribute()
+    {   //获取货主ID数组
+        return array_column(DB::select(DB::raw("SELECT * FROM owner_price_logistic_owner WHERE owner_price_logistic_id = ?"),[$this->id]),"owner_id");
+    }
+
+    public function getLogisticIdAttribute()
+    {   //获取快递ID数组
+        return array_column(DB::select(DB::raw("SELECT * FROM owner_price_logistic_logistic WHERE owner_price_logistic_id = ?"),[$this->id]),"logistic_id");
+    }
 }

+ 14 - 0
app/OwnerPriceOperation.php

@@ -12,7 +12,11 @@ class OwnerPriceOperation extends Model
         "strategy",         //策略
         "feature",          //特征
         "remark",           //备注
+        "priority",         //优先级 值越大越高
     ];
+    public static $features = null;
+    public static $columnMapping = null;
+
 
     public function ownerInStorageRule()
     {   //入库规则
@@ -22,4 +26,14 @@ class OwnerPriceOperation extends Model
     {   //出库规则
         return $this->hasMany(OwnerOutStorageRule::class,"owner_price_operation_id","id");
     }
+    public function ownerPriceOperationOwners()
+    {   //货主中间表
+        return $this->belongsToMany(Owner::class,"owner_price_operation_owner","owner_price_operation_id","owner_id");
+    }
+
+    public function getFeatureFormatAttribute()
+    {
+        if ($this->strategy == '默认')return "/";
+        return app("FeatureService")->formatFeature(self::$features,$this->feature,self::$columnMapping);
+    }
 }

+ 1 - 0
app/OwnerReport.php

@@ -13,6 +13,7 @@ class OwnerReport extends Model
         "owner_id",                     //货主ID
         "counting_month",               //结算月
         "daily_average_order_amount",   //日均单量
+        "total",                        //总单量
         "current_month_counting_area",  //结算月盘点面积
         "last_month_counting_area",     //结算月上月盘点面积
         "owner_bill_report_id"          //账单ID

+ 10 - 0
app/OwnerStoragePriceModelOwner.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+class OwnerStoragePriceModelOwner extends Model
+{
+    protected $table = "owner_storage_price_model_owner";
+}

+ 23 - 0
app/Providers/AppServiceProvider.php

@@ -12,6 +12,7 @@ use App\Services\CommodityBarcodeService;
 use App\Services\common\DataHandlerService;
 use App\Services\CustomerService;
 use App\Services\DepositoryService;
+use App\Services\FeatureService;
 use App\Services\InventoryAccountMissionService;
 use App\Services\InventoryCompareService;
 use App\Services\LogService;
@@ -32,8 +33,17 @@ use App\Services\OrderService;
 use App\Services\OrderIssueWorkLoadService;
 use App\Services\OrderPackageCommoditiesService;
 use App\Services\OrderTrackingService;
+use App\Services\OwnerAreaReportService;
+use App\Services\OwnerBillReportService;
+use App\Services\OwnerFeeDetailService;
+use App\Services\OwnerOutStorageRuleService;
+use App\Services\OwnerPriceDirectLogisticService;
+use App\Services\OwnerPriceExpressService;
+use App\Services\OwnerPriceLogisticService;
+use App\Services\OwnerPriceOperationService;
 use App\Services\OwnerReportService;
 use App\Services\OwnerService;
+use App\Services\OwnerStoragePriceModelService;
 use App\Services\PackageService;
 use App\Services\PackageStatisticsService;
 use App\Services\ProcessesContentService;
@@ -48,6 +58,7 @@ use App\Services\StoreCheckingReceiveItemService;
 use App\Services\StoreCheckingReceiveService;
 use App\Services\StoreItemService;
 use App\Services\StoreService;
+use App\Services\UnitService;
 use App\Services\UserOwnerGroupService;
 use App\Services\UserService;
 use App\Services\WarehouseService;
@@ -142,6 +153,13 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('StoreItemService',StoreItemService::class);
         app()->singleton('PackageService',PackageService::class);
         app()->singleton('ProcessMethodService',ProcessMethodService::class);
+        app()->singleton('OwnerReportService',OwnerReportService::class);
+        app()->singleton('OwnerAreaReportService',OwnerAreaReportService::class);
+        app()->singleton('OwnerFeeDetailService',OwnerFeeDetailService::class);
+        app()->singleton('OwnerBillReportService',OwnerBillReportService::class);
+        app()->singleton('OwnerPriceExpressService',OwnerPriceExpressService::class);
+        app()->singleton('OwnerPriceLogisticService',OwnerPriceLogisticService::class);
+        app()->singleton('OwnerPriceDirectLogisticService',OwnerPriceDirectLogisticService::class);
 
         $this->loadingOrderModuleService();
         $this->loadingBasedModuleService();
@@ -169,6 +187,11 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('DepositoryService',DepositoryService::class);
         app()->singleton('UserOwnerGroupService',UserOwnerGroupService::class);
         app()->singleton('CustomerService',CustomerService::class);
+        app()->singleton('OwnerStoragePriceModelService',OwnerStoragePriceModelService::class);
+        app()->singleton('UnitService',UnitService::class);
+        app()->singleton('OwnerPriceOperationService',OwnerPriceOperationService::class);
+        app()->singleton('FeatureService',FeatureService::class);
+        app()->singleton('OwnerOutStorageRuleService',OwnerOutStorageRuleService::class);
     }
 
     private function loadingRejectedModuleService(){

+ 47 - 0
app/Services/CommodityService.php

@@ -3,6 +3,7 @@
 namespace App\Services;
 
 use App\Commodity;
+use App\Http\Controllers\CommodityController;
 use App\CommodityBarcode;
 use App\OracleBasSKU;
 use App\Owner;
@@ -266,4 +267,50 @@ Class CommodityService
         $commodity->delete();
     }
 
+    public function syncWMSOrderCode($owner,$skus)
+    {
+        $basSku = OracleBasSKU::query()->whereIn('SKU',$skus)->where('CustomerID',$owner->code)->get();
+        $inner_params = [];
+        $created_at = new Carbon();
+        $basSku->each(function($bas_sku)use(&$inner_params,$owner,$created_at){
+            $inner_params = [
+                'owner_id' => $owner->id,
+                'sku' => $bas_sku->sku,
+                'name' =>$bas_sku->descr_c,
+                'created_at' => $created_at,
+                'length' =>$bas_sku->skulength,
+                'width' => $bas_sku->skuwidth,
+                'height' => $bas_sku->skuhigh,
+                'volumn' => $bas_sku->cube
+            ];
+        });
+        if(count($inner_params) > 0){
+            try {
+                $this->insert($inner_params);
+                app('LogService')->log(__METHOD__, __FUNCTION__, json_encode($inner_params));
+            } catch (\Exception $e) {
+                app('LogService')->log(__METHOD__, 'Error '.__FUNCTION__, json_encode($inner_params).' || '.$e->getMessage());
+            }
+        }
+    }
+    //获取箱规
+    public function getPack($owner_id, $sku)
+    {
+        $that = $this;
+        return app("CacheService")->getOrExecute("pack_{$owner_id}_{$sku}",function ()use($owner_id,$sku,$that){
+            $commodity = $that->first([
+                "owner_id" => $owner_id,
+                "sku" => $sku
+            ]);
+            if (!$commodity || $commodity->pack === null){
+                $owner = app("OwnerService")->find($owner_id);
+                $action = new CommodityController();
+                $action->syncOwnerCommodities($owner->id,$owner->code,$sku);
+            }
+            return $that->first([
+                "owner_id" => $owner_id,
+                "sku" => $sku
+            ])->pack;
+        });
+    }
 }

+ 28 - 0
app/Services/CustomerService.php

@@ -11,4 +11,32 @@ Class CustomerService
         return Customer::query()->select($column)->get();
     }
 
+    public function paginate()
+    {
+        return Customer::query()->orderByDesc('id')->paginate(50);
+    }
+
+    public function create(array $params)
+    {
+        return Customer::query()->create($params);
+    }
+
+    public function find($id)
+    {
+        return Customer::query()->find($id);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = Customer::query();
+        foreach ($params as $column => $value){
+            $query->where($column,$value);
+        }
+        return $query->update($values);
+    }
+
+    public function destroy($id)
+    {
+        return Customer::destroy($id);
+    }
 }

+ 189 - 0
app/Services/FeatureService.php

@@ -0,0 +1,189 @@
+<?php 
+
+namespace App\Services; 
+
+use App\Feature;
+
+Class FeatureService
+{
+    public function getMapArray()
+    {
+        $features = Feature::query()->get();
+        $map = [];
+        foreach ($features as $feature){
+            $map[$feature->id] = ["type"=>$feature->type,"logic"=>$feature->logic,"describe"=>$feature->describe];
+        }
+        return $map;
+    }
+
+    public function translationFeature($str)
+    {
+        if (!$str)return null;
+        $result = [];
+        preg_match_all('/\d+|[\&\|\(\)]/',$str,$result); //初次匹配以数字&|()为分隔符生成数组
+        $sign = 0;  //为第二次切割做起点标记
+        $model = [];//第二次切割数组
+        $ids = [];//记录出现的特征ID,统一查询
+        foreach ($result[0] as $index => &$str){
+            if (is_numeric($str)){
+                $model[] = array_slice($result[0],$sign,($index-$sign)+1);
+                $sign = $index+1;
+                $ids[] = $str;
+                continue;
+            }
+            if ($index == count($result[0])-1 && $str == ')'){
+                $model[] = [")"];
+            }
+        }//以数字为标准切割策略组
+        $features = Feature::query()->find($ids);//查询出现的特征
+        $featureMap = [];
+        foreach ($features as $index => $feature){
+            $featureMap[$feature->id] = $index;
+        }//为查询的特征重组为key-val形式数组留做引用
+        foreach ($model as $index => &$m){
+            $arr = [
+                "strategyGroupStartSign" => false,//是否为策略组起点,这将在解析时解析为 (
+                "calculation" => "",//运算规则,目前仅有 &,| 翻译后填入
+                "type"=>"",  //特征类型
+                "id"=>"",  //特征ID
+                "logic"=>"",  //特征逻辑
+                "describe"=>"",  //特征信息
+                "strategyGroupEndSign" => false,//是否为策略组终点,这将在解析时解析为 )
+            ];//最终对象组模型,策略组将几组特征组合引用
+            foreach ($m as $str){
+                if (is_numeric($str)){//填入特征信息
+                    if (isset($featureMap[$str])){
+                        $arr["type"] = $features[$featureMap[$str]]->type;
+                        $arr["id"] = $features[$featureMap[$str]]->id;
+                        $arr["logic"] = $features[$featureMap[$str]]->logic;
+                        $arr["describe"] = $features[$featureMap[$str]]->describe;
+                    }
+                    continue;
+                }
+                switch ($str){//特殊字符的翻译
+                    case "(":
+                        $arr["strategyGroupStartSign"] = true;
+                        break;
+                    case ")":
+                        $model[$index-1]["strategyGroupEndSign"] = true;
+                        break;
+                    case "&":
+                        $arr["calculation"] = "并且";
+                        break;
+                    case "|":
+                        $arr["calculation"] = "或";
+                        break;
+                }
+            }
+            if (!$arr["id"]){
+                unset($model[$index]);
+                continue;
+            }
+            $m = $arr;//变更当前指针为翻译结果
+        }
+        return $model;
+    }
+
+    public function analysisFeature($features)
+    {
+        $str = "";
+        $map = [];
+        foreach ($features as &$feature){
+            if (!$feature["type"] || !$feature["logic"] || !$feature["describe"])continue;
+            $f = Feature::query()->firstOrCreate([
+                "type"=>$feature["type"],  //特征类型
+                "logic"=>$feature["logic"],  //特征逻辑
+                "describe"=>$feature["describe"],  //特征信息
+            ]);
+            $feature["id"] = $f->id;
+            $map[$feature["id"]] = $f;
+            if ($feature["calculation"] == '并且')$str .= '&';
+            else $str .= '|';
+            if ($feature["strategyGroupStartSign"])$str .= "(";
+            $str .= $feature["id"];
+            if ($feature["strategyGroupEndSign"])$str .= ")";
+        }
+        return ['feature'=>$str,"map"=>$map];
+    }
+
+    public function formatFeature(array $features, $value, $columnMapping = null)
+    {
+        if (!$features)return $value;
+        preg_match_all('/\d+|[\&\|\(\)]/',$value,$result);
+        foreach ($result[0] as &$str){
+            if (is_numeric($str) && isset($features[$str])){
+                $column = $features[$str]["type"];
+                $logic = $features[$str]["logic"];
+                $describe = $features[$str]["describe"];
+                if ($columnMapping){
+                    $column = $columnMapping[$column] ?? $column;
+                    switch ($logic){
+                        case "包含":
+                            $logic = " like ";
+                            $describe = "%".$describe."%";
+                            break;
+                        case "不包含":
+                            $logic = " not like ";
+                            $describe = "%".$describe."%";
+                            break;
+                        case "等于":
+                            $logic = " = ";
+                            break;
+                    }
+                    $str = $column.$logic.$describe;
+                }else $str = $features[$str]["type"].' '.$features[$str]["logic"].' '.$features[$str]["describe"];
+            }
+            if ($str == "&"){
+                if ($columnMapping) $str = " and ";
+                else $str = " 并且 ";
+            }
+            if ($str == "|"){
+                if ($columnMapping) $str = " or ";
+                else $str = " 或 ";
+            }
+        }
+        return implode("",$result[0]);
+    }
+
+    public function matchFeature($value, $columnMapping, $matchObject) :bool
+    {
+        preg_match_all('/\d+/',$value,$ids);
+        if ($ids[0])$fs = Feature::query()->whereIn("id",$ids[0])->get();
+        else return false;
+        $features = [];
+        foreach ($fs as $f){
+            $features[$f->id] = $f;
+        }
+        preg_match_all('/\d+|[\&\|\(\)]/',$value,$result);
+        foreach ($result[0] as &$str) {
+            if (is_numeric($str) && isset($features[$str])) {
+                $column = $features[$str]["type"];
+                $logic = $features[$str]["logic"];
+                $describe = $features[$str]["describe"];
+                $value = isset($columnMapping[$column]) ? $matchObject[$columnMapping[$column]] : '';
+                switch ($logic) {
+                    case "包含":
+                        $str = mb_strpos($value,$describe) === false ? 'false' : 'true';
+                        break;
+                    case "不包含":
+                        $str = mb_strpos($value,$describe) === false ? 'true' : 'false';
+                        break;
+                    case "等于":
+                        $str = $value == $describe ? 'true' : 'false';
+                        break;
+                }
+                continue;
+            }
+            if ($str == "&") {
+                $str = '&&';
+                continue;
+            }
+            if ($str == "|") {
+                $str = '||';
+            }
+        }
+        $is = implode("",$result[0]);
+        return eval("return $is;");
+    }
+
+}

+ 14 - 15
app/Services/LaborReportService.php

@@ -27,20 +27,15 @@ class LaborReportService
 {
     private function conditionQuery(array $params){
         $user=Auth::user();
-        $laborReports=LaborReport::query()->with(['user','userDutyCheck','userWorkgroup','laborCompany'])->orderBy('labor_reports.id','DESC');
+        $laborReports=LaborReport::query()
+            ->with(['user','userDutyCheck','userWorkgroup','laborCompany','laborReportStatus','已退场','未审核'])->orderBy('labor_reports.id','DESC');
         if (!($params["is_export"] ?? false)&&!($params['id']??null)){
             $laborReports = $laborReports->whereNotIn('labor_reports.enter_number',function ($builder)use($params){
                 $builder->select('enter_number')->from('labor_reports')
                     ->leftJoin('labor_report_statuses','labor_reports.id','labor_report_statuses.labor_report_id')
                     ->where('labor_report_statuses.status','已退场');
-//                if (!($params['created_at_start'] ?? false) ||!($params['created_at_end'] ?? false)){
-//                    $builder->where('labor_report_statuses.created_at','like',date('Y-m-d').'%');
-//                }
             });
         }else unset($params['is_export']);
-//        if (!($params['created_at_start'] ?? false) ||!($params['created_at_end'] ?? false)){
-//            $laborReports->where('labor_reports.created_at','like',date('Y-m-d').'%');
-//        }
         $columnQueryRules=[
             'enter_number' => ['timeLimit' => 15],
             'created_at_start' => ['alias' => 'created_at' , 'startDate' => ' 00:00:00'],
@@ -106,10 +101,10 @@ class LaborReportService
             //退场时间跨天情况
             $yesterdayDate=Carbon::now()->subDays(1)->format('Y-m-d');
             $laborReportYesterday=LaborReport::where('user_id',$userDutyCheck->user_id)->where('created_at','like',$yesterdayDate.'%')->orderBy('id','desc')->first();
-            if (!$laborReportYesterday->group_user_id&&!$laborReportYesterday->verify){
-                LaborReport::query()->where('user_id',$userDutyCheck->user_id)->whereNull('group_user_id')->whereNull('verify_at')->orderBy('id','desc')->delete();
-                $laborReportYesterday=LaborReport::where('user_id',$userDutyCheck->user_id)->where('created_at','like',$yesterdayDate.'%')->orderBy('id','desc')->first();
-            }
+//            if (!$laborReportYesterday->group_user_id&&!$laborReportYesterday->verify_at){
+//                LaborReport::query()->where('user_id',$userDutyCheck->user_id)->whereNull('group_user_id')->whereNull('verify_at')->orderBy('id','desc')->delete();
+//                $laborReportYesterday=LaborReport::where('user_id',$userDutyCheck->user_id)->where('created_at','like',$yesterdayDate.'%')->orderBy('id','desc')->first();
+//            }
 //            if (!$laborReportYesterday->check_out_at&&$laborReportYesterday['user_workgroup_id']){
 //                UserDutyCheck::where('user_id',$laborReportYesterday->user_id)->where('type','登出')->where('checked_at','like',Carbon::now()->format('Y-m-d H:i').'%')->orderBy('id','desc')->delete();
 //                return "<h1 style='color: darkred;text-align:center'>您还未退组,暂不可退场,请联系组长!</h1>";
@@ -119,10 +114,10 @@ class LaborReportService
                 if ($exportReport) event(new ExportEvent($exportReport));
         }
         if($laborReport&&$importAndExportQRCodeType=='export'){
-            if (!$laborReport->group_user_id&&!$laborReport->verify){
-                LaborReport::where('user_id',$userDutyCheck->user_id)->whereNull('group_user_id')->whereNull('verify_at')->orderBy('id','desc')->delete();
-                $laborReport=LaborReport::where('user_id',$userDutyCheck->user_id)->where('created_at','like',$dateNow.'%')->orderBy('id','desc')->first();
-            }
+//            if (!$laborReport->group_user_id&&!$laborReport->verify_at){
+//                LaborReport::where('user_id',$userDutyCheck->user_id)->whereNull('group_user_id')->whereNull('verify_at')->orderBy('id','desc')->delete();
+//                $laborReport=LaborReport::where('user_id',$userDutyCheck->user_id)->where('created_at','like',$dateNow.'%')->orderBy('id','desc')->first();
+//            }
 //            if (!$laborReport['check_out_at']&&$laborReport['user_workgroup_id']){
 //                UserDutyCheck::where('user_id',$laborReport->user_id)->where('type','登出')->where('checked_at','like',Carbon::now()->format('Y-m-d H:i').'%')->orderBy('id','desc')->delete();
 //                return "<h1 style='color: darkred;text-align:center'>您还未退组,暂不可退场,请联系组长!</h1>";
@@ -217,4 +212,8 @@ class LaborReportService
         return $laborReport;
     }
 
+    public function addOrUpdateRemark($remark,$id){
+        return LaborReport::query()->updateOrCreate(['id'=>$id],['remark'=>$remark]);
+    }
+
 }

+ 37 - 22
app/Services/OrderIssueService.php

@@ -82,7 +82,11 @@ class OrderIssueService
         if (isset($arr['custom_code'])) {
             $query->where('custom_code', $arr['custom_code']);
         }
-
+        if(isset($arr['hiddenTag'])){
+            $query->where('hidden_tag', $arr['hiddenTag']);
+        }else{
+            $query->whereNull('hidden_tag');
+        }
         $query->selectRaw('order_issues.* ,order_issue_on_tops.id top_id ,order_issue_on_tops.remark,order_issue_on_tops.updated_at top_update')
             ->leftJoin('order_issue_on_tops', 'order_issue_on_tops.order_issue_id', '=', 'order_issues.id')
             ->whereNull('order_issue_on_tops.deleted_at')
@@ -171,7 +175,8 @@ class OrderIssueService
             }
         }
         if (isset($condition['order_issue_type_id'])) {
-            $query->where('order_issue_type_id', $condition['order_issue_type_id']);
+            $type_ids = explode(',',$condition['order_issue_type_id']);
+            $query->whereIn('order_issue_type_id', $type_ids);
         }
         if (!($condition['is_handle'] ?? false) && !($condition['final_status'] ?? false)) {
             if (!(isset($condition['settlement_at_start']) || isset($condition['settlement_at_end']))) {
@@ -181,10 +186,21 @@ class OrderIssueService
             }
         }
         if (isset($condition['logistic_indemnity_money'])) {
-            $query->where('logistic_indemnity_money', $condition['logistic_indemnity_money']);
+            if($condition['logistic_indemnity_money']== '是'){
+                $query->whereNotNull('logistic_indemnity_money');
+            }elseif($condition['logistic_indemnity_money']== '否'){
+                $query->whereNull('logistic_indemnity_money');
+            }
         }
         if (isset($condition['baoshi_indemnity_money'])) {
-            $query->where('baoshi_indemnity_money', $condition['baoshi_indemnity_money']);
+            if($condition['baoshi_indemnity_money']== '是'){
+                $query->whereNotNull('baoshi_indemnity_money');
+            }elseif($condition['baoshi_indemnity_money']== '否'){
+                $query->whereNull('baoshi_indemnity_money');
+            }
+        }
+        if (isset($condition['rejectingStatus'])) {
+            $query->where('rejecting_status',$condition['rejectingStatus']);
         }
         if (isset($condition['order_issue_ids'])) {
             $orderIssuesId = $condition['order_issue_ids'];
@@ -290,11 +306,11 @@ class OrderIssueService
         if ($bool) {
             return ['success' => $bool];
         } else {
-            return ['success' => $bool, 'fail_info' => '问题件创建失败'];
+            return ['success' => $bool, 'fail_info' => '问题件创建失败,请检查勾选订单的状态'];
         }
     }
 
-    public function createOrderIssueByWmsOrder($orderHeaders, $order_issue_type_id, $result_explain, $imported_status = '正常', $custom_code = null)
+    public function createOrderIssueByWmsOrder($orderHeaders, $order_issue_type_id, $result_explain, $imported_status = '正常', $custom_code = null,$hiddenTag = null)
     {
         /** @var OrderService $orderService */
         $orderService = app('OrderService');
@@ -302,22 +318,21 @@ class OrderIssueService
 //        $orders = $orderService->getByWmsOrders($orderHeaders);
         $orderService->createByWmsOrder($orderHeaders);
         $orders = Order::query()->whereIn('code',data_get($orderHeaders,'*.orderno'))->whereHas('packages')->get();
-
+        if($orders->count()==0)return false;
         $innerParams = [];
-        if($orders->count()>0){
-            foreach ($orderHeaders as $orderHeader) {
-                $order = $orders->where('code',$orderHeader->orderno)->first();
-                if($order==null){
-                    $order = Order::query()->where('code',$orderHeader->orderno)->first();
-                }
-                $innerParams[] = [
-                    'order_id' => $order->id,
-                    'order_issue_type_id' => $order_issue_type_id,
-                    'result_explain' => $result_explain,
-                    'imported_status' => $imported_status,
-                    'custom_code' => $custom_code
-                ];
+        foreach ($orderHeaders as $orderHeader) {
+            $order = $orders->where('code',$orderHeader->orderno)->first();
+            if($order==null){
+                $order = Order::query()->where('code',$orderHeader->orderno)->first();
             }
+            $innerParams[] = [
+                'order_id' => $order->id,
+                'order_issue_type_id' => $order_issue_type_id,
+                'result_explain' => $result_explain,
+                'imported_status' => $imported_status,
+                'custom_code' => $custom_code,
+                'hidden_tag' => $hiddenTag
+            ];
         }
         try {
             $this->insert($innerParams);
@@ -498,14 +513,14 @@ class OrderIssueService
     }
 
 
-    public function createOrderIssue($logisticNumber, $type, $result_explain, $importedStatus = '正常', $custom_code = null)
+    public function createOrderIssue($logisticNumber, $type, $result_explain, $importedStatus = '正常', $custom_code = null,$hiddenTag = null)
     {
         $orderHeaders = OracleDOCOrderHeader::query()->with(['oracleDOCOrderDetails', 'actAllocationDetails', 'oracleBASCode'])
             ->whereHas('actAllocationDetails', function ($query) use ($logisticNumber) {
                 $query->where('picktotraceid', $logisticNumber);
             })->get();
         $orderIssueType = OrderIssueType::query()->where('name', $type)->first();
-        return $this->createOrderIssueByWmsOrder($orderHeaders, $orderIssueType->id, $result_explain, $importedStatus, $custom_code);
+        return $this->createOrderIssueByWmsOrder($orderHeaders, $orderIssueType->id, $result_explain, $importedStatus, $custom_code,$hiddenTag);
     }
 
     /**

+ 0 - 1
app/Services/OrderPackageService.php

@@ -437,7 +437,6 @@ class OrderPackageService
             $params = $this->getInnerParams($orderHeader,$order,$packages_maps);
             $inner_params = array_merge($inner_params,$params);
         }
-
         if(count($inner_params)>0){
             try {
                 $bool = $this->insert($inner_params);

+ 7 - 4
app/Services/OrderService.php

@@ -203,7 +203,7 @@ class OrderService
             $ordernos = app('OracleActAllocationDetailService')
                 ->getOrderno(['checktime_start'=>$checktime_start,'checktime_end'=>$checktime_end,
                     'paginate'=>$paginate,'page'=>$page]);
-            $params['ordernos'] = $ordernos;
+            if ($ordernos)$params['ordernos'] = $ordernos;
         }
         $sql="select ACT_ALLOCATION_DETAILS.CHECKTIME,DOC_ORDER_HEADER.addtime,DOC_ORDER_HEADER.C_PROVINCE,DOC_ORDER_HEADER.C_CITY,DOC_ORDER_HEADER.C_DISTRICT,DOC_ORDER_HEADER.C_CONTACT,DOC_ORDER_HEADER.OrderNo,DOC_ORDER_HEADER.SOStatus,DOC_ORDER_HEADER.WAREHOUSEID,DOC_ORDER_HEADER.CustomerID
         ,DOC_ORDER_HEADER.C_Tel2,DOC_ORDER_HEADER.C_Tel1,DOC_ORDER_HEADER.CarrierName,DOC_ORDER_HEADER.IssuePartyName,DOC_ORDER_HEADER.EDIREMARKS2,
@@ -697,8 +697,8 @@ class OrderService
         $warehouse = app('WarehouseService')->firstOrCreate(["code"=>$orderHeader->warehouseid],["code"=>$orderHeader->warehouseid,"name"=>$orderHeader->warehouseid]);
         return [
             'code' =>$orderHeader->orderno,
-            'owner_id' =>$owner->id,
-            'shop_id' =>$shop->id,
+            'owner_id' =>$owner->id ?? '',
+            'shop_id' =>$shop->id ?? '',
             'logistic_id' => $logistic->id ??'',
             'consignee_name' =>  $orderHeader->c_contact,
             'consignee_phone' =>  empty($orderHeader->c_tel2)?$orderHeader->c_tel1:$orderHeader->c_tel2,
@@ -879,7 +879,10 @@ class OrderService
         $warehouse = $dataHandlerService->getKeyValue(['code'=>$orderHeader->warehouseid],$warehouse_map);
         $owner = $dataHandlerService->getKeyValue(['code'=>$orderHeader->customerid],$owner_map);
         $logistic = $dataHandlerService->getKeyValue(['code'=>$orderHeader->userdefine1],$logistic_map);
-        $shop = $dataHandlerService->getKeyValue(['name'=>$orderHeader->issuepartyname,'owner_id'=>$owner->id??null],$shop_map);
+        $shop['id'] = null;
+        if($orderHeader->issuepartyname != null && $orderHeader->issuepartyname != '' ){
+            $shop = $dataHandlerService->getKeyValue(['name'=>$orderHeader->issuepartyname ?? '','owner_id'=>$owner->id??''],$shop_map);
+        }
         return [
             'code'=>$orderHeader['orderno'],
             'warehouse_id' => $warehouse['id'] ?? null,

+ 37 - 0
app/Services/OrderTrackingService.php

@@ -496,4 +496,41 @@ class OrderTrackingService
         ];
     }
 
+    public function fillInOrderTracking($orderTracking = null)
+    {
+        $orderTrackingIds = [];
+        try {
+            $date = new Carbon();
+            if($orderTracking==null){
+                $orderTracking = OrderTracking::query()
+                    ->where('created_at', '!=', '0000-00-00 00:00:00')
+                    ->where('planning_sent_at', '!=', '0000-00-00 00:00:00')
+                    ->whereNull('signed_at')
+                    ->where('planning_sent_at','<',$date)
+                    ->get();
+            }
+            if(count($orderTracking)==0)return;
+            $update_params = [['id','signed_at']];
+            $orderTracking = $orderTracking->where('created_at', '!=', '0000-00-00 00:00:00')
+                ->where('planning_sent_at', '!=', '0000-00-00 00:00:00')
+                ->whereNull('signed_at')
+                ->where('planning_sent_at','<',$date);
+            $orderTracking->each(function($item)use(&$update_params){
+                $update_params[] = [
+                    'id' => $item->id,
+                    'signed_at' => $item->planning_sent_at
+                ];
+            });
+            if(count($update_params) > 0) $this->batchUpdate($update_params);
+            $orderTrackingIds = data_get($orderTracking, '*.id');
+            OrderTracking::query()->whereIn('id', $orderTrackingIds)
+                ->whereNull('is_on_duty_shift')
+                ->whereNull('is_arrival')
+                ->update(['is_on_duty_shift' => '是', 'is_arrival' => '是']);
+            app('LogService')->log(__METHOD__,__FUNCTION__,'修改签收日期 是否赶上卡班 到货情况'.json_encode($orderTrackingIds));
+        } catch (\Exception $e) {
+            app('LogService')->log(__METHOD__,'ERROR '.__FUNCTION__,'修改签收日期 是否赶上卡班 到货情况 ERROR'.json_encode($orderTrackingIds).' || '.json_encode($e->getMessage()).' || '.json_encode($e->getTraceAsString()));
+        }
+    }
+
 }

+ 85 - 0
app/Services/OwnerAreaReportService.php

@@ -0,0 +1,85 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OwnerAreaReport;
+use App\OwnerBillReport;
+use App\Services\common\QueryService;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\DB;
+
+Class OwnerAreaReportService
+{
+    /**
+     * @param Builder $builder
+     * @param array $params
+     * @return Builder
+     */
+    private function query(Builder $builder, array $params)
+    {
+        $columnQueryRules = [
+            'counting_month_start' => ['alias' => 'counting_month', 'startDate' => '-01'],
+            'counting_month_end' => ['alias' => 'counting_month', 'endDate' => '-31'],
+            'owner_id' => ['multi' => ','],
+        ];
+        if ($params["customer_id"] ?? false){
+            $builder->whereHas('owner',function ($query)use(&$params){
+                /** @var Builder $query*/
+                $query->where("customer_id",$params["customer_id"]);
+                unset($params["customer_id"]);
+            });
+        }
+        return app(QueryService::class)->query($params, $builder, $columnQueryRules);
+    }
+
+    public function paginate(array $params, array $withs = null)
+    {
+        $areas = OwnerAreaReport::query()->orderByDesc('id');
+        if ($withs)$areas->with($withs);
+        return $this->query($areas,$params)->paginate($params["paginate"] ?? 50);
+    }
+
+
+    /**
+     * 面积变更会去对比账单更新账单 考虑到后续账单变更有多种渠道此处加排他锁
+     *
+     * @param array $params
+     * @param array $values
+     * @return int
+     */
+    public function update(array $params, array $values):bool
+    {
+        DB::beginTransaction();
+        $area = $this->query(OwnerAreaReport::query(),$params)->with("ownerStoragePriceModel")->lockForUpdate()->first();
+        try{
+            if ($values["accounting_area"] ?? null && $area->accounting_area != $values["accounting_area"]){
+                $report = OwnerBillReport::query()->lockForUpdate()->where("owner_id",$area->owner_id)
+                    ->where("counting_month",'like',$area->counting_month."%")->first();
+                if ($report){
+                    if (!$area->ownerStoragePriceModel)return false;
+                    $diff = $area->accounting_area - $values["accounting_area"];
+                    $diffAmount = app("OwnerStoragePriceModelService")->calculationAmount($area->ownerStoragePriceModel, $diff, $area->owner_id, $area->counting_month);
+                    if ($diffAmount != 0){
+                        $up = ["initial_fee"=>$report->initial_fee - $diffAmount];
+                        if ($report->confirm_fee !== null)$up["difference"] = $up["initial_fee"] - $report->confirm_fee;
+                        $report->update($up);
+                    }
+                }
+            }
+            $area->update($values);
+            DB::commit();
+            return true;
+        }catch (\Exception $e){
+            DB::rollBack();
+            return false;
+        }
+    }
+
+    public function get(array $params, array $withs = null)
+    {
+        $query = OwnerAreaReport::query()->orderByDesc('id');
+        if ($withs)$query->with($withs);
+        return $this->query($query,$params)->get();
+    }
+
+}

+ 58 - 0
app/Services/OwnerBillReportService.php

@@ -0,0 +1,58 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OwnerBillReport;
+use App\Services\common\QueryService;
+use Illuminate\Database\Eloquent\Builder;
+
+Class OwnerBillReportService
+{
+
+    /**
+     * @param Builder $builder
+     * @param array $params
+     * @return Builder
+     */
+    private function query(Builder $builder, array $params)
+    {
+        $columnQueryRules = [
+            'counting_month_start' => ['alias' => 'counting_month', 'startDate' => '-01'],
+            'counting_month_end' => ['alias' => 'counting_month', 'endDate' => '-31'],
+            'owner_id' => ['multi' => ','],
+        ];
+        if (($params["customer_id"] ?? false) || ($params["owner_group_id"] ?? false)){
+            $builder->whereHas('owner',function ($query)use(&$params){
+                /** @var Builder $query*/
+                if ($params["customer_id"] ?? false){
+                    $query->where("customer_id",$params["customer_id"]);
+                    unset($params["customer_id"]);
+                }
+                if ($params["owner_group_id"] ?? false){
+                    $query->where("user_owner_group_id",$params["owner_group_id"]);
+                    unset($params["owner_group_id"]);
+                }
+            });
+        }
+        return app(QueryService::class)->query($params, $builder, $columnQueryRules);
+    }
+
+    public function paginate(array $params, array $withs = null)
+    {
+        $bills = OwnerBillReport::query()->orderByDesc('id');
+        if ($withs)$bills->with($withs);
+        return $this->query($bills,$params)->paginate($params["paginate"] ?? 50);
+    }
+
+    public function update(array $params, array $values)
+    {
+        return $this->query(OwnerBillReport::query(),$params)->update($values);
+    }
+
+    public function get(array $params, array $withs = null)
+    {
+        $bills = OwnerBillReport::query()->orderByDesc('id');
+        if ($withs)$bills->with($withs);
+        return $this->query($bills,$params)->get();
+    }
+}

+ 58 - 0
app/Services/OwnerFeeDetailService.php

@@ -0,0 +1,58 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OwnerFeeDetail;
+use App\Services\common\QueryService;
+use Illuminate\Database\Eloquent\Builder;
+
+Class OwnerFeeDetailService
+{
+    /**
+     * @param Builder $builder
+     * @param array $params
+     * @return Builder
+     */
+    private function query(Builder $builder, array $params)
+    {
+        $columnQueryRules = [
+            'worked_at_start' => ['alias' => 'worked_at', 'startDate' => ''],
+            'worked_at_end' => ['alias' => 'worked_at', 'endDate' => ''],
+            'owner_id' => ['multi' => ','],
+            'id' => ['multi' => ','],
+            'operation_bill' => ['like' => ''],
+            'logistic_bill' => ['like' => ''],
+        ];
+        if ($params["customer_id"] ?? false){
+            $builder->whereHas('owner',function ($query)use(&$params){
+                /** @var Builder $query*/
+                $query->where("customer_id",$params["customer_id"]);
+                unset($params["customer_id"]);
+            });
+        }
+        return app(QueryService::class)->query($params, $builder, $columnQueryRules, 'owner_fee_details');
+    }
+
+    public function paginate(array $params, array $withs = null)
+    {
+        $areas = OwnerFeeDetail::query()->orderByDesc('id');
+        if ($withs)$areas->with($withs);
+        return $this->query($areas,$params)->paginate($params["paginate"] ?? 50);
+    }
+
+    public function getSql($params)
+    {
+        $query = $this->query(OwnerFeeDetail::query()->orderByDesc('id'),$params);
+        $query->selectRaw("owner_fee_details.*,(work_fee+logistic_fee) total");
+        $query->leftJoin("owners","owner_fee_details.owner_id","owners.id")
+            ->selectRaw("owners.name owner_name")
+        ->leftJoin("customers","owners.customer_id","customers.id")
+            ->selectRaw("customers.name customer_name")
+        ->leftJoin("shops","owner_fee_details.shop_id","shops.id")
+            ->selectRaw("shops.name shop_name")
+        ->leftJoin("logistics","owner_fee_details.logistic_id","logistics.id")
+            ->selectRaw("logistics.name logistic_name");
+        return $query->sql();
+    }
+
+}

+ 57 - 0
app/Services/OwnerOutStorageRuleService.php

@@ -0,0 +1,57 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OwnerOutStorageRule;
+
+Class OwnerOutStorageRuleService
+{ 
+    public function get(array $params, array $withs = [], $isTranslateFeature = false, array $translateColumn = [])
+    {
+        if ($isTranslateFeature){
+            $features = app("FeatureService")->getMapArray();
+            OwnerOutStorageRule::$features = $features;
+            OwnerOutStorageRule::$columnMapping = $translateColumn;
+        }
+        $rule = OwnerOutStorageRule::query();
+        if ($withs)$rule->with($withs);
+        foreach ($params as $column=>$param){
+            $rule->where($column,$param);
+        }
+        return $rule->get();
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = OwnerOutStorageRule::query();
+        foreach ($params as $column=>$param){
+            $query->where($column,$param);
+        }
+        return $query->update($values);
+    }
+
+    public function create(array $params)
+    {
+        return OwnerOutStorageRule::query()->create($params);
+    }
+
+    public function findUpdate(OwnerOutStorageRule $rule, array $values)
+    {
+        return $rule->update($values);
+    }
+
+    public function find($id)
+    {
+        return OwnerOutStorageRule::query()->find($id);
+    }
+
+
+    public function isExist(array $params)
+    {
+        $query = OwnerOutStorageRule::query();
+        foreach ($params as $column=>$param){
+            $query->where($column,$param);
+        }
+        return $query->count();
+    }
+}

+ 111 - 0
app/Services/OwnerPriceDirectLogisticService.php

@@ -0,0 +1,111 @@
+<?php 
+
+namespace App\Services; 
+
+use App\Owner;
+use App\OwnerPriceDirectLogistic;
+use App\OwnerPriceDirectLogisticCar;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\DB;
+
+Class OwnerPriceDirectLogisticService
+{ 
+    public function paginate($id = null)
+    {
+        $query = OwnerPriceDirectLogistic::query()->with("owners");
+        if($id)$query->where("id",$id);
+        return $query->paginate(50);
+    }
+
+    public function create(array $params)
+    {
+        return OwnerPriceDirectLogistic::query()->create($params);
+    }
+
+    public function destroy($id)
+    {
+        OwnerPriceDirectLogisticCar::query()->where("owner_price_direct_logistic_id",$id)->delete();
+        DB::table("owner_price_direct_logistic_owner")->where("owner_price_direct_logistic_id",$id)->delete();
+        return OwnerPriceDirectLogistic::destroy($id);
+    }
+
+    public function find($id)
+    {
+        return OwnerPriceDirectLogistic::query()->find($id);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = OwnerPriceDirectLogistic::query();
+        foreach ($params as $column=>$param){
+            $query->where($column,$param);
+        }
+        return $query->update($values);
+    }
+
+    public function updateDetail(array $params, array $values)
+    {
+        $query = OwnerPriceDirectLogisticCar::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->update($values);
+    }
+
+    public function isExistDetail(array $params)
+    {
+        $query = OwnerPriceDirectLogisticCar::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->count();
+    }
+
+    public function createDetail(array $params)
+    {
+        return OwnerPriceDirectLogisticCar::query()->create($params);
+    }
+
+    public function destroyDetail($id)
+    {
+        return OwnerPriceDirectLogisticCar::destroy($id);
+    }
+
+    public function getExistOwnerName($owner_id, $id) :array
+    {
+        if (!is_array($owner_id))$owner_id = [$owner_id];
+        $owners = Owner::query()->withCount(["ownerPriceDirectLogistics"=>function($query)use($id){
+            if ($id)$query->where("id","!=",$id);
+        }])->whereIn("id",$owner_id)->get();
+        $arr = [];
+        foreach ($owners as $owner){
+            if ($owner->owner_price_direct_logistics_count > 0)$arr[] = $owner->name;
+        }
+        return $arr;
+    }
+
+
+    /**
+     * CODE: -1:未找到计费模型
+     *
+     * @param double $amount
+     * @param integer $owner_id
+     * @param integer $car_id
+     * @return double
+     */
+    public function matching($amount, $owner_id, $car_id)
+    {
+        $model = OwnerPriceDirectLogistic::query()->with(["details"=>function($query)use($car_id){
+            /** @var Builder $query */
+            $query->where("car_type_id",$car_id);
+        }])->whereHas("owners",function ($query)use($owner_id){
+            /** @var Builder $query */
+            $query->where("id",$owner_id);
+        })->first();
+        if (!$model || !$model->details)return -1;
+        if ($amount < $model->base_km)$amount = $model->base_km;
+        $initialMoney = $model->base_km*$model->details[0]->base_fee;
+        $amount -= $model->base_km;
+        return ($amount*$model->details[0]->additional_fee)+$initialMoney;
+    }
+}

+ 130 - 0
app/Services/OwnerPriceExpressService.php

@@ -0,0 +1,130 @@
+<?php 
+
+namespace App\Services; 
+
+use App\Logistic;
+use App\Owner;
+use App\OwnerPriceExpress;
+use App\OwnerPriceExpressProvince;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\DB;
+
+Class OwnerPriceExpressService
+{ 
+
+    public function paginate($id = null)
+    {
+        $query = OwnerPriceExpress::query()->with(["owners","logistics"])
+            ->orderByDesc("id");
+        if ($id)$query->where("id",$id);
+        return $query->paginate(50);
+    }
+
+    public function find($id, $withs = [])
+    {
+        return OwnerPriceExpress::query()->with($withs)->find($id);
+    }
+
+    public function updateDetail(array $params, array $values)
+    {
+        $query = OwnerPriceExpressProvince::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->update($values);
+    }
+
+    public function create(array $params)
+    {
+        return OwnerPriceExpress::query()->create($params);
+    }
+
+    public function createDetail(array $params)
+    {
+        return OwnerPriceExpressProvince::query()->create($params);
+    }
+
+    public function isExistDetail(array $params)
+    {
+        $query = OwnerPriceExpressProvince::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->count();
+    }
+
+    public function destroyDetail($id)
+    {
+        return OwnerPriceExpressProvince::destroy($id);
+    }
+
+    public function getExistOwnerName($owner_id, $id=null) :array
+    {
+        if (!is_array($owner_id))$owner_id = [$owner_id];
+        $owners = Owner::query()->withCount(["ownerPriceExpresses"=>function($query)use($id){
+            if ($id)$query->where("id","!=",$id);
+        }])->whereIn("id",$owner_id)->get();
+        $arr = [];
+        foreach ($owners as $owner){
+            if ($owner->owner_price_expresses_count > 0)$arr[] = $owner->name;
+        }
+        return $arr;
+    }
+
+    public function getExistLogisticName($logistic_id, $id=null):array
+    {
+        $logistics = Logistic::query()->withCount(["ownerPriceExpresses"=>function($query)use($id){
+            if ($id)$query->where("id","!=",$id);
+        }])->whereIn("id",$logistic_id)->get();
+        $arr = [];
+        foreach ($logistics as $logistic){
+            if ($logistic->owner_price_expresses_count > 0)$arr[] = $logistic->name;
+        }
+        return $arr;
+    }
+
+    public function destroy($id)
+    {
+        OwnerPriceExpressProvince::query()->where("owner_price_express_id",$id)->delete();
+        DB::table("owner_price_express_owner")->where("owner_price_express_id",$id)->delete();
+        DB::table("owner_price_express_logistic")->where("owner_price_express_id",$id)->delete();
+        return OwnerPriceExpress::destroy($id);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = OwnerPriceExpress::query();
+        foreach ($params as $column=>$param){
+            $query->where($column,$params);
+        }
+        return $query->update($values);
+    }
+
+    /**
+     * CODE: -1:未找到计费模型
+     *
+     * @param double $weight
+     * @param integer $owner_id
+     * @param integer $logistic_id
+     * @param integer $province_id
+     * @return double
+     */
+    public function matching($weight, $owner_id, $logistic_id, $province_id)
+    {
+        $model = OwnerPriceExpress::query()->with(["details"=>function($query)use($province_id){
+            /** @var Builder $query */
+            $query->where("province_id",$province_id);
+        }])->whereHas("owners",function ($query)use($owner_id){
+            /** @var Builder $query */
+           $query->where("id",$owner_id);
+        })->whereHas("logistics",function ($query)use($logistic_id){
+            /** @var Builder $query */
+            $query->where("id",$logistic_id);
+        })->first();
+        if (!$model || !$model->details)return -1;
+        if ($weight < $model->initial_weight)$weight = $model->initial_weight;
+        $initialMoney = $model->initial_weight*$model->details[0]->initial_weight_price;
+        $weight -= $model->initial_weight;
+        return ($weight*$model->details[0]->additional_weight_price)+$initialMoney;
+    }
+}

+ 139 - 0
app/Services/OwnerPriceLogisticService.php

@@ -0,0 +1,139 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OwnerPriceLogistic;
+use App\OwnerPriceLogisticDetail;
+use Illuminate\Database\Eloquent\Builder;
+
+Class OwnerPriceLogisticService
+{ 
+    public function paginate($id = null)
+    {
+        $query = OwnerPriceLogistic::query()->with(["owners","logistics","unit","otherUnit"]);
+        if ($id)$query->where("id",$id);
+        return $query->paginate(50);
+    }
+
+    public function create(array $params)
+    {
+        return OwnerPriceLogistic::query()->create($params);
+    }
+
+    public function find($id, $withs=[])
+    {
+        return OwnerPriceLogistic::query()->with($withs)->find($id);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = OwnerPriceLogistic::query();
+        foreach ($params as $column=>$param){
+            $query->where($column,$params);
+        }
+        return $query->update($values);
+    }
+
+    public function updateDetail(array $params, array $values)
+    {
+        $query = OwnerPriceLogisticDetail::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->update($values);
+    }
+
+    public function isExistDetail(array $params)
+    {
+        $query = OwnerPriceLogisticDetail::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->count();
+    }
+
+    public function createDetail(array $params)
+    {
+        return OwnerPriceLogisticDetail::query()->create($params);
+    }
+
+    public function destroyDetail($id)
+    {
+        return OwnerPriceLogisticDetail::destroy($id);
+    }
+
+    public function checkRange($range):bool
+    {
+        $arrRanges = explode(",",$range);
+        $len = count($arrRanges);
+        if ($len==0)return false;   //范围为空 false
+        $previous = []; //慢指针数组 不记录第一个值
+        foreach ($arrRanges as $index => $value){
+            if ($index == $len-1)$preg = "/\d*\-/"; //最后一个范围不允许封闭
+            else $preg = "/\d*\-\d*/";
+            preg_match($preg, $value, $match);
+            if (!$match || $match[0]!=$value)return false;//匹配结果不等于值 false
+            $arr = explode("-",$value); //二次切割判断是否连续
+            if ($index != 0){
+                if ($index == $len-1){
+                    if ((int)$arr[0] != (int)$previous[$index-1][1])return false; //最后一个范围只需要判断起始值
+                }else{
+                    if ((int)$arr[0] != (int)$previous[$index-1][1] || (int)$arr[1] <= (int)$arr[0])return false; //普通范围起始值必须为上一个结束值 当前结束值必须大于起始值
+                }
+            }else{
+                if ((int)$arr[1] <= (int)$arr[0])return false; //第一个范围只需判断当前结束值大于起始值
+            }
+            $previous[] = $arr;
+        }
+        return true;
+    }
+
+    /**
+     * CODE: -1:未找到计费模型
+     *
+     * @param double $amount
+     * @param integer $owner_id
+     * @param integer $logistic_id
+     * @param integer $unit_id
+     * @param integer $province_id
+     * @param integer $city_id
+     * @return double
+     */
+    public function matching($amount, $owner_id, $logistic_id, $unit_id, $province_id, $city_id)
+    {
+        $model = OwnerPriceLogistic::query()->with(["details"=>function($query)use($province_id,$city_id){
+            /** @var Builder $query */
+            $query->where("province_id",$province_id)->where("city_id",$city_id);
+        }])->where(function ($query)use($unit_id){
+            /** @var Builder $query */
+            $query->where("unit_id",$unit_id)->orWhere("other_unit_id",$unit_id);
+        })->whereHas("owners",function ($query)use($owner_id){
+            /** @var Builder $query */
+            $query->where("id",$owner_id);
+        })->whereHas("logistics",function ($query)use($logistic_id){
+            /** @var Builder $query */
+            $query->where("id",$logistic_id);
+        })->first();
+        if (!$model || !$model->details)return -1;
+        $fee = $model->pick_up_price + $model->fuel_price + $model->service_price; //服务费
+        foreach ($model->details as $detail){
+            if ($unit_id != $detail->unit_id)continue;
+            $arr = explode("-",$detail->range);
+            if (count($arr) < 2){
+                if ($amount >= $arr[0])return $this->calculation($amount,$detail,$fee);
+            }else{
+                if ($amount >= $arr[0] && $amount < $arr[1])return $this->calculation($amount,$detail,$fee);
+            }
+        }
+        return -1;
+    }
+
+    private function calculation($amount, $detail, $fee)
+    {
+        if ($amount < $detail->initial_amount)$amount = $detail->initial_amount; //小于起始数以起始数为准
+        $initialMoney = $detail->initial_amount*$detail->unit_price; //起始数计费
+        $amount -= $detail->initial_amount; //减起始数为续数
+        if ($initialMoney < $detail->initial_fee)$initialMoney = $detail->initial_fee; //小于起始计费以起始计费为准
+        return ($amount*$detail->unit_price)+$initialMoney+$detail->delivery_fee+$fee;
+    }
+}

+ 253 - 0
app/Services/OwnerPriceOperationService.php

@@ -0,0 +1,253 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OwnerInStorageRule;
+use App\OwnerOutStorageRule;
+use App\OwnerPriceOperation;
+use App\Services\common\QueryService;
+use App\Unit;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\DB;
+
+Class OwnerPriceOperationService
+{
+    /**
+     * @param Builder $builder
+     * @param array $params
+     * @return Builder
+     */
+    private function query(Builder $builder, array $params)
+    {
+        if ($params["owner_id"] ?? false){
+            $ids = $this->ownerGetIds($params["owner_id"]);
+            if ($ids)$builder->whereIn("id",$ids);
+            unset($params["owner_id"]);
+        }
+        $columnQueryRules = [
+            "name" => ["like"=>""]
+        ];
+        return app(QueryService::class)->query($params, $builder, $columnQueryRules);
+    }
+
+    public function paginate(array $params, array $withs = [])
+    {
+        return $this->query(OwnerPriceOperation::query()->orderByDesc('id')->with($withs),$params)
+            ->paginate($params["paginate"] ?? 50);
+    }
+
+
+    private function ownerGetIds(string $owner_id)
+    {
+        if (!$owner_id)return [];
+        $arr = DB::select(DB::raw("SELECT owner_price_operation_id AS id FROM owner_price_operation_owner WHERE owner_id in (".$owner_id.")"));
+        return array_column($arr,"id");
+    }
+
+    public function destroy($id)
+    {
+        OwnerOutStorageRule::query()->where("owner_price_operation_id",$id)->delete();
+        OwnerInStorageRule::query()->where("owner_price_operation_id",$id)->delete();
+        DB::table("owner_price_operation_owner")->where("owner_price_operation_id",$id)->delete();
+        return OwnerPriceOperation::destroy($id);
+    }
+
+    /**
+     * @param array $params
+     * @return Model
+     */
+    public function create(array $params)
+    {
+        return OwnerPriceOperation::query()->create($params);
+    }
+
+    public function insertRule(array $params, $type = '出库')
+    {
+        if ($type == '出库')OwnerOutStorageRule::query()->insert($params);
+        else OwnerInStorageRule::query()->insert($params);
+    }
+
+    public function find($id, $isGetRule = false, $withs = [])
+    {
+        $query = OwnerPriceOperation::query()->with($withs)->find($id);
+        if ($isGetRule){
+            if ($query->operation_type == '入库'){
+                $query->load("ownerInStorageRule");
+                $query->rules = $query->ownerInStorageRule ? json_encode([$query->ownerInStorageRule]) : null;
+            }else{
+                $query->load("ownerOutStorageRules");
+                $query->rules = json_encode($query->ownerOutStorageRules);
+            }
+        }
+        return $query;
+    }
+
+    public function destroyRule($id, $type)
+    {
+        if ($type=="入库")OwnerInStorageRule::query()->where("owner_price_operation_id",$id)->delete();
+        else OwnerOutStorageRule::query()->where("owner_price_operation_id",$id)->delete();
+    }
+
+    public function findUpdate(OwnerPriceOperation $model, array $params)
+    {
+        return $model->update($params);
+    }
+
+    /** 参数顺序: 数量 匹配对象 列映射 货主ID 单位ID 类型 SKU .
+     *  匹配顺序: 类型 货主 策略 单位 特征                    ..多对多匹配规则废弃,1对1,设单位必定为件,对应规则必然只有一项存在
+     *  单位匹配: 件,箱,单 由小到大,依次换算匹配           .
+     * @param int $amount
+     * @param array|object $matchObject  key-val
+     * @param array $columnMapping       key-val
+     * @param string $owner_id
+     * @param string $type
+     * @param string $sku
+     * @return double
+     * 错误代码: -1:非法数量 -2:无计费模型 -3:未知单位 -4:sku为空 -5:货主未找到 -6:无箱规 -7:未匹配到计费模型
+     */
+    public function matchRule($amount, $matchObject, $columnMapping, $owner_id, $sku = null, $type = '出库')
+    {
+        if ($amount <= 0 )return -1;
+
+        $unitModels = Unit::query()->whereIn("name",["件","箱","单"])->get();
+        $units = [];
+        foreach ($unitModels as $unitModel)$units[$unitModel->id] = $unitModel->name;
+
+        $withs = $type=='出库' ? ['ownerOutStorageRules'=>function($query){
+            /** @var Builder $query */
+            $query->orderByRaw("CASE strategy  WHEN '默认' THEN 1 WHEN '特征' THEN 2 WHEN '起步' THEN 3 END DESC,priority DESC");
+        }] : ['ownerInStorageRule'] ;
+        $rules = OwnerPriceOperation::query()->with($withs)
+            ->where("operation_type","出库")
+            ->whereHas("ownerPriceOperationOwners",function ($query)use($owner_id){
+                /** @var Builder $query */
+                $query->where("id",$owner_id);
+            })
+            ->orderByRaw("strategy desc,priority desc")->get(); //货主下的全部规则
+        if (!$rules)return -2;
+
+        if ($type == '入库'){
+            foreach ($rules as $rule){
+                if (!$rule->ownerInStorageRule)continue;
+                if ($rule->strategy == '特征'){
+                    $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
+                    if ($bool === true){
+                        if (!isset($units[$rule->ownerInStorageRule->unit_id])) return -3;
+                        if ($units[$rule->ownerInStorageRule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
+                            $amount = $this->changeUnit($amount,$owner_id,$sku);
+                            if ($amount<0) return $amount;
+                        }
+                        if ($units[$rule->ownerInStorageRule->unit_id] == '单')$amount = 1; //为单时数量设为1;
+                        return ceil($amount/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
+                    };
+                }else{
+                    if (!isset($units[$rule->ownerInStorageRule->unit_id])) return -3;
+                    if ($units[$rule->ownerInStorageRule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
+                        $amount = $this->changeUnit($amount,$owner_id,$sku);
+                        if ($amount<0) return $amount;
+                    }
+                    if ($units[$rule->ownerInStorageRule->unit_id] == '单')$amount = 1; //为单时数量设为1;
+                    return ceil($amount/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
+                };
+            }
+            return -7;
+        }
+        //出库
+        foreach ($rules as $rule){
+            if (!$rule->ownerOutStorageRules)continue;
+            if ($rule->strategy == '特征'){
+                $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);//匹配特征
+                if ($bool === true){
+                    $money = $this->matchOutStorage($amount,$rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$sku);
+                    if ($money>0)return $money;
+                };
+            }else{
+                $money = $this->matchOutStorage($amount,$rule->ownerOutStorageRules,$columnMapping,$matchObject,$units,$owner_id,$sku);
+                if ($money>0)return $money;
+            };
+        }
+        return -7;
+    }
+    private function changeUnit($amount,$owner_id,$sku)
+    {
+        if (!$sku)return -4;
+        $pack = app("CommodityService")->getPack($owner_id,$sku);
+        if (!$pack)return -6;
+        return ceil($amount/$pack);
+    }
+    private function matchOutStorage($amount, $rules, $columnMapping, $matchObject, $units, $owner_id, $sku)
+    {
+        $money = 0;
+        foreach ($rules as $rule){
+            switch ($rule->strategy){
+                case "起步":
+                    $money = $rule->amount * $rule->unit_price;
+                    if ($units[$rule->unit_id] == '箱') { //为箱时同步商品寻找箱规
+                        if (!$sku)return -4;
+                        $pack = app("CommodityService")->getPack($owner_id,$sku);
+                        if (!$pack)return -6;
+                        $rule->amount *= $pack;
+                    }
+
+                    if ($amount < $rule->amount)$amount = $rule->amount;
+                    else $amount -= $rule->amount;
+                    break;
+                case "特征":
+                    if (app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject)){
+                        if (!isset($units[$rule->unit_id]) || $units[$rule->unit_id] == '单') return -3;
+                        if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
+                            $amount = $this->changeUnit($amount,$owner_id,$sku);
+                        }
+                        return (ceil($amount/$rule->amount)*$rule->unit_price)+$money;
+                    };
+                    break;
+                case "默认":
+                    if (!isset($units[$rule->unit_id]) || $units[$rule->unit_id] == '单') return -3;
+                    if ($units[$rule->unit_id] == '箱'){ //为箱时同步商品寻找箱规
+                        $amount = $this->changeUnit($amount,$owner_id,$sku);
+                    }
+                    return (ceil($amount/$rule->amount)*$rule->unit_price)+$money;
+                    break;
+            }
+        }
+        return -7;
+    }
+
+    private function matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $unit_id, $rules, $sku, $units = null, $isMatch = false)
+    {
+        /*foreach ($rules as $rule){
+            if ($unit_id != $rule->ownerInStorageRule->unit_id)continue;
+            else{
+                if ($rule->strategy == '特征'){
+                    $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
+                    if ($bool === true){
+                        return ceil($amount/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
+                    };
+                }else{
+                    return ceil($amount/$rule->ownerInStorageRule->amount)*$rule->ownerInStorageRule->unit_price;
+                };
+            }
+        }
+        //单位换算
+        if (!$units){
+            $unitModels = Unit::query()->whereIn("name",["件","箱","单"])->get();
+            if (!$unitModels) return null;
+            foreach ($unitModels as $unitModel)$units[$unitModel->name] = $unitModel->id;
+        }
+        $name = array_search($unit_id,$units);
+        //递归匹配
+        switch ($name){
+            case "件"://布尔值校验是否匹配过件来确保箱只匹配一次件
+                return $this->matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $units["箱"], $rules, $sku, $units, true);
+            case "箱"://箱存在向下向上转换
+                if ($isMatch){
+                    return $this->matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $units["单"], $rules, $sku, $units);
+                }else{
+                    return $this->matchInStorage($amount, $matchObject, $columnMapping, $owner_id, $units["件"], $rules, $sku, $units);
+                }
+            case "单"://三次匹配皆无,返回null
+                return null;
+        }*/
+    }
+}

+ 0 - 5
app/Services/OwnerReportService.php

@@ -59,9 +59,4 @@ Class OwnerReportService
         return $this->query($query,$params)->paginate($params["paginate"] ?? 50);
     }
 
-    public function getSql(array $params)
-    {
-
-    }
-
 }

+ 31 - 1
app/Services/OwnerService.php

@@ -85,8 +85,21 @@ Class OwnerService
         },config('cache.expirations.rarelyChange'));
     }
 
-    public function create(array $params){
+    public function find($id)
+    {
+        return Owner::query()->find($id);
+    }
+
+    public function update(Owner $owner, array $values, array $related = [])
+    {
+        if ($related["ownerStoragePriceModels"] ?? false)$owner->ownerStoragePriceModels()->sync($related["ownerStoragePriceModels"]);
+        return $owner->update($values);
+    }
+
+    public function create(array $params, array $related = []){
+        /** @var Owner $owner */
         $owner = Owner::query()->create($params);
+        if ($related["ownerStoragePriceModels"] ?? false)$owner->ownerStoragePriceModels()->syncWithoutDetaching($related["ownerStoragePriceModels"]);
         return $owner;
     }
 
@@ -158,6 +171,7 @@ Class OwnerService
         /** @var User $user */
         $user = Auth::user();
         $query = Owner::query();
+        if ($withs)$query->with($withs);
         if ($authority){
             $ids = $user->getPermittingOwnerIdsAttribute();
             if ($ids) $query->whereIn("id",$ids);
@@ -168,6 +182,22 @@ Class OwnerService
         return $query->get();
     }
 
+    public function paginate(array $params, array $withs = null, bool $authority = true, bool $notShowSoftDelete = false)
+    {
+        /** @var User $user */
+        $user = Auth::user();
+        $query = Owner::query();
+        if ($withs)$query->with($withs);
+        if ($authority){
+            $ids = $user->getPermittingOwnerIdsAttribute();
+            if ($ids) $query->whereIn("id",$ids);
+            else return null;
+        }
+        if ($notShowSoftDelete) $query->whereNull('deleted_at');
+        $query = $this->query($query,$params);
+        return $query->paginate($params["paginate"] ?? 50);
+    }
+
     private function query(Builder $builder, array $params)
     {
         foreach ($params as $column => $param){

+ 66 - 0
app/Services/OwnerStoragePriceModelService.php

@@ -0,0 +1,66 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OwnerReport;
+use App\OwnerStoragePriceModel;
+
+Class OwnerStoragePriceModelService
+{ 
+    public function getSelection(array $columns = ["counting_type","using_type"], array $withs = [])
+    {
+        return OwnerStoragePriceModel::query()->select($columns)->with($withs)->get();
+    }
+
+    public function paginate($id = null,array $withs = [])
+    {
+        $query = OwnerStoragePriceModel::query()->orderByDesc('id')->with($withs);
+        if ($id)$query->where("id",$id);
+        return $query->paginate($params["paginate"] ?? 50);
+    }
+
+    public function create(array $params)
+    {
+        return OwnerStoragePriceModel::query()->create($params);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = OwnerStoragePriceModel::query();
+        foreach ($params as $column => $value){
+            $query->where($column,$value);
+        }
+        return $query->update($values);
+    }
+
+    public function find($id)
+    {
+        return OwnerStoragePriceModel::query()->find($id);
+    }
+    public function destroy($id)
+    {
+        return OwnerStoragePriceModel::destroy($id);
+    }
+
+    //暂时不考虑单位换算问题:后期可能存在多单位换算,此处仅视为单位为 m²
+    public function calculationAmount(OwnerStoragePriceModel $model, $area, $owner_id = null, $month = null) :int
+    {
+        if (!$model || !$area) return 0;
+        if ((int)$area < $model->minimum_area) $area = (int)$model->minimum_area;
+        $money = $area*$model->price;
+        switch ($model->discount_type){
+            case "按单减免":
+                if ($owner_id && $month){
+                    $report = OwnerReport::query()->select("id","total")
+                        ->where("owner_id",$owner_id)
+                        ->where("counting_month","like",$month."%")->first();
+                    $money -= $report ? ($report->total)*($model->discount_value) : 0;
+                }
+                break;
+            case "固定减免":
+                $money -= (int)$model->discount_value;
+                break;
+        }
+        return $money;
+    }
+}

+ 30 - 0
app/Services/ProcessMethodService.php

@@ -11,4 +11,34 @@ Class ProcessMethodService
         return ProcessMethod::query()->select($column)->get();
     }
 
+    public function paginate()
+    {
+        return ProcessMethod::query()->orderByDesc('id')->paginate(50);
+    }
+
+    public function create(array $params)
+    {
+        return ProcessMethod::query()->create($params);
+    }
+
+
+    public function find($id)
+    {
+        return ProcessMethod::query()->find($id);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = ProcessMethod::query();
+        foreach ($params as $column => $value){
+            $query->where($column,$value);
+        }
+        return $query->update($values);
+    }
+
+    public function destroy($id)
+    {
+        return ProcessMethod::destroy($id);
+    }
+
 }

+ 4 - 0
app/Services/ShopService.php

@@ -9,6 +9,10 @@ use Carbon\Carbon;
 
 class ShopService
 {
+    public function getSelection(array $column = ['id', 'name'])
+    {
+        return Shop::query()->select($column)->get();
+    }
 
     function firstOrCreate(array $param, array $values = null){
         $shop = Shop::query();

+ 29 - 0
app/Services/UserOwnerGroupService.php

@@ -12,4 +12,33 @@ Class UserOwnerGroupService
         return UserOwnerGroup::query()->select($column)->get();
     }
 
+    public function paginate()
+    {
+        return UserOwnerGroup::query()->orderByDesc('id')->paginate(50);
+    }
+
+    public function create(array $params)
+    {
+        return UserOwnerGroup::query()->create($params);
+    }
+
+
+    public function find($id)
+    {
+        return UserOwnerGroup::query()->find($id);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = UserOwnerGroup::query();
+        foreach ($params as $column => $value){
+            $query->where($column,$value);
+        }
+        return $query->update($values);
+    }
+
+    public function destroy($id)
+    {
+        return UserOwnerGroup::destroy($id);
+    }
 }

+ 0 - 5
app/User.php

@@ -2,16 +2,11 @@
 
 namespace App;
 
-use App\Services\UserService;
-use Carbon\Carbon;
 use Illuminate\Notifications\Notifiable;
-use Illuminate\Contracts\Auth\MustVerifyEmail;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Gate;
-use Illuminate\Database\Eloquent\SoftDeletes;
 use App\Traits\ModelTimeFormat;
 
 class User extends Authenticatable

+ 1 - 0
config/users.php

@@ -6,4 +6,5 @@ return [
     'superAdmin' => ['ldaaww','baoshi56','周亚萍','shiyao','zhouzhendong','胡浩','zengjun','阿珺','huhao','yang'],
     'token_expire_minutes'=>7200,
     'token_check_in_expire_minutes'=>432000, //打卡过期时间,单位为秒
+    'cookie_expire_minutes'=>7200,//cookie过期时间,单位分钟
 ];

+ 13 - 0
database/factories/LogisticFactory.php

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

+ 27 - 0
database/factories/OrderTrackingFactory.php

@@ -0,0 +1,27 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use Faker\Generator as Faker;
+
+$factory->define(\App\OrderTracking::class, function (Faker $faker) {
+    return [
+        'order_package_commodity_id' => rand(10,100),
+        'owner_id' => rand(0,10),
+        'web_order_number'=>$faker->uuid,
+        'pick_up_at' =>$faker->dateTime(),
+        'sale' => $faker->name,
+        'client' => $faker->name,
+        'order_client_code' => $faker->uuid,
+        'order_remark' => $faker->text(10),
+        'pallet_total' => $faker->numberBetween(0,10),
+        'planning_sent_at'=>$faker->dateTimeBetween('-100 hour','now'),
+        'is_on_duty_shift'=>['是','否',null][rand(0,1)],
+        'is_arrival'=>['是','否',null][rand(0,1)],
+        'signed_at' => null,
+        'receive_bill_status'=>null,
+        'remark' => $faker->text(10),
+        'gross_weight'=>$faker->numberBetween(0,10),
+        'bulk' => $faker->numberBetween(0,10)
+    ];
+});

+ 3 - 3
database/factories/OwnerBillReportFactory.php

@@ -4,9 +4,9 @@
 
 use App\OwnerBillReport;
 use Faker\Generator as Faker;
-
-$factory->define(OwnerBillReport::class, function (Faker $faker) {
-    $owner = \App\Owner::query()->whereNotNull("user_owner_group_id")->first();
+$owner = \App\Owner::query()->whereNotNull("user_owner_group_id")->first();
+$factory->define(OwnerBillReport::class, function (Faker $faker)use(&$owner) {
+    if (!$owner)$owner = \App\Owner::query()->whereNotNull("user_owner_group_id")->first();
     $initial_fee = mt_rand(0,50000) / 10;
     $confirm_fee = mt_rand(0,50000) / 10;
     return [

+ 39 - 0
database/factories/OwnerFeeDetailFactory.php

@@ -0,0 +1,39 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerFeeDetail;
+use Faker\Generator as Faker;
+
+$owner = \App\Owner::query()->whereNotNull('customer_id')->first();
+if ($owner)$shop = \App\Shop::query()->where("owner_id",$owner->id)->first();
+else $shop = null;
+$logistic = \App\Logistic::query()->first();
+$method = \App\ProcessMethod::query()->first();
+$factory->define(OwnerFeeDetail::class, function (Faker $faker)use(&$owner,&$shop,&$logistic,&$method) {
+    if (!$owner)$owner = \App\Owner::query()->whereNotNull('customer_id')->first();
+    if (!$shop){
+        if ($owner)$shop = \App\Shop::query()->where("owner_id",$owner->id)->first();
+        else $shop = null;
+    }
+    if (!$logistic) $logistic = \App\Logistic::query()->first();
+    if (!$method)$method = \App\ProcessMethod::query()->first();
+    $type = ["发货","收货","增值服务"];
+    return [
+        "owner_id"          => $owner ? $owner->id : factory(\App\Owner::class),         //货主ID
+        "worked_at"         => $faker->date(),//作业时间
+        "type"              =>$type[array_rand($type)],//类型
+        "shop_id"           =>$shop ? $shop->id : factory(\App\Shop::class),//店铺ID
+        "operation_bill"    => \Illuminate\Support\Str::random(10),//发/收/退/提货单号
+        "consignee_name"    => $faker->name,   //收件人
+        "consignee_phone"   =>$faker->phoneNumber,  //收件人电话
+        "commodity_amount"  =>mt_rand(0,100), //商品数量
+        "logistic_bill"     =>\Illuminate\Support\Str::random(12),    //快递单号
+        "volume"            =>mt_rand(10,2600) / 88,//体积
+        "weight"            =>mt_rand(10,2600) / 88,           //重量
+        "logistic_id"       =>$logistic ? $logistic->id : factory(\App\Logistic::class),      //物流ID
+        "process_method_id" =>$method ? $method->id : factory(\App\ProcessMethod::class),//加工类型ID
+        "work_fee"          =>mt_rand(100,10000) / 10,         //作业费
+        "logistic_fee"      =>mt_rand(100,10000) / 10,     //物流费
+    ];
+});

+ 17 - 0
database/factories/OwnerInStorageRuleFactory.php

@@ -0,0 +1,17 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerInStorageRule;
+use Faker\Generator as Faker;
+
+$unit = \App\Unit::query()->first();
+$factory->define(OwnerInStorageRule::class, function (Faker $faker)use(&$unit){
+    if (!$unit)$unit = \App\Unit::query()->first();
+    return [
+        "owner_price_operation_id"  => factory(\App\OwnerPriceOperation::class), //作业计费ID
+        "amount"                    => mt_rand(0,100),                   //计量
+        "unit_id"                   => $unit ? $unit->id : factory(\App\Unit::class),//单位ID
+        "unit_price"                =>mt_rand(10,100) / 16,               //单价
+    ];
+});

+ 20 - 0
database/factories/OwnerOutStorageRuleFactory.php

@@ -0,0 +1,20 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerOutStorageRule;
+use Faker\Generator as Faker;
+
+$unit = \App\Unit::query()->first();
+$factory->define(OwnerOutStorageRule::class, function (Faker $faker)use(&$unit) {
+    if (!$unit)$unit = \App\Unit::query()->first();
+    $strategy = ['默认','特征'];
+    return [
+        "owner_price_operation_id"          => factory(\App\OwnerPriceOperation::class),         //作业计费ID
+        "strategy"                          =>$strategy[array_rand($strategy)],         //策略
+        "amount"                            =>mt_rand(0,100),                           //起步数
+        "unit_id"                           => $unit ? $unit->id : factory(\App\Unit::class),//单位ID
+        "unit_price"                        =>mt_rand(10,100) / 12,                       //单价
+        "feature"                           =>\Illuminate\Support\Str::random(6),                          //特征
+    ];
+});

+ 16 - 0
database/factories/OwnerPriceExpressFactory.php

@@ -0,0 +1,16 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerPriceExpress;
+use Faker\Generator as Faker;
+
+$unit = \App\Unit::query()->first();
+$factory->define(OwnerPriceExpress::class, function (Faker $faker)use(&$unit) {
+    if (!$unit)$unit = \App\Unit::query()->first();
+    return [
+        "name" => $faker->name,                     //名称
+        "initial_weight_unit_id" => $unit ? $unit->id : factory(\App\Unit::class),   //首重单位
+        "additional_weight_unit_id" => $unit ? $unit->id : factory(\App\Unit::class),//续重单位
+    ];
+});

+ 17 - 0
database/factories/OwnerPriceOperationFactory.php

@@ -0,0 +1,17 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerPriceOperation;
+use Faker\Generator as Faker;
+$factory->define(OwnerPriceOperation::class, function (Faker $faker) {
+    $operation_type = ['入库','出库'];
+    $strategy = ['默认','特征'];
+    return [
+        "operation_type"=>$operation_type[array_rand($operation_type)],   //操作类型
+        "name"          =>$faker->name,             //名称
+        "strategy"      =>$strategy[array_rand($strategy)],         //策略
+        "feature"       =>\Illuminate\Support\Str::random(10),          //特征
+        "remark"        =>$faker->text,           //备注
+    ];
+});

+ 22 - 0
database/factories/OwnerStoragePriceModelFactory.php

@@ -0,0 +1,22 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\OwnerStoragePriceModel;
+use Faker\Generator as Faker;
+$unit = \App\Unit::query()->first();
+$factory->define(OwnerStoragePriceModel::class, function (Faker $faker) use(&$unit){
+    if (!$unit) $unit = \App\Unit::query()->first();
+    $counting_type = ['包仓','灵活用仓','统单价'];
+    $using_type = ['常温','恒温'];
+    $discount_type = ['无减免','按单减免','固定减免'];
+    return [
+        "counting_type" => $counting_type[array_rand($counting_type)],    //计费类型
+        "using_type" => $using_type[array_rand($using_type)],       //用仓类型
+        "minimum_area" => mt_rand(100,1000) / 50,     //最低起租面积
+        "price" => mt_rand(1,20) / 10,            //单价
+        "discount_type" => $discount_type[array_rand($discount_type)],    //减免类型
+        "discount_value" => mt_rand(0,10) / 12,   //减免值
+        "unit_id" => $unit ? $unit->id : factory(\App\Unit::class),          //单位ID
+    ];
+});

+ 16 - 0
database/factories/ProcessMethodFactory.php

@@ -0,0 +1,16 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\ProcessMethod;
+use Faker\Generator as Faker;
+
+$unit = \App\Unit::query()->first();
+$factory->define(ProcessMethod::class, function (Faker $faker)use(&$unit) {
+    if (!$unit)$unit = \App\Unit::query()->first();
+    return [
+        'name' => $faker->name,
+        "unit_id" => $unit ? $unit->id : factory(\App\Unit::class),
+        "unit_price" => mt_rand(10,50) / 9,
+    ];
+});

+ 15 - 0
database/factories/ShopFactory.php

@@ -0,0 +1,15 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\Shop;
+use Faker\Generator as Faker;
+
+$owner = \App\Owner::query()->whereNotNull('customer_id')->first();
+$factory->define(Shop::class, function (Faker $faker)use(&$owner) {
+    if (!$owner) $owner = \App\Owner::query()->whereNotNull('customer_id')->first();
+    return [
+        'name' => $faker->name,
+        'owner_id' => $owner ? $owner->id : factory(\App\Owner::class),
+    ];
+});

+ 12 - 0
database/factories/UnitFactory.php

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

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

@@ -18,6 +18,7 @@ class CreateOwnerReportsTable extends Migration
             $table->bigInteger('owner_id')->index()->comment('外键货主');
             $table->date('counting_month')->nullable()->comment('结算月');
             $table->decimal('daily_average_order_amount',11,2)->nullable()->comment('日均单量');
+            $table->integer('total')->nullable()->comment("结算月总单量");
             $table->decimal('current_month_counting_area',11,2)->nullable()->comment('结算月盘点面积');
             $table->decimal('last_month_counting_area',11,2)->nullable()->comment('结算月上月盘点面积');
             $table->bigInteger('owner_bill_report_id')->nullable()->index()->comment('账单');

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

@@ -17,11 +17,13 @@ class CreateOwnerAreaReportsTable extends Migration
             $table->id();
             $table->bigInteger('owner_id')->index()->comment('外键货主');
             $table->date('counting_month')->index()->comment('结算月');
+            $table->bigInteger('user_owner_group_id')->index()->nullable()->comment('项目组');
             $table->decimal('area_on_tray',8,2)->nullable()->comment('货物整托');
             $table->decimal('area_on_half_tray',8,2)->nullable()->comment('货物半托');
             $table->decimal('area_on_flat',8,2)->nullable()->comment('平面区面积');
             $table->decimal('accounting_area',8,2)->nullable()->comment('结算面积');
             $table->enum('status',['编辑中','已完成'])->default('编辑中')->comment('状态');
+            $table->bigInteger("owner_storage_price_model_id")->index()->comment("关联仓储计费标准");
             $table->timestamps();
         });
     }

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

@@ -16,7 +16,6 @@ class CreateOwnerFeeDetailsTable extends Migration
         Schema::create('owner_fee_details', function (Blueprint $table) {
             $table->id();
             $table->bigInteger('owner_id')->index()->comment('外键货主');
-            $table->date('counting_month')->index()->comment('结算月');
             $table->date('worked_at')->index()->comment('作业时间');
             $table->enum('type',["发货","收货","增值服务"])->index()->comment('类型');
             $table->bigInteger('shop_id')->nullable()->index()->comment('外键店铺');

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

@@ -14,6 +14,7 @@ class CreateOwnerBillReportsTable extends Migration
     public function up()
     {
         Schema::create('owner_bill_reports', function (Blueprint $table) {
+            $table->engine = 'InnoDB';
             $table->id();
             $table->bigInteger('owner_id')->index()->comment('外键项目');
             $table->date('counting_month')->index()->comment('结算月');

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

@@ -13,7 +13,7 @@ class CreateOwnerStoragePriceModelTable extends Migration
      */
     public function up()
     {
-        Schema::create('owner_storage_price_model', function (Blueprint $table) {
+        Schema::create('owner_storage_price_models', function (Blueprint $table) {
             $table->id();
             $table->enum("counting_type",["包仓","灵活用仓","统单价"])->default("灵活用仓")->comment('计费类型');
             $table->enum("using_type",["常温","恒温"])->default("常温")->comment('用仓类型');
@@ -33,6 +33,6 @@ class CreateOwnerStoragePriceModelTable extends Migration
      */
     public function down()
     {
-        Schema::dropIfExists('owner_storage_price_model');
+        Schema::dropIfExists('owner_storage_price_models');
     }
 }

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

@@ -18,6 +18,7 @@ class CreateOwnerPriceOperationsTable extends Migration
             $table->enum("operation_type",["入库","出库"])->default("入库")->comment("操作类型");
             $table->string("name")->nullable()->comment("名称");
             $table->enum("strategy",["默认","特征"])->default("默认")->comment("策略");
+            $table->integer("priority")->default(0)->index()->comment("匹配优先级(越大越优先)");
             $table->string("feature")->nullable()->comment("特征");
             $table->string("remark")->nullable()->comment("备注");
             $table->timestamps();

+ 3 - 2
database/migrations/2020_10_28_105613_create_owner_out_storage_rules_table.php

@@ -14,13 +14,14 @@ class CreateOwnerOutStorageRulesTable extends Migration
     public function up()
     {
         Schema::create('owner_out_storage_rules', function (Blueprint $table) {
-            $table->bigInteger("owner_price_operation_id")->comment("外键作业计费模型");
-            $table->enum("owner_price_operation_strategy",["默认","特征"])->comment("作业计费模型策略");
+            $table->id();
+            $table->bigInteger("owner_price_operation_id")->index()->comment("外键作业计费模型");
             $table->enum("strategy",["起步","默认","特征"])->comment("出库策略");
             $table->integer("amount")->nullable()->comment("起步数");
             $table->bigInteger("unit_id")->index()->comment("外键单位");
             $table->decimal("unit_price",8,4)->comment("单价");
             $table->string("feature")->nullable()->comment("特征");
+            $table->integer("priority")->default(0)->index()->comment("匹配优先级(越大越优先)");
         });
     }
 

+ 2 - 1
database/migrations/2020_10_28_105639_create_owner_in_storage_rules_table.php

@@ -14,7 +14,8 @@ class CreateOwnerInStorageRulesTable extends Migration
     public function up()
     {
         Schema::create('owner_in_storage_rules', function (Blueprint $table) {
-            $table->bigInteger("owner_price_operation_id")->primary()->comment("外键作业计费模型");
+            $table->id();
+            $table->bigInteger("owner_price_operation_id")->index()->comment("外键作业计费模型");
             $table->integer("amount")->default(1)->comment("计量");
             $table->bigInteger("unit_id")->index()->comment("外键单位");
             $table->decimal("unit_price",8,4)->comment("单价");

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

@@ -16,8 +16,8 @@ class CreateOwnerPriceExpressesTable extends Migration
         Schema::create('owner_price_expresses', function (Blueprint $table) {
             $table->id();
             $table->string("name")->comment("价格名称");
-            $table->bigInteger("initial_weight_unit_id")->index()->comment("首重单位");
-            $table->bigInteger("additional_weight_unit_id")->index()->comment("续重单位");
+            $table->decimal("initial_weight")->comment("首重");
+            $table->decimal("additional_weight")->comment("续重");
             $table->timestamps();
         });
     }

+ 20 - 0
database/migrations/2020_10_28_170858_save_customer_authority_data.php

@@ -12,34 +12,54 @@ class SaveCustomerAuthorityData extends Migration
         '客户管理-项目-查询',
         '客户管理-项目-录入',
         '客户管理-项目-面积',
+        '客户管理-项目-面积-编辑',
+        '客户管理-项目-编辑',
         '客户管理-财务-即时账单',
         '客户管理-财务-账单确认',
+        '客户管理-财务-账单确认-编辑',
+        '客户管理-财务-账单确认-完结',
         '计费模型-仓储',
         '计费模型-仓储-录入',
+        '计费模型-仓储-编辑',
+        '计费模型-仓储-删除',
         '客户',
         '客户-查询',
         '客户-录入',
+        '客户-编辑',
+        '客户-删除',
         '项目组',
         '项目组-查询',
         '项目组-录入',
+        '项目组-编辑',
+        '项目组-删除',
         '作业类型',
         '作业类型-查询',
         '作业类型-录入',
+        '作业类型-编辑',
+        '作业类型-删除',
         '特征',
         '特征-录入',
         '特征-查询',
         '计费模型-作业',
         '计费模型-作业-查询',
         '计费模型-作业-录入',
+        '计费模型-作业-编辑',
+        '计费模型-作业-删除',
         '计费模型-快递',
         '计费模型-快递-查询',
         '计费模型-快递-录入',
+        '计费模型-快递-编辑',
+        '计费模型-快递-删除',
         '计费模型-物流',
         '计费模型-物流-查询',
         '计费模型-物流-录入',
+        '计费模型-物流-编辑',
+        '计费模型-物流-删除',
         '计费模型-直发',
         '计费模型-直发-查询',
         '计费模型-直发-录入',
+        '计费模型-直发-编辑',
+        '计费模型-直发-删除',
     ];
     /**
      * Run the migrations.

+ 31 - 0
database/migrations/2020_11_02_095633_create_owner_storage_price_model_owner_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateOwnerStoragePriceModelOwnerTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('owner_storage_price_model_owner', function (Blueprint $table) {
+            $table->bigInteger("owner_storage_price_model_id")->comment("外键仓储计费");
+            $table->bigInteger("owner_id")->comment("外键货主");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('owner_storage_price_model_owner');
+    }
+}

+ 31 - 0
database/migrations/2020_11_03_095611_create_owner_price_operation_owner_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateOwnerPriceOperationOwnerTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('owner_price_operation_owner', function (Blueprint $table) {
+            $table->bigInteger("owner_price_operation_id")->comment("外键作业价格");
+            $table->bigInteger("owner_id")->comment("外键货主");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('owner_price_operation_owner');
+    }
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов