LD 5 лет назад
Родитель
Сommit
bbb79572a3
34 измененных файлов с 503 добавлено и 112 удалено
  1. 2 18
      app/Console/Commands/CreateOwnerAreaReport.php
  2. 9 5
      app/Console/Commands/CreateOwnerReport.php
  3. 82 0
      app/Http/Controllers/CustomerController.php
  4. 15 2
      app/Http/Controllers/PriceModelController.php
  5. 2 6
      app/Http/Controllers/TestController.php
  6. 11 14
      app/Imports/ExpressImport.php
  7. 2 1
      app/Jobs/OrderCreateInstantBill.php
  8. 6 1
      app/OwnerStoragePriceModel.php
  9. 32 1
      app/Services/FeatureService.php
  10. 2 1
      app/Services/OrderService.php
  11. 30 0
      app/Services/OwnerAreaReportService.php
  12. 1 1
      app/Services/OwnerPriceOperationService.php
  13. 2 1
      app/Services/OwnerService.php
  14. 18 5
      app/Services/OwnerStoragePriceModelService.php
  15. 1 1
      app/Services/StoreService.php
  16. 37 0
      database/migrations/2021_01_27_174543_add_column_owner_price_model_storage.php
  17. 31 0
      database/migrations/2021_01_28_091010_add_authority_weight_panel.php
  18. 30 0
      resources/sass/animation.css
  19. 4 0
      resources/views/control/panel.blade.php
  20. 25 0
      resources/views/customer/_selectedOwner.blade.php
  21. 30 8
      resources/views/customer/project/area.blade.php
  22. 20 6
      resources/views/customer/project/create.blade.php
  23. 2 2
      resources/views/customer/project/menu.blade.php
  24. 2 2
      resources/views/customer/project/part/_directLogistic.blade.php
  25. 2 2
      resources/views/customer/project/part/_express.blade.php
  26. 28 16
      resources/views/customer/project/part/_storage.blade.php
  27. 3 1
      resources/views/customer/project/part/_three.blade.php
  28. 23 0
      resources/views/customer/project/report.blade.php
  29. 29 16
      resources/views/maintenance/priceModel/storage/create.blade.php
  30. 2 1
      resources/views/maintenance/priceModel/storage/index.blade.php
  31. 1 1
      resources/views/waybill/index.blade.php
  32. 4 0
      routes/web.php
  33. 14 0
      tests/Services/OwnerStoragePriceModelService/OwnerStoragePriceModelServiceTest.php
  34. 1 0
      webpack.mix.js

+ 2 - 18
app/Console/Commands/CreateOwnerAreaReport.php

@@ -35,7 +35,7 @@ class CreateOwnerAreaReport extends Command
     }
 
     /**
-     * 25号生成盘点面积记录,记录留空由人工填写
+     * 1号生成盘点面积记录,记录留空由人工填写
      *
      * @return void
      */
@@ -44,24 +44,8 @@ class CreateOwnerAreaReport extends Command
         /** @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);
-            LogService::log(__METHOD__,"客户管理-定时生成盘点记录",json_encode($createOwnerAreaReport));
+            app("OwnerAreaReportService")->notExistToInsert($owners);
         }
     }
 }

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

@@ -67,7 +67,7 @@ class CreateOwnerReport extends Command
         $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 SOSTATUS = '99' and 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){
@@ -117,9 +117,13 @@ class CreateOwnerReport extends Command
             ];
         }
         //执行生成或修改
-        app(BatchUpdateService::class)->batchUpdate('owner_reports', $updateReports);
-        app('LogService')->log(__METHOD__,"客户管理-修改原有货主报表",json_encode($updateReports));
-        DB::table("owner_reports")->insert($createReports);
-        app('LogService')->log(__METHOD__,"客户管理-生成货主报表",json_encode($createReports));
+        if (count($updateReports)>1){
+            app(BatchUpdateService::class)->batchUpdate('owner_reports', $updateReports);
+            app('LogService')->log(__METHOD__,"客户管理-修改原有货主报表",json_encode($updateReports));
+        }
+        if (count($createReports)>0){
+            DB::table("owner_reports")->insert($createReports);
+            app('LogService')->log(__METHOD__,"客户管理-生成货主报表",json_encode($createReports));
+        }
     }
 }

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

@@ -4,6 +4,8 @@ namespace App\Http\Controllers;
 
 use App\Components\AsyncResponse;
 use App\Owner;
+use App\OwnerAreaReport;
+use App\OwnerReport;
 use App\Services\LogService;
 use App\Services\OwnerAreaReportService;
 use App\Services\OwnerBillReportService;
@@ -420,4 +422,84 @@ class CustomerController extends Controller
     {
         $this->success($this->validator($request->input())->errors());
     }
+
+    public function createReport()
+    {
+        $ids = \request("val");
+        if (!$ids)$this->error("未选择任何项目");
+
+        $reports = OwnerReport::query()->with("owner")
+            ->where("counting_month",">=",date("Y-m")."-01")
+            ->whereIn("owner_id",$ids)->get(["id","owner_id"]);
+        $errors = [];
+        $exist = [];
+        foreach ($reports as $report){
+            $errors[] = "“".($report->owner ? $report->owner->name : $report->owner_id)."”已存在本月报表";
+            $exist[] = $report->owner_id;
+        }
+        $ids = array_diff($ids,$exist);
+        $insert = [];
+        $date = date("Y-m-d H:i:s");
+        foreach ($ids as $id){
+            $insert[] = [
+                "owner_id"       => $id,
+                "counting_month" => date("Y-m-d"),
+                "created_at"     => $date
+            ];
+        }
+        if ($insert){
+            OwnerReport::query()->insert($insert);
+            LogService::log(__METHOD__,"手动生成报表",json_encode($insert));
+        }
+        $reports = OwnerReport::query()->with(["owner.userOwnerGroup","owner.customer"])
+            ->where("counting_month",">=",date("Y-m")."-01")
+            ->whereIn("owner_id",$ids)->get();
+        $result = [];
+        foreach ($reports as $report){
+            $result[] = [
+                "id" => $report->id,
+                "ownerGroupName" => $report->owner ? ($report->owner->userOwnerGroup ? $report->owner->userOwnerGroup->name : '') : '',
+                "customerName" => $report->owner ? ($report->owner->customer ? $report->owner->customer->name : '') : '',
+                "ownerName" => $report->owner ? $report->owner->name : '',
+                "ownerStatus" => $report->owner ? ($report->owner->deleted_at ? "冻结" : "激活") : '',
+                "ownerStorageDuration" => $report->owner ? ($report->owner->created_at ? ((new \DateTime())->diff(new \DateTime($report->owner->created_at))->days)  : '') : '',
+                "ownerCreatedAt" => $report->owner ? $report->owner->created_at : '',
+                "countingMonth" => $report->counting_month,
+            ];
+        }
+        $this->success(["errors"=>$errors,"data"=>$result]);
+    }
+
+    public function createAreaReport()
+    {
+        $ids = \request("val");
+        if (!$ids)$this->error("未选择任何项目");
+
+        /** @var OwnerService $service */
+        $service = app("OwnerService");
+        $owners = $service->get(["id"=>$ids],["ownerStoragePriceModels"],false,true);
+        app("OwnerAreaReportService")->notExistToInsert($owners);
+
+        $reports = OwnerAreaReport::query()
+            ->where("counting_month",">=",date("Y-m")."-01")
+            ->whereIn("owner_id",array_column($owners->toArray(),"id"))->get();
+        $result = [];
+        foreach ($reports as $report){
+            $result[] = [
+                "id" => $report->id,
+                "ownerGroupId" => $report->user_owner_group_id,
+                "ownerName" => $report->owner ? $report->owner->name : '',
+                "customerName" => $report->owner ? ($report->owner->customer ? $report->owner->customer->name : '') : '',
+                "countingMonth" => $report->counting_month,
+                "areaOnTray" => $report->area_on_tray,
+                "areaOnHalfTray" => $report->area_on_half_tray,
+                "areaOnFlat" => $report->area_on_flat,
+                "accountingArea" => $report->accounting_area,
+                "status" => $report->status,
+                "updatedAt" => $report->updated_at,
+                "ownerStoragePriceModel"=> $report->ownerStoragePriceModel ? $report->ownerStoragePriceModel->using_type : '' ,
+            ];
+        }
+        $this->success($result);
+    }
 }

+ 15 - 2
app/Http/Controllers/PriceModelController.php

@@ -35,7 +35,7 @@ class PriceModelController extends Controller
     public function storageIndex(Request $request)
     {
         if(!Gate::allows('计费模型-仓储')){ return redirect('denied');  }
-        $models = app('OwnerStoragePriceModelService')->paginate($request->input("id"),["unit","owners"]);
+        $models = app('OwnerStoragePriceModelService')->paginate($request->input("id"),["unit","owners","timeUnit"]);
         return response()->view('maintenance.priceModel.storage.index',compact("models"));
     }
 
@@ -79,6 +79,7 @@ class PriceModelController extends Controller
             "discount_type" => $request->input("discount_type"),
             "discount_value"=> $request->input("discount_value"),
             "unit_id"       => $request->input("unit_id"),
+            "time_unit_id"  => $request->input("time_unit_id"),
         ]);
         $model = new OwnerStoragePriceModel();
         $model->id = $request->input("id");
@@ -105,6 +106,7 @@ class PriceModelController extends Controller
             'price'=>['required','numeric','min:0'],
             'discount_type'=>['required'],
             'unit_id'=>['required','integer'],
+            'time_unit_id'=>['required','integer'],
         ],[
             'required'=>':attribute 为必填项',
             'min'=>':attribute 不得小于0',
@@ -118,6 +120,7 @@ class PriceModelController extends Controller
             'discount_type' =>"减免类型",
             'discount_value'=>"减免值",
             'unit_id'       =>"单位",
+            'time_unit_id'  =>"计时单位",
         ]);
     }
 
@@ -1005,6 +1008,7 @@ class PriceModelController extends Controller
             "discount_type"     => request("discount_type"),
             "discount_value"    => request("discount_value") ?? 0,
             "unit_id"           => request("unit_id"),
+            "time_unit_id"      => request("time_unit_id"),
         ];
         if (request("id"))app('OwnerStoragePriceModelService')->update(["id"=>request("id")],$values);
         else{
@@ -1296,7 +1300,13 @@ class PriceModelController extends Controller
     {
         $owner = new Owner();
         $owner->id = request("id");
-        $owner->load(["ownerStoragePriceModels","ownerPriceOperations.items","ownerPriceExpresses"=>function($query){
+        $owner->load(["ownerStoragePriceModels","ownerPriceOperations"=>function($query){
+            /** @var Builder $query */
+            $query->with(["items"=>function($query){
+                /** @var Builder $query */
+                $query->orderByRaw("CASE strategy  WHEN '起步' THEN 1 WHEN '默认' THEN 2 WHEN '特征' THEN 3 END");
+            }]);
+        },"ownerPriceExpresses"=>function($query){
             /** @var Builder $query */
             $query->with(["details","logistics"]);
         },"ownerPriceLogistics"=>function($query){
@@ -1310,6 +1320,9 @@ class PriceModelController extends Controller
             $operation["featureFormat"] = $operation->featureFormat;
             foreach ($operation->items as &$item){
                 $item["featureFormat"] = $item->featureFormat;
+                if ($operation["operation_type"]==='出库' && $item["strategy"] == "起步"){
+                    $item["type"] = $item["amount"] ? 0 : 1;
+                }
             }
         }
         $this->success($owner);

+ 2 - 6
app/Http/Controllers/TestController.php

@@ -132,12 +132,8 @@ class TestController extends Controller
     }
 
     public function zzd(){
-        $update = [
-            ["id","wms_status","remark","updated_at"],
-            ["id"=>6,"wms_status"=>"完全收货",
-                "remark"=>"01.[ALLBLU]普通波次","updated_at"=>"2021-01-27 08:58:53"]
-        ];
-        dd(app(BatchUpdateService::class)->batchUpdate("batches",$update));
+        $month = "2020-02";
+        dd("50"*"2");
     }
 
     public function syncWeight()

+ 11 - 14
app/Imports/ExpressImport.php

@@ -43,7 +43,7 @@ class ExpressImport implements ToCollection,WithHeadingRow
         $map = [];
         $provinces = Province::query()->get();
         foreach ($provinces as $province){
-            $map[$province->name] = $province->id;
+            $map[mb_substr($province->name,0,2)] = $province->id;
         }
 
         if (!$this->express){
@@ -63,7 +63,8 @@ class ExpressImport implements ToCollection,WithHeadingRow
         $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["省"]])){
+            $province = mb_substr($item["省"],0,2);
+            if (!isset($map[$province])){
                 $errors[] = "第“".($index+2)."”行未知省份";
                 continue;
             }
@@ -75,9 +76,9 @@ class ExpressImport implements ToCollection,WithHeadingRow
                 $errors[] = "第“".($index+2)."”行非法续重价格";
                 continue;
             }
-            if (isset($existDetails[$map[$item["省"]]])){
+            if (isset($existDetails[$map[$province]])){
                 $update[] = [
-                    "id" => $existDetails[$map[$item["省"]]],
+                    "id" => $existDetails[$map[$province]],
                     "initial_weight_price" => $item["首重价格"],
                     "additional_weight_price" => $item["续重价格"],
                     "updated_at" => $date,
@@ -86,7 +87,7 @@ class ExpressImport implements ToCollection,WithHeadingRow
             }
             $insert[] = [
                 "owner_price_express_id" => $id,
-                "province_id" => $map[$item["省"]],
+                "province_id" => $map[$province],
                 "initial_weight_price" => $item["首重价格"],
                 "additional_weight_price" => $item["续重价格"],
                 "created_at" => $date,
@@ -111,14 +112,10 @@ class ExpressImport implements ToCollection,WithHeadingRow
         $errors = [];
         $data = [];
         foreach ($collection as $index => $item){
-            if (!isset($map[$item["省"]])){
-                foreach ($map as $name=>$id){
-                    if (mb_strpos($item["省"],$name) !== false)$item["省"] = $name;
-                }
-                if (!isset($map[$item["省"]])){
-                    $errors[] = "第“".($index+2)."”行未知省份";
-                    continue;
-                }
+            $province = mb_substr($item["省"],0,2);
+            if (!isset($map[$province])){
+                $errors[] = "第“".($index+2)."”行未知省份";
+                continue;
             }
             if (!is_numeric($item["首重价格"]) || $item["首重价格"] <= 0){
                 $errors[] = "第“".($index+2)."”行非法首重价格";
@@ -129,7 +126,7 @@ class ExpressImport implements ToCollection,WithHeadingRow
                 continue;
             }
             $data[] = [
-                "province_id" => $map[$item["省"]],
+                "province_id" => $map[$province],
                 "initial_weight_price" => $item["首重价格"],
                 "additional_weight_price" => $item["续重价格"],
             ];

+ 2 - 1
app/Jobs/OrderCreateInstantBill.php

@@ -36,7 +36,8 @@ class OrderCreateInstantBill implements ShouldQueue
     public function handle(OrderService $service)
     {
         try{
-            $service->createInstantBill($this->order);
+            if (!$service->createInstantBill($this->order))
+                LogService::log(__METHOD__,"ERROR-订单生成即时账单",$this->order->toJson());
         }catch (\Exception $e){
             LogService::log(__METHOD__,"ERROR-订单生成即时账单",$this->order->toJson()." | ".$e->getMessage());
         }

+ 6 - 1
app/OwnerStoragePriceModel.php

@@ -19,14 +19,19 @@ class OwnerStoragePriceModel extends Model
         "discount_type",    //减免类型
         "discount_value",   //减免值
         "unit_id",          //单位ID
+        "time_unit_id",     //计时单位ID
     ];
 
     public function unit()
     {   //单位
-        return $this->hasOne(Unit::class,"id","unit_id");
+        return $this->belongsTo(Unit::class);
     }
     public function owners()
     {   //货主
         return $this->belongsToMany(Owner::class,"owner_storage_price_model_owner","owner_storage_price_model_id","owner_id");
     }
+    public function timeUnit()
+    {   //计时单位
+        return $this->belongsTo(Unit::class,"time_unit_id");
+    }
 }

+ 32 - 1
app/Services/FeatureService.php

@@ -178,6 +178,18 @@ Class FeatureService
                         case "等于":
                             $logic = " = ";
                             break;
+                        case "大于":
+                            $logic = " > ";
+                            break;
+                        case "大于等于":
+                            $logic = " >= ";
+                            break;
+                        case "小于":
+                            $logic = " < ";
+                            break;
+                        case "小于等于":
+                            $logic = " <= ";
+                            break;
                     }
                     $str = $column.$logic."'".$describe."'";
                 }else $str = $features[$str]["type"].' '.$features[$str]["logic"].' '.$features[$str]["describe"];
@@ -230,7 +242,7 @@ Class FeatureService
                 $column = $features[$str]["type"];
                 $logic = $features[$str]["logic"];
                 $describe = $features[$str]["describe"];
-                if ($column == '商品名称' && $isMultiMatching){
+                if (($column == '商品名称' || $column == '订单数') && $isMultiMatching){
                     $packageColumn = $columnMapping["packages"] ?? "packages";
                     $packages = $matchObject[$packageColumn] ?? [];
                     $str = $this->multiMatching($packages,$logic,$describe,$columnMapping[$column] ?? '');
@@ -247,6 +259,8 @@ Class FeatureService
                     case "等于":
                         $str = $value == $describe ? 'true' : 'false';
                         break;
+                    default:
+                        $str = 'false';
                 }
                 continue;
             }
@@ -275,6 +289,7 @@ Class FeatureService
     {
         if(!$column)return 'false';
 
+        $sum = 0;
         foreach ($packages as $package){
             $value = $package[$column] ?? '';
             switch ($logic) {
@@ -287,8 +302,24 @@ Class FeatureService
                 case "等于":
                     if ($value == $describe)return 'true';
                     break;
+                default:
+                    $sum += $value;
             }
         }
+        switch ($logic) {
+            case "大于":
+                if ($sum > $describe) return 'true';
+                break;
+            case "大于等于":
+                if ($sum >= $describe) return 'true';
+                break;
+            case "小于":
+                if ($sum < $describe) return 'true';
+                break;
+            case "小于等于":
+                if ($sum <= $describe) return 'true';
+                break;
+        }
         return "false";
     }
 

+ 2 - 1
app/Services/OrderService.php

@@ -1030,6 +1030,7 @@ class OrderService
             foreach($package->commodities as &$commodity){
                 $commodity["commodity_name"] = $commodity->commodity ? $commodity->commodity->name : '';
                 $commodity["sku"] = $commodity->commodity ? $commodity->commodity->sku : '';
+                $commodity["amount"] = $commodity->amount;
                 $amount += $commodity->amount;
             }
             $commodities = array_merge($commodities,$package->commodities->toArray());
@@ -1050,7 +1051,7 @@ class OrderService
         if ($logistic_fee!==null && $logistic_fee<0)$logistic_fee = null;
 
         $object = ["commodities"=>$commodities,"logistic_name"=>($order->logistic ? $order->logistic->name : ''),"shop_name"=>($order->shop ? $order->shop->name : ''),"order_type"=>$order->order_type];
-        $mapping = ["packages"=>"commodities","商品名称"=>"commodity_name","承运商"=>"logistic_name","店铺类型"=>"shop_name","订单类型"=>"order_type"];
+        $mapping = ["packages"=>"commodities","商品名称"=>"commodity_name","承运商"=>"logistic_name","店铺类型"=>"shop_name","订单类型"=>"order_type","订单数"=>"amount"];
 
         /** @var OwnerPriceOperationService $service */
         $service = app("OwnerPriceOperationService");

+ 30 - 0
app/Services/OwnerAreaReportService.php

@@ -96,4 +96,34 @@ Class OwnerAreaReportService
         return $query->update(["status"=>"已完成"]);
     }
 
+    //根据货主生成盘点面积记录
+    public function notExistToInsert($owners)
+    {
+        if (!$owners)return;
+        $reports = OwnerAreaReport::query()
+            ->where("counting_month",">=",date("Y-m")."-01")
+            ->whereIn("owner_id",array_column($owners->toArray(),"id"))->get();
+        $sign = [];
+        foreach ($reports as $report)$sign[$report->owner_id."_".$report->owner_storage_price_model_id] = true;
+        $month = date('Y-m-d');
+        $date = date('Y-m-d H:i:s');
+        $createOwnerAreaReport = [];
+        foreach ($owners as $owner){
+            if (!$owner->ownerStoragePriceModels)continue;
+            foreach ($owner->ownerStoragePriceModels as $model){
+                $key = $owner->id."_".$model->id;
+                if (!isset($sign[$key])) $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,
+                ];
+            }
+        }
+        if ($createOwnerAreaReport){
+            DB::table("owner_area_reports")->insert($createOwnerAreaReport);
+            LogService::log(__METHOD__,"客户管理-生成盘点记录",json_encode($createOwnerAreaReport));
+        }
+    }
 }

+ 1 - 1
app/Services/OwnerPriceOperationService.php

@@ -164,7 +164,7 @@ Class OwnerPriceOperationService
         foreach ($rules as $rule){
             if (!$rule->items)continue;
             if ($rule->strategy == '特征'){
-                $bool = true;//app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
+                $bool = app("FeatureService")->matchFeature($rule->feature,$columnMapping,$matchObject);
                 if ($bool === true){
                     $money = $this->matchItem($rule->items,$columnMapping,$matchObject,$units,$owner_id,$type=='入库' ? true : false);
                     if ($money>0)return $money;

+ 2 - 1
app/Services/OwnerService.php

@@ -241,7 +241,8 @@ Class OwnerService
                 });
                 continue;
             }
-            $builder->where($column,$param);
+            if (is_array($param))$builder->whereIn($column,$param);
+            else $builder->where($column,$param);
         }
         return $builder;
     }

+ 18 - 5
app/Services/OwnerStoragePriceModelService.php

@@ -2,6 +2,7 @@
 
 namespace App\Services;
 
+use App\Order;
 use App\OwnerReport;
 use App\OwnerStoragePriceModel;
 use Illuminate\Support\Facades\DB;
@@ -47,7 +48,7 @@ Class OwnerStoragePriceModelService
         return OwnerStoragePriceModel::destroy($id);
     }
 
-    //暂时不考虑单位换算问题:后期可能存在多单位换算,此处仅视为单位为 m²
+    //暂时不考虑单位换算问题:后期可能存在多单位换算,此处仅视为单位为 m²,m³
     public function calculationAmount(OwnerStoragePriceModel $model, $area, $owner_id = null, $month = null)
     {
         if (!$model || !$area) return 0;
@@ -56,16 +57,28 @@ Class OwnerStoragePriceModelService
         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;
+                    if ($model->timeUnit->name == '月'){
+                        $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 -= $model->discount_value;
                 break;
         }
+        if ($model->timeUnit->name == '日'){
+            $days = date('t', strtotime($month."-01"));
+            $money *= $days;
+            for($i=1;$i<=$days;$i++){
+                $d = $i<10 ? "0".$i : $i;
+                $query = DB::raw("SELECT COUNT(1) c FROM orders WHERE wms_status = ? and updated_at between ? and ?");
+                $count = DB::selectOne($query,['订单完成',$month."-".$d." 00:00:00",$month."-".$d." 23:59:59"]);
+                $money -= $count ? ($count->c)*($model->discount_value) : 0;
+            }
+        }
         return $money;
     }
 }

+ 1 - 1
app/Services/StoreService.php

@@ -317,7 +317,7 @@ Class StoreService
         /** @var OwnerPriceOperationService $service */
         $service = app("OwnerPriceOperationService");
 
-        $mapping = ["packages" => "storeItems", "商品名称" => "name", "订单类型" => "stored_method"];
+        $mapping = ["packages" => "storeItems", "商品名称" => "name", "订单类型" => "stored_method", "订单数"=>"amount"];
 
         $work_fee = $service->matching($store, $mapping, $store->owner_id, "入库");
         if ($work_fee < 0) $work_fee = null;

+ 37 - 0
database/migrations/2021_01_27_174543_add_column_owner_price_model_storage.php

@@ -0,0 +1,37 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+class AddColumnOwnerPriceModelStorage extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('owner_storage_price_models', function (Blueprint $table) {
+            $table->bigInteger("time_unit_id")->comment("计时单位");
+        });
+        DB::statement("ALTER TABLE features MODIFY COLUMN type enum ('商品名称','订单类型','承运商','店铺类型','订单数') default null");
+        DB::statement("ALTER TABLE features MODIFY COLUMN logic enum ('包含','不包含','等于','大于','大于等于','小于','小于等于') default null");
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('owner_storage_price_models', function (Blueprint $table) {
+            $table->dropColumn("time_unit_id");
+        });
+        DB::statement("ALTER TABLE features MODIFY COLUMN type enum ('商品名称','订单类型','承运商','店铺类型') default null");
+        DB::statement("ALTER TABLE features MODIFY COLUMN logic enum ('包含','不包含','等于') default null");
+    }
+}

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

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddAuthorityWeightPanel extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        \App\Authority::query()->create([
+            "name"       => "控制台-称重统计",
+            "alias_name" => "控制台-称重统计",
+        ]);
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        \App\Authority::query()->where("name","控制台-称重统计")->delete();
+    }
+}

+ 30 - 0
resources/sass/animation.css

@@ -0,0 +1,30 @@
+.animation-translation{
+    animation:move 500ms infinite;
+    -moz-animation:move 500ms infinite; /* Firefox */
+    -webkit-animation:move 500ms infinite; /* Safari and Chrome */
+    -o-animation:move 500ms infinite;/* Opera */
+}
+
+@keyframes move
+{
+    from {top:0;}
+    to {top:-50px;}
+}
+
+@-moz-keyframes move /* Firefox */
+{
+    from {top:0;}
+    to {top:-50px;}
+}
+
+@-webkit-keyframes move /* Safari and Chrome */
+{
+    from {top:0;}
+    to {top:-50px;}
+}
+
+@-o-keyframes move /* Opera */
+{
+    from {top:0;}
+    to {top:-50px;}
+}

+ 4 - 0
resources/views/control/panel.blade.php

@@ -347,6 +347,7 @@
                 @endcan
             </div>
             <div class="row my-3">
+                @can("控制台-称重统计")
                 <div class="col-6">
                     <div class="card">
                         <div class="card-header">
@@ -366,6 +367,7 @@
                         </div>
                     </div>
                 </div>
+                @endcan
             </div>
         </div>
     </div>
@@ -546,7 +548,9 @@
 
                 this.laborReportsUserGroupsCountChart = echarts.init(document.getElementById('laborReportsUserGroupsCount'));
                 this.initLaborReportsUserGroupsCountChart();
+                @endcan
 
+                @can("控制台-称重统计")
                 this.cardPool.weight = echarts.init(document.getElementById("weight"));
                 this.loadWeightInfo();
                 @endcan

+ 25 - 0
resources/views/customer/_selectedOwner.blade.php

@@ -0,0 +1,25 @@
+<div class="modal fade" tabindex="-1" role="dialog" id="selectedOwner">
+    <div class="modal-dialog modal-dialog-centered">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal">&times;</button>
+            </div>
+            <div class="modal-body">
+                <div class="row">
+                    <label class="col-6">
+                        <select class="selectpicker border border-2 border-dark rounded" id="owners" multiple data-live-search="true" title="项目(多选)">
+                            <option v-for="owner in owners" :value="owner.name">@{{ owner.value }}</option>
+                        </select>
+                    </label>
+                    <div class="col-6">
+                        <p v-for="error in errors" class="text-danger">@{{ error }}</p>
+                    </div>
+                </div>
+
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-success pull-right" @click="createReport()">生成</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 30 - 8
resources/views/customer/project/area.blade.php

@@ -1,13 +1,16 @@
 @extends('layouts.app')
 @section('title')
-    称重管理-项目报表
+    客户管理-面积报表
 @endsection
 @section('content')
     @component('customer.project.menu')@endcomponent
     <div class="container-fluid" id="container">
+
+        @include("customer._selectedOwner")
+
         <div id="form_div"></div>
         <div>
-            <button type="button" class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget" :class="[checkData.length>0?'btn-dark text-light':'']"
+            <button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle tooltipTarget" :class="[checkData.length>0?'btn-dark text-light':'']"
                     data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">
                 导出Excel
             </button>
@@ -15,6 +18,7 @@
                 <a class="dropdown-item" @click="areaExport(false)" href="javascript:">导出勾选内容</a>
                 <a class="dropdown-item" @click="areaExport(true)" href="javascript:">导出所有页</a>
             </div>
+            <button class="ml-1 btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#selectedOwner">新 增</button>
         </div>
         <div>
             <label for="all" id="cloneCheckAll" class="d-none">
@@ -46,7 +50,7 @@
                     <td>@{{ area.ownerName }}</td>
                     <td>@{{ area.countingMonth }}</td>
                     <td>@{{ area.updatedAt }}</td>
-                    <td>@{{ area.ownerStoragePriceModelUsingType }}</td>
+                    <td>@{{ area.ownerStoragePriceModel }}</td>
                     <td>
                         <label><input :readonly="editIndex==i ? false : true" @change="thisArea.area_on_tray = $event.target.value"
                                       type="number" min="0" class="form-control form-control-sm" :value="area.areaOnTray"></label>
@@ -89,7 +93,7 @@
                         accountingArea : "{{$area->accounting_area}}",
                         status : "{{$area->status}}",
                         updatedAt : "{{$area->updated_at}}",
-                        ownerStoragePriceModelUsingType:"{{ $area->owner ? implode(",",array_unique(array_column(($area->owner->ownerStoragePriceModels)->toArray(),"using_type"))) : '' }}",
+                        ownerStoragePriceModel:"{{ $area->ownerStoragePriceModel ? $area->ownerStoragePriceModel->using_type : '' }}",
                     },
                     @endforeach
                 ],
@@ -118,6 +122,7 @@
                 checkData : [],
                 editIndex : "-1",
                 sum : Number("{{ $areas->total() }}"),
+                errors:[],
             },
             watch:{
                 checkData:{
@@ -162,11 +167,11 @@
                     {name:'ownerName',value: '子项目'},
                     {name:'countingMonth',value: '结算月'},
                     {name:'createdAt',value: '录入时间'},
-                    {name:'ownerStoragePriceModelUsingType',value: '用仓类型'},
+                    {name:'ownerStoragePriceModel',value: '用仓类型'},
                     {name:'areaOnTray',value: '货物整托', neglect: true},
                     {name:'areaOnHalfTray',value: '货物半托', neglect: true},
-                    {name:'areaOnFlat',value: '平面区面积', neglect: true},
-                    {name:'accountingArea',value: '结算面积', neglect: true},
+                    {name:'areaOnFlat',value: '平面区(面积/体积)', neglect: true},
+                    {name:'accountingArea',value: '结算(面积/体积)', neglect: true},
                 ];
                 let _this=this;
                 setTimeout(function () {
@@ -237,7 +242,24 @@
                             window.tempTip.show("网络错误:"+err);
                         })
                     });
-                }
+                },
+                createReport(){
+                    let dom = $("#owners");
+                    let val = dom.selectpicker('val');
+                    window.tempTip.setDuration(3000);
+                    window.tempTip.setIndex(1099);
+                    if (val.length<1){
+                        window.tempTip.show("未选择");
+                        return;
+                    }
+                    let url="{{url('customer/project/createAreaReport')}}";
+                    let params = {val:val};
+                    window.tempTip.postBasicRequest(url,params,res=>{
+                        this.areas = res.concat(this.areas);
+                        dom.selectpicker('val',[]);
+                        return "已生成报表";
+                    },true)
+                },
             },
         });
     </script>

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

@@ -1,6 +1,6 @@
 @extends('layouts.app')
 @section('title')客户管理-项目录入@endsection
-
+@section("head")<link href="{{ mix('css/animation.css') }}" rel="stylesheet">@endsection
 @section('content')
     @component('customer.project.menu')
         @if($owner)
@@ -67,6 +67,7 @@
                     </div>
                 </div>
             </div>
+            <hr class="mt-2">
             <div class="row mt-3" v-if="base != 'three' || isLoad">
                 <div class="pull-right offset-7">
                     <button type="button" class="btn btn-info ml-1 text-white" v-show="base !== 'one'" @click="back()">上一步</button>
@@ -135,6 +136,7 @@
                         discount_type : "无减免",
                         discount_value : "",
                         unit_id : "",
+                        time_unit_id : "",
                     },
                     operation:{
                         operation_type:"入库",
@@ -238,28 +240,36 @@
                     if (type === this.type)return;//相同终止是为了减少重复加载动作
                     this._clearRefuse();//清除垃圾数据
                     let parent = $("#parent");
+                    let dom = "";
                     switch (type) {
                         case "storage":
                             this._loadStorage();
-                            parent.prepend($("#storage-card"));
+                            dom = $("#storage-card");
                             break;
                         case "operation":
                             this._loadOperation();
-                            parent.prepend($("#operation-card"));
+                            dom = $("#operation-card");
                             break;
                         case "express":
                             this._loadExpress();
-                            parent.prepend($("#express-card"));
+                            dom = $("#express-card");
                             break;
                         case "logistic":
                             this._loadLogistic();
-                            parent.prepend($("#logistic-card"));
+                            dom = $("#logistic-card");
                             break;
                         case "directLogistic":
                             this._loadDirectLogistic();
-                            parent.prepend($("#directLogistic-card"));
+                            dom = $("#directLogistic-card");
                             break;
                     }
+                    dom.addClass("animation-translation");
+                    dom.fadeOut(500);
+                    setTimeout(function(){
+                        dom.removeClass("animation-translation");
+                        parent.prepend(dom);
+                        dom.fadeIn();
+                    },400);
                     this.type = type;
                 },
                 //下一步
@@ -543,6 +553,8 @@
                     if (!this.model.storage.using_type)error["using_type"] = ["未选择用仓类型"];
                     if (!this.model.storage.price)error["price"] = ["未输入单价"];
                     if (!this.model.storage.discount_type)error["discount_type"] = ["未选择减免类型"];
+                    if (!this.model.storage.unit_id)error["unit_id"] = ["未选择单位"];
+                    if (!this.model.storage.time_unit_id)error["time_unit_id"] = ["未选择计时单位"];
                     if (JSON.stringify(error) !== "{}"){
                         this.errors = error;
                         this.$forceUpdate();
@@ -570,6 +582,7 @@
                             discount_type : "无减免",
                             discount_value : "",
                             unit_id : "",
+                            time_unit_id : "",
                         };
                         this.errors = [];
                     });
@@ -615,6 +628,7 @@
                         for (let i=0;i<res.items.length;i++){
                             res.items[i].features = this.model.operation.items[sign]['features'];
                             res.items[i].featureFormat = this.model.operation.items[sign]['featureFormat'];
+                            res.items[i].type = this.model.operation.items[sign]['type'];
                             sign++;
                         }
                         if (params.id) this.selectedModel.operation[params.index] = res;

+ 2 - 2
resources/views/customer/project/menu.blade.php

@@ -6,11 +6,11 @@
             <ul class="nav nav-pills">
                 @can('客户管理-项目-报表')
                 <li class="nav-item">
-                    <a target="customer/project/report" class="nav-link" href="{{url('customer/project/report')}}" :class="{active:isActive('report',3)}">报表</a>
+                    <a target="customer/project/report" class="nav-link" href="{{url('customer/project/report')}}" :class="{active:isActive('report',3)}">概览</a>
                 </li> @endcan
                 @can('客户管理-项目-面积')
                     <li class="nav-item">
-                        <a target="customer/project/area" class="nav-link" href="{{url('customer/project/area')}}" :class="{active:isActive('area',3)}">面积</a>
+                        <a target="customer/project/area" class="nav-link" href="{{url('customer/project/area')}}" :class="{active:isActive('area',3)}">用仓报表</a>
                     </li> @endcan
                 @can('客户管理-项目-查询')
                 <li class="nav-item">

+ 2 - 2
resources/views/customer/project/part/_directLogistic.blade.php

@@ -15,8 +15,8 @@
     </span>
 </div>
 <div class="row mt-3">
-    <label class="col-3 cursor-pointer" @click="show('directLogistic-item-card')">详情&nbsp;
-        <span class="fa" :class="upList['express-item'] ? 'fa-angle-double-right' : 'fa-angle-double-down'"></span></label>
+    <label class="col-3 cursor-pointer" @click="show('directLogistic-item-card')"><span @click="show('directLogistic-item-card')">详情&nbsp;
+        <span class="fa" :class="upList['express-item'] ? 'fa-angle-double-right' : 'fa-angle-double-down'"></span></span></label>
     <div class="col-9">
         <div class="w-100 form-inline">
             <input id="directLogisticFile" type="file" class="d-none" accept=".csv, .xlsx, .xls" @change="importDirectLogistic($event)"/>

+ 2 - 2
resources/views/customer/project/part/_express.blade.php

@@ -21,8 +21,8 @@
            v-model="model.express.additional_weight" :class="errors.additional_weight ? 'is-invalid' : ''"></label>
 </div>
 <div class="row mt-3">
-    <label class="col-3 cursor-pointer" @click="show('express-item')">详情&nbsp;
-        <span class="fa" :class="upList['express-item'] ? 'fa-angle-double-right' : 'fa-angle-double-down'"></span></label>
+    <label class="col-3 cursor-pointer"><span @click="show('express-item')">详情&nbsp;
+        <span class="fa" :class="upList['express-item'] ? 'fa-angle-double-right' : 'fa-angle-double-down'"></span></span></label>
     <div class="col-9">
         <div class="w-100 form-inline">
             <input id="expressFile" type="file" class="d-none" accept=".csv, .xlsx, .xls" @change="importExpress($event)"/>

+ 28 - 16
resources/views/customer/project/part/_storage.blade.php

@@ -34,12 +34,34 @@
     </span>
 </div>
 <div class="row mt-3">
-    <label for="price" class="col-2 text-info">单价</label>
-    <input id="price" type="number" min="0" step="0.001" class="col-6 form-control"
-           :class="errors.price ? 'is-invalid' : ''" v-model="model.storage.price">
-    <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.price">
-        <strong>@{{ errors.price[0] }}</strong>
-    </span>
+    <div class="col-4 row">
+        <label for="price" class="col-4 text-info">单价</label>
+        <input id="price" type="number" min="0" step="0.001" class="offset-3 col-5 form-control"
+               :class="errors.price ? 'is-invalid' : ''" v-model="model.storage.price">
+        <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.price">
+            <strong>@{{ errors.price[0] }}</strong>
+        </span>
+    </div>
+    <div class="col-3 row m-0">
+        <label for="unit_id" class="col-5 offset-1 text-info">单位</label>
+        <select id="unit_id" class="col-6 form-control"
+                :class="errors.unit_id ? 'is-invalid' : ''" v-model="model.storage.unit_id">
+            <option v-for="unit in pool.units" :value="unit.id">@{{ unit.name }}</option>
+        </select>
+        <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.unit_id">
+            <strong>@{{ errors.unit_id[0] }}</strong>
+        </span>
+    </div>
+    <div class="col-3 row m-0">
+        <label for="time_unit_id" class="col-5 offset-1 text-info">计时</label>
+        <select id="time_unit_id" class="col-6 form-control"
+                :class="errors.time_unit_id ? 'is-invalid' : ''" v-model="model.storage.time_unit_id">
+            <option v-for="unit in pool.units" :value="unit.id" v-if="unit.name == '日' || unit.name == '月'">@{{ unit.name }}</option>
+        </select>
+        <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.time_unit_id">
+            <strong>@{{ errors.time_unit_id[0] }}</strong>
+        </span>
+    </div>
 </div>
 <div class="row mt-3">
     <label for="discount_type" class="col-2 text-info">减免类型</label>
@@ -58,14 +80,4 @@
     <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.discount_value">
         <strong>@{{ errors.discount_value[0] }}</strong>
     </span>
-</div>
-<div class="row mt-3">
-    <label for="unit_id" class="col-2 text-info">单位</label>
-    <select id="unit_id" class="col-3 form-control"
-            :class="errors.unit_id ? 'is-invalid' : ''" v-model="model.storage.unit_id">
-        <option v-for="unit in pool.units" :value="unit.id">@{{ unit.name }}</option>
-    </select>
-    <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.unit_id">
-        <strong>@{{ errors.unit_id[0] }}</strong>
-    </span>
 </div>

+ 3 - 1
resources/views/customer/project/part/_three.blade.php

@@ -14,6 +14,7 @@
                         <th>起租面积</th>
                         <th>单价</th>
                         <th>单位</th>
+                        <th>计时单位</th>
                         <th>减免类型</th>
                         <th>减免值</th>
                         <th></th>
@@ -25,6 +26,7 @@
                         <td>@{{ item.minimum_area }}</td>
                         <td>@{{ item.price }}</td>
                         <td>@{{ poolMapping.units ? poolMapping.units[item.unit_id] : '' }}</td>
+                        <td>@{{ poolMapping.units ? poolMapping.units[item.time_unit_id] : '' }}</td>
                         <td>@{{ item.discount_type }}</td>
                         <td>@{{ item.discount_value }}</td>
                         <td class="cursor-pointer" @click.stop="delStorage(item,i)"><span class="font-weight-bold text-danger">&times;</span></td>
@@ -109,7 +111,7 @@
                                     <div class="row">
                                         <div class="col-10">
                                             <label>@{{ item.strategy }}</label>:
-                                            <b>@{{ item.amount }}</b>&nbsp;@{{ poolMapping.units ? poolMapping.units[item.unit_id] : '' }} / <b>@{{ item.unit_price }}</b>元
+                                            <span v-if="item.amount > 0"><b>@{{ item.amount }}</b>&nbsp;@{{ poolMapping.units ? poolMapping.units[item.unit_id] : '' }} /</span><b>&nbsp;@{{ item.unit_price }}</b>元
                                         </div>
                                         <div class="col-1">
                                             <span class="cursor-pointer text-danger font-weight-bold"

+ 23 - 0
resources/views/customer/project/report.blade.php

@@ -5,6 +5,9 @@
 @section('content')
     @component('customer.project.menu')@endcomponent
     <div class="container-fluid card d-none" id="container">
+
+        @include("customer._selectedOwner")
+
         <div id="form_div"></div>
         <div>
             <button type="button" class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget" :class="[checkData.length>0?'btn-dark text-light':'']"
@@ -15,6 +18,7 @@
                 <a class="dropdown-item" @click="reportExport(false)" href="javascript:">导出勾选内容</a>
                 <a class="dropdown-item" @click="reportExport(true)" href="javascript:">导出所有页</a>
             </div>
+            <button class="ml-1 btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#selectedOwner">新 增</button>
         </div>
         <div>
             <label for="all" id="cloneCheckAll" class="d-none">
@@ -104,6 +108,7 @@
                 ],
                 checkData : [],
                 sum : Number("{{ $reports->total() }}"),
+                errors:[],
             },
             mounted(){
                 $('#container').removeClass('d-none');
@@ -188,6 +193,24 @@
                         this.checkData = [];
                     }
                 },
+                createReport(){
+                    let dom = $("#owners");
+                    let val = dom.selectpicker('val');
+                    window.tempTip.setDuration(3000);
+                    window.tempTip.setIndex(1099);
+                    if (val.length<1){
+                        window.tempTip.show("未选择");
+                        return;
+                    }
+                    let url="{{url('customer/project/createReport')}}";
+                    let params = {val:val};
+                    window.tempTip.postBasicRequest(url,params,res=>{
+                        this.errors = res.errors;
+                        this.reports = res.data.concat(this.reports);
+                        dom.selectpicker('val',[]);
+                        return "已生成报表";
+                    },true)
+                },
             }
         });
     </script>

+ 29 - 16
resources/views/maintenance/priceModel/storage/create.blade.php

@@ -60,12 +60,34 @@
                 </span>
             </div>
             <div class="row mt-3">
-                <label for="price" class="col-2 text-info">单价</label>
-                <input id="price" type="number" min="0" step="0.001" name="price" class="col-6 form-control"
-                       :class="errors.price ? 'is-invalid' : ''" v-model="model.price">
-                <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.price">
-                    <strong>@{{ errors.price[0] }}</strong>
-                </span>
+                <div class="col-5 row">
+                    <label for="price" class="col-4 text-info">单价</label>
+                    <input id="price" type="number" min="0" step="0.001" name="price" class="col-7 offset-1 form-control" required
+                           :class="errors.price ? 'is-invalid' : ''" v-model="model.price">
+                    <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.price">
+                        <strong>@{{ errors.price[0] }}</strong>
+                    </span>
+                </div>
+                <div class="col-3 row">
+                    <label for="unit_id" class="col-4 text-info">单位</label>
+                    <select id="unit_id" name="unit_id" class="col-8 form-control" required
+                            :class="errors.unit_id ? 'is-invalid' : ''" v-model="model.unit_id">
+                        <option v-for="unit in units" :value="unit.id" v-if="unit.name == 'm²' || unit.name == 'm³'">@{{ unit.name }}</option>
+                    </select>
+                    <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.unit_id">
+                        <strong>@{{ errors.unit_id[0] }}</strong>
+                    </span>
+                </div>
+                <div class="col-3 row">
+                    <label for="time_unit_id" class="col-4 text-info">计时</label>
+                    <select id="time_unit_id" name="time_unit_id" class="col-8 form-control" required
+                            :class="errors.time_unit_id ? 'is-invalid' : ''" v-model="model.time_unit_id">
+                        <option v-for="unit in units" :value="unit.id" v-if="unit.name == '日' || unit.name == '月'">@{{ unit.name }}</option>
+                    </select>
+                    <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.unit_id">
+                        <strong>@{{ errors.unit_id[0] }}</strong>
+                    </span>
+                </div>
             </div>
             <div class="row mt-3">
                 <label for="discount_type" class="col-2 text-info">减免类型</label>
@@ -85,16 +107,6 @@
                     <strong>@{{ errors.discount_value[0] }}</strong>
                 </span>
             </div>
-            <div class="row mt-3">
-                <label for="unit_id" class="col-2 text-info">单位</label>
-                <select id="unit_id" name="unit_id" class="col-3 form-control"
-                        :class="errors.unit_id ? 'is-invalid' : ''" v-model="model.unit_id">
-                    <option v-for="unit in units" :value="unit.id">@{{ unit.name }}</option>
-                </select>
-                <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.unit_id">
-                    <strong>@{{ errors.unit_id[0] }}</strong>
-                </span>
-            </div>
             <div class="row mt-3 offset-1">
                 <button type="submit" class="btn btn-success col-7">提交</button>
             </div>
@@ -117,6 +129,7 @@
                     'price' : "{{old('price') ?? (isset($model) ? $model->price : '')}}",
                     'discount_type' : "{{old('discount_type') ?? (isset($model) ? $model->discount_type : '')}}",
                     'unit_id' : "{{old('unit_id') ?? (isset($model) ? $model->unit_id : '')}}",
+                    'time_unit_id' : "{{old('time_unit_id') ?? (isset($model) ? $model->time_unit_id : '')}}",
                     owner_id:{!! old('owner_id') ? json_encode(old('owner_id')) : (isset($model) ? json_encode(array_column($model->owners->toArray(),"id")) : '[]') !!},
                 },
                 counting_type : ['包仓','灵活用仓','统单价'],

+ 2 - 1
resources/views/maintenance/priceModel/storage/index.blade.php

@@ -33,7 +33,7 @@
                 <td>
                     <small v-for="owner in model.owners">@{{ owner.name }}<br></small>
                 </td>
-                <td>@{{ model.price }}/@{{ model.unit_name }}</td>
+                <td>@{{ model.price }}/@{{ model.unit_name }}/@{{ model.time_unit_name }}</td>
                 <td>@{{ model.discount_type }}</td>
                 <td>@{{ model.discount_value }}</td>
                 <td>@{{ model.created_at }}</td>
@@ -64,6 +64,7 @@
                         discount_type : "{{$model->discount_type}}",
                         discount_value : "{{$model->discount_value}}",
                         unit_name : "{{$model->unit ? $model->unit->name : ''}}",
+                        time_unit_name : "{{$model->timeUnit ? $model->timeUnit->name : ''}}",
                         created_at : "{{$model->created_at}}",
                         owners:{!! $model->owners !!},
                     },

+ 1 - 1
resources/views/waybill/index.blade.php

@@ -54,7 +54,7 @@
                 <tr>
                     <th class="table-header-layer-1" colspan="4"></th>
                     <th class="table-header-layer-1" colspan="11"><span class="fa fa-file-text-o"></span> 运单信息</th>
-                    <th class="table-header-layer-1" colspan="13"><span class="fa fa-truck"></span> 运输信息</th>
+                    <th class="table-header-layer-1" colspan="16"><span class="fa fa-truck"></span> 运输信息</th>
                     <th class="table-header-layer-1" colspan="5"><span class="fa fa-rmb"></span> 费用信息
                     @can('运输管理-删除')
                         <th class="table-header-layer-1" colspan="1"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>

+ 4 - 0
routes/web.php

@@ -650,6 +650,10 @@ Route::group(['prefix'=>'customer'],function(){
 
         //获取现有计费模型
         Route::post('getPriceModel','PriceModelController@getPriceModel');
+
+        //手动生成账单
+        Route::post("createReport","CustomerController@createReport");
+        Route::post("createAreaReport","CustomerController@createAreaReport");
     });
     Route::group(['prefix'=>'finance'],function(){
         Route::group(['prefix'=>'instantBill'],function(){

+ 14 - 0
tests/Services/OwnerStoragePriceModelService/OwnerStoragePriceModelServiceTest.php

@@ -7,6 +7,7 @@ use App\Owner;
 use App\OwnerReport;
 use App\OwnerStoragePriceModel;
 use App\Services\OwnerStoragePriceModelService;
+use App\Unit;
 use Tests\TestCase;
 
 class OwnerStoragePriceModelServiceTest extends  TestCase
@@ -20,6 +21,16 @@ class OwnerStoragePriceModelServiceTest extends  TestCase
         parent::setUp();
         $this->service = app(OwnerStoragePriceModelService::class);
 
+        $unit = Unit::query()->where("name","月")->first();
+        $units = [];
+        if (!$unit){
+            $unit = Unit::query()->create([
+                "name" => "月",
+                "code" => "月"
+            ]);
+            $units[] = $unit;
+        }
+        $this->data["units"] = $units;
         $this->data["models"] = [
             factory(OwnerStoragePriceModel::class)->create([
                 "minimum_area" => 600,     //最低起租面积
@@ -27,6 +38,7 @@ class OwnerStoragePriceModelServiceTest extends  TestCase
                 "discount_type" => "按单减免",    //减免类型
                 "discount_value" => 0.1,   //减免值
                 "unit_id" => 1,          //单位ID
+                "time_unit_id" => $unit->id,          //单位ID
             ])->toArray(),
             factory(OwnerStoragePriceModel::class)->create([
                 "minimum_area" => 600,     //最低起租面积
@@ -34,6 +46,7 @@ class OwnerStoragePriceModelServiceTest extends  TestCase
                 "discount_type" => "固定减免",    //减免类型
                 "discount_value" => 3.6,   //减免值
                 "unit_id" => 1,          //单位ID
+                "time_unit_id" => $unit->id,          //计时单位ID
             ])->toArray(),
         ];
         $this->data["owners"] = [
@@ -67,6 +80,7 @@ class OwnerStoragePriceModelServiceTest extends  TestCase
         OwnerStoragePriceModel::destroy(array_column($this->data["models"],"id"));
         Owner::destroy(array_column($this->data["owners"],"id"));
         OwnerReport::destroy(array_column($this->data["reports"],"id"));
+        Unit::destroy(array_column($this->data["units"],"id"));
         parent::tearDown();
     }
 }

+ 1 - 0
webpack.mix.js

@@ -28,5 +28,6 @@ mix.js('resources/js/utilities/barcode.js','public/js/utilities/barcode.js');
 mix.copy('resources/sound/','public/sound');
 mix.js('resources/js/elementUi.js','public/js/element-ui.js')
     .sass('resources/sass/elementUi.scss', 'public/css/element-ui.css');
+mix.copy("resources/sass/animation.css",'public/css/animation.css');
 
 mix.version();