Переглянути джерело

客户管理-审核与恢复

Zhouzhendong 5 роки тому
батько
коміт
a85056b36e
40 змінених файлів з 1292 додано та 432 видалено
  1. 1 1
      app/Console/Commands/CreateOwnerBillReport.php
  2. 2 2
      app/Console/Commands/CreateOwnerReport.php
  3. 14 14
      app/Http/Controllers/CustomerController.php
  4. 404 274
      app/Http/Controllers/PriceModelController.php
  5. 4 6
      app/Http/Controllers/TestController.php
  6. 4 1
      app/Imports/ExpressImport.php
  7. 6 0
      app/Imports/OwnerPriceDirectLogisticDetailImport.php
  8. 3 0
      app/Imports/OwnerPriceLogisticDetailImport.php
  9. 75 9
      app/Owner.php
  10. 4 1
      app/OwnerPriceDirectLogistic.php
  11. 4 0
      app/OwnerPriceDirectLogisticCar.php
  12. 2 1
      app/OwnerPriceExpress.php
  13. 2 0
      app/OwnerPriceLogistic.php
  14. 4 0
      app/OwnerPriceLogisticDetail.php
  15. 3 2
      app/OwnerPriceOperation.php
  16. 4 0
      app/OwnerPriceOperationItem.php
  17. 2 0
      app/OwnerStoragePriceModel.php
  18. 1 1
      app/Services/OwnerAreaReportService.php
  19. 88 2
      app/Services/OwnerPriceDirectLogisticService.php
  20. 95 3
      app/Services/OwnerPriceExpressService.php
  21. 97 6
      app/Services/OwnerPriceLogisticService.php
  22. 98 3
      app/Services/OwnerPriceOperationService.php
  23. 25 4
      app/Services/OwnerService.php
  24. 60 2
      app/Services/OwnerStoragePriceModelService.php
  25. 35 1
      app/Services/common/QueryService.php
  26. 59 0
      database/migrations/2021_03_09_172210_change_price_model_table.php
  27. 1 1
      resources/views/customer/index.blade.php
  28. 3 3
      resources/views/customer/menu.blade.php
  29. 4 4
      resources/views/customer/project/area.blade.php
  30. 128 63
      resources/views/customer/project/create.blade.php
  31. 3 3
      resources/views/customer/project/index.blade.php
  32. 3 3
      resources/views/customer/project/menu.blade.php
  33. 45 15
      resources/views/customer/project/part/_three.blade.php
  34. 1 1
      resources/views/finance/billConfirmation.blade.php
  35. 1 1
      resources/views/finance/instantBill.blade.php
  36. 2 2
      resources/views/layouts/menu.blade.php
  37. 1 1
      resources/views/maintenance/priceModel/operation/create.blade.php
  38. 1 1
      resources/views/maintenance/priceModel/operation/index.blade.php
  39. 1 1
      resources/views/personnel/menu.blade.php
  40. 2 0
      routes/web.php

+ 1 - 1
app/Console/Commands/CreateOwnerBillReport.php

@@ -78,7 +78,7 @@ class CreateOwnerBillReport extends Command
                     "created_at"        => $date,
                 ];
             }
-            LogService::log(__METHOD__,"客户管理-生成确认账单",json_encode($createOwnerBillReport));
+            LogService::log(__METHOD__,"项目管理-生成确认账单",json_encode($createOwnerBillReport));
             DB::table("owner_bill_reports")->insert($createOwnerBillReport);
         }
     }

+ 2 - 2
app/Console/Commands/CreateOwnerReport.php

@@ -118,11 +118,11 @@ class CreateOwnerReport extends Command
         //执行生成或修改
         if (count($updateReports)>1){
             app(BatchUpdateService::class)->batchUpdate('owner_reports', $updateReports);
-            app('LogService')->log(__METHOD__,"客户管理-修改原有货主报表",json_encode($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));
+            app('LogService')->log(__METHOD__,"项目管理-生成货主报表",json_encode($createReports));
         }
     }
 }

+ 14 - 14
app/Http/Controllers/CustomerController.php

@@ -33,7 +33,7 @@ class CustomerController extends Controller
      */
     public function projectReport(Request $request)
     {
-        if(!Gate::allows('客户管理-项目-报表')){ return view('customer.index');  }
+        if(!Gate::allows('项目管理-项目-报表')){ return view('customer.index');  }
         $withs = ["ownerBillReport","owner"=>function($query){
             /** @var Builder $query */
             $query->select("id","warehouse_id","name","deleted_at","created_at","customer_id","user_owner_group_id")
@@ -49,7 +49,7 @@ class CustomerController extends Controller
 
     public function projectReportExport(Request $request)
     {
-        if(!Gate::allows('客户管理-项目-报表')){ return redirect('denied');  }
+        if(!Gate::allows('项目管理-项目-报表')){ return redirect('denied');  }
         /** @var OwnerReportService $service */
         $service = app('OwnerReportService');
         $withs = ["ownerBillReport","owner"=>function($query){
@@ -93,7 +93,7 @@ class CustomerController extends Controller
 
     public function projectIndex()
     {
-        if(!Gate::allows('客户管理-项目-查询')){ return redirect('denied');  }
+        if(!Gate::allows('项目管理-项目-查询')){ return redirect('denied');  }
         /** @var OwnerService $service */
         $service = app('OwnerService');
         $owners = $service->paginate(request()->input(),['customer',"userOwnerGroup","userWorkGroup",
@@ -111,7 +111,7 @@ class CustomerController extends Controller
 
     public function projectIndexExport(Request $request)
     {
-        if(!Gate::allows('客户管理-项目-查询')){ return redirect('denied');  }
+        if(!Gate::allows('项目管理-项目-查询')){ return redirect('denied');  }
         /** @var OwnerService $service */
         $service = app('OwnerService');
         $withs = ['customer',"userOwnerGroup","contracts","taxRate","ownerStoragePriceModels","ownerAreaReport"=>function($query){
@@ -158,7 +158,7 @@ class CustomerController extends Controller
 
     public function projectCreate()
     {
-        if(!Gate::allows('客户管理-项目-录入')){ return redirect('denied');  }
+        if(!Gate::allows('项目管理-项目-录入')){ return redirect('denied');  }
         $customers = app('CustomerService')->getSelection();
         $ownerGroups = app('UserOwnerGroupService')->getSelection();
         $userGroups = app('UserWorkgroupService')->getSelection(["id","name","warehouse_id"]);
@@ -169,7 +169,7 @@ class CustomerController extends Controller
 
     public function projectUpdate()
     {
-        $this->gate("客户管理-项目-录入");
+        $this->gate("项目管理-项目-录入");
         if (!request("id"))$this->error("项目不存在,无法补充详细信息");
         $errors = $this->validator(request()->input())->errors();
         if (count($errors)>0)$this->success(["errors"=>$errors]);
@@ -205,7 +205,7 @@ class CustomerController extends Controller
 
     public function projectEdit($id)
     {
-        if(!Gate::allows('客户管理-项目-编辑')){ return redirect('denied');  }
+        if(!Gate::allows('项目管理-项目-编辑')){ return redirect('denied');  }
         /** @var Owner $owner */
         $owner = app('OwnerService')->find($id);
         $owner->loadCount(["ownerStoragePriceModels","ownerPriceOperations","ownerPriceExpresses","ownerPriceLogistics","ownerPriceDirectLogistics"]);
@@ -226,7 +226,7 @@ class CustomerController extends Controller
 
     public function projectArea(Request $request)
     {
-        if(!Gate::allows('客户管理-项目-面积')){ return redirect('denied');  }
+        if(!Gate::allows('项目管理-项目-面积')){ return redirect('denied');  }
         $areas = app('OwnerAreaReportService')->paginate($request->input(),["owner"=>function($query){$query->with(["customer","ownerStoragePriceModels.unit"]);},"userOwnerGroup"]);
         $ownerGroups = app('UserOwnerGroupService')->getSelection();
         $customers = app('CustomerService')->getSelection();
@@ -237,7 +237,7 @@ class CustomerController extends Controller
 
     public function updateArea()
     {
-        $this->gate("客户管理-项目-面积-编辑");
+        $this->gate("项目管理-项目-面积-编辑");
         if (!request("id")) $this->error("非法参数");
 
         $total = ((int)request("areaOnTray")*2.5) +
@@ -256,7 +256,7 @@ class CustomerController extends Controller
     //面积报表审核
     public function areaReportAudit()
     {
-        $this->gate("客户管理-项目-用仓盘点-审核");
+        $this->gate("项目管理-项目-用仓盘点-审核");
         $id = request("id");
         if(!$id)$this->error("非法参数");
         $area = OwnerAreaReport::query()->find($id);
@@ -268,7 +268,7 @@ class CustomerController extends Controller
 
     public function projectAreaExport(Request $request)
     {
-        if(!Gate::allows('客户管理-项目-面积')){ return redirect('denied');  }
+        if(!Gate::allows('项目管理-项目-面积')){ return redirect('denied');  }
         $params = $request->input();
         if ($request->checkAllSign)unset($params['checkAllSign']);
         else $params = ["id"=>$request->data];
@@ -399,7 +399,7 @@ class CustomerController extends Controller
         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.'- (IFNULL(work_fee,0)+IFNULL(storage_fee,0)+IFNULL(logistic_fee,0))'),"updated_at"=>$date]);
-        LogService::log(__METHOD__,"客户管理-修改账单报表",json_encode($request->input()));
+        LogService::log(__METHOD__,"项目管理-修改账单报表",json_encode($request->input()));
         return ["success"=>true,"data"=>$date];
     }
 
@@ -418,9 +418,9 @@ class CustomerController extends Controller
         if (!$area || $area->status!='编辑中')$this->error("对应面积报表状态异常");
         $bill->update(["confirmed"=>"是"]);
 
-        LogService::log(__METHOD__,"客户管理-确认账单",json_encode(request()->input()));
+        LogService::log(__METHOD__,"项目管理-确认账单",json_encode(request()->input()));
         app('OwnerAreaReportService')->lockArea(null, $bill->owner_id, $bill->counting_month);
-        LogService::log(__METHOD__,"客户管理-锁定账单的所有面积",json_encode($bill,JSON_UNESCAPED_UNICODE));
+        LogService::log(__METHOD__,"项目管理-锁定账单的所有面积",json_encode($bill,JSON_UNESCAPED_UNICODE));
         $this->success();
     }
 

Різницю між файлами не показано, бо вона завелика
+ 404 - 274
app/Http/Controllers/PriceModelController.php


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

@@ -54,6 +54,7 @@ use App\OrderTracking;
 use App\Owner;
 use App\OwnerFeeDetail;
 use App\OwnerFeeDetailLogistic;
+use App\OwnerPriceExpress;
 use App\OwnerPriceOperation;
 use App\OwnerPriceOperationItem;
 use App\OwnerReport;
@@ -157,12 +158,9 @@ class TestController extends Controller
         dd(Region::query()->where("id",">=",404)->where("id","<=",432)->delete());
     }
     public function tt1(){
-        $logistics = [1,2,3];
-        $logisticSql = "(''";
-        foreach ($logistics as $logistic)$logisticSql.=",".$logistic;
-        $logisticSql .= ")";
-        $sql = "SELECT COUNT(1) c FROM orders WHERE logistic_id IN {$logisticSql} AND wms_status = ? AND wms_edittime BETWEEN ? AND ?";
-        dd($sql);
+        $a = new Owner();
+        $a->load("ownerPriceOperations");
+        dd($a);
     }
     public function zzd(){
         ini_set('max_execution_time',2500);

+ 4 - 1
app/Imports/ExpressImport.php

@@ -59,6 +59,9 @@ class ExpressImport implements ToCollection,WithHeadingRow,WithMultipleSheets
             return $this->readonly($collection,$map);
         }
 
+        if (!$this->express->operation){
+            $this->express = app("OwnerPriceExpressService")->copy($this->express);
+        }
         //已存在的计费
         $existDetails = [];
         foreach ($this->express->details as $detail){
@@ -111,7 +114,7 @@ class ExpressImport implements ToCollection,WithHeadingRow,WithMultipleSheets
             LogService::log(__METHOD__,"快递计费导入录入",json_encode($insert));
         }
 
-        $this->express->load(["details"=>function($query){$query->with("province");}]);
+        $this->express->load("details.province");
         Cache::put("express",["success"=>true,"data"=>$this->express->details,"errors"=>$errors],86400);
         return true;
     }

+ 6 - 0
app/Imports/OwnerPriceDirectLogisticDetailImport.php

@@ -64,10 +64,16 @@ class OwnerPriceDirectLogisticDetailImport implements ToCollection,WithHeadingRo
             $map[$carType->name] = $carType->id;
         }
 
+        //只读情况下
         if (!$this->model){
             return $this->readonly($collection, $map, $additional);
         }
 
+        //拷贝数据时切换对象
+        if (!$this->model->operation){
+            $this->model = app("OwnerPriceDirectLogisticService")->copy($this->model);
+        }
+
         //已存在的计费
         $existDetails = [];
         foreach ($this->model->details as $detail){

+ 3 - 0
app/Imports/OwnerPriceLogisticDetailImport.php

@@ -59,6 +59,9 @@ class OwnerPriceLogisticDetailImport implements ToCollection,WithHeadingRow
         if (!$this->logistic)
             return $this->readonly($collection, $map, $cityMap, $cityMappingProvince);
 
+        if (!$this->logistic->operation){
+            $this->logistic = app("OwnerPriceLogisticService")->copy($this->express);
+        }
         //对比单位
         $unit = $this->logistic->unit ? strtoupper($this->logistic->unit->name) : '';
         $otherUnit = $this->logistic->otherUnit ? strtoupper($this->logistic->otherUnit->name) : '';

+ 75 - 9
app/Owner.php

@@ -2,8 +2,8 @@
 
 namespace App;
 
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
-use Illuminate\Database\Eloquent\SoftDeletes;
 use Illuminate\Support\Facades\Auth;
 
 /**
@@ -12,6 +12,7 @@ use Illuminate\Support\Facades\Auth;
 use App\Traits\ModelTimeFormat;
 
 use App\Traits\ModelLogChanging;
+use Illuminate\Support\Facades\DB;
 
 class Owner extends Model
 {
@@ -89,29 +90,59 @@ class Owner extends Model
     {   //工作组
         return $this->belongsTo(UserWorkgroup::class,"user_workgroup_id","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 ownerStoragePriceModels()
+    {   //仓储计费
+        $query = OwnerPriceExpress::query()->select("target_id")
+            ->whereNotNull("operation")->where("operation","!=","")
+            ->whereNotNull("target_id")->where("target_id","!=","");
+        return $this->belongsToMany(OwnerStoragePriceModel::class,"owner_storage_price_model_owner","owner_id","owner_storage_price_model_id")
+            ->whereNotIn("id",$query)->where(function(Builder $query){
+                $query->where("operation","!=","D")->orWhereNull("operation");
+            });
+    }
     public function ownerPriceOperations()
     {   //作业计费
-        return $this->belongsToMany(OwnerPriceOperation::class,"owner_price_operation_owner","owner_id","owner_price_operation_id");
+        $query = OwnerPriceOperation::query()->select("target_id")
+            ->whereNotNull("operation")->where("operation","!=","")
+            ->whereNotNull("target_id")->where("target_id","!=","");
+        return $this->belongsToMany(OwnerPriceOperation::class,"owner_price_operation_owner","owner_id","owner_price_operation_id")
+            ->whereNotIn("id",$query)->where(function(Builder $query){
+                $query->where("operation","!=","D")->orWhereNull("operation");
+            });
     }
     public function ownerPriceExpresses()
     {   //快递计费
-        return $this->belongsToMany(OwnerPriceExpress::class,"owner_price_express_owner","owner_id","owner_price_express_id");
+        $query = OwnerPriceExpress::query()->select("target_id")
+            ->whereNotNull("operation")->where("operation","!=","")
+            ->whereNotNull("target_id")->where("target_id","!=","");
+        return $this->belongsToMany(OwnerPriceExpress::class,"owner_price_express_owner","owner_id","owner_price_express_id")
+            ->whereNotIn("id",$query)->where(function(Builder $query){
+                $query->where("operation","!=","D")->orWhereNull("operation");
+            });
     }
     public function ownerPriceLogistics()
     {   //物流计费
-        return $this->belongsToMany(OwnerPriceLogistic::class,"owner_price_logistic_owner","owner_id","owner_price_logistic_id");
+        $query = OwnerPriceExpress::query()->select("target_id")
+            ->whereNotNull("operation")->where("operation","!=","")
+            ->whereNotNull("target_id")->where("target_id","!=","");
+        return $this->belongsToMany(OwnerPriceLogistic::class,"owner_price_logistic_owner","owner_id","owner_price_logistic_id")
+            ->whereNotIn("id",$query)->where(function(Builder $query){
+                $query->where("operation","!=","D")->orWhereNull("operation");
+            });
     }
     public function ownerPriceDirectLogistics()
     {   //直发车计费
-        return $this->belongsToMany(OwnerPriceDirectLogistic::class,"owner_price_direct_logistic_owner","owner_id","owner_price_direct_logistic_id");
+        $query = OwnerPriceExpress::query()->select("target_id")
+            ->whereNotNull("operation")->where("operation","!=","")
+            ->whereNotNull("target_id")->where("target_id","!=","");
+        return $this->belongsToMany(OwnerPriceDirectLogistic::class,"owner_price_direct_logistic_owner","owner_id","owner_price_direct_logistic_id")
+            ->whereNotIn("id",$query)->where(function(Builder $query){
+                $query->where("operation","!=","D")->orWhereNull("operation");
+            });
     }
     public function warehouse()
     {   //仓库
@@ -121,4 +152,39 @@ class Owner extends Model
     {   //税率
         return $this->belongsTo(TaxRate::class);
     }
+    public function storageAudit()
+    {   //审核的仓储模型
+        return $this->belongsToMany(OwnerStoragePriceModel::class,"owner_storage_price_model_owner")
+            ->select(DB::raw(1))->whereNotNull("operation")
+            ->where("operation","!=","")
+            ->limit(1);
+    }
+    public function operationAudit()
+    {   //审核的作业模型
+        return $this->belongsToMany(OwnerPriceOperation::class,"owner_price_operation_owner")
+            ->select(DB::raw(1))->whereNotNull("operation")
+            ->where("operation","!=","")
+            ->limit(1);
+    }
+    public function expressAudit()
+    {   //审核的快递模型
+        return $this->belongsToMany(OwnerPriceExpress::class,"owner_price_express_owner")
+            ->select(DB::raw(1))->whereNotNull("operation")
+            ->where("operation","!=","")
+            ->limit(1);
+    }
+    public function logisticAudit()
+    {   //审核的物流模型
+        return $this->belongsToMany(OwnerPriceLogistic::class,"owner_price_logistic_owner")
+            ->select(DB::raw(1))->whereNotNull("operation")
+            ->where("operation","!=","")
+            ->limit(1);
+    }
+    public function directLogisticAudit()
+    {   //审核的直发模型
+        return $this->belongsToMany(OwnerPriceDirectLogistic::class,"owner_price_direct_logistic_owner")
+            ->select(DB::raw(1))->whereNotNull("operation")
+            ->where("operation","!=","")
+            ->limit(1);
+    }
 }

+ 4 - 1
app/OwnerPriceDirectLogistic.php

@@ -13,7 +13,10 @@ class OwnerPriceDirectLogistic extends Model
 
     protected $fillable = [
         "name",     //名称
-        "base_km"   //起步公里数
+        "base_km",  //起步公里数
+        "operation",//操作
+        "target_id",//目标ID
+
     ];
 
     public function details()

+ 4 - 0
app/OwnerPriceDirectLogisticCar.php

@@ -21,4 +21,8 @@ class OwnerPriceDirectLogisticCar extends Model
     {   //车型
         return $this->hasOne(CarType::class,"id","car_type_id");
     }
+    public function ownerPriceDirectLogistic()
+    {   //直发车计费
+        return $this->belongsTo(OwnerPriceDirectLogistic::class,"owner_price_direct_logistic_id","id");
+    }
 }

+ 2 - 1
app/OwnerPriceExpress.php

@@ -15,6 +15,8 @@ class OwnerPriceExpress extends Model
         "name",             //名称
         "initial_weight",   //首重
         "additional_weight",//续重
+        "operation",        //操作
+        "target_id",        //目标ID
     ];
 
     public function owners()
@@ -34,7 +36,6 @@ class OwnerPriceExpress extends Model
     {   //获取货主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 - 0
app/OwnerPriceLogistic.php

@@ -20,6 +20,8 @@ class OwnerPriceLogistic extends Model
         "pick_up_price",    //提货费
         "fuel_price",       //燃油附加费
         "service_price",    //信息服务费
+        "operation",        //操作
+        "target_id",        //目标ID
     ];
 
     public function getUnitRangeJsonAttribute()

+ 4 - 0
app/OwnerPriceLogisticDetail.php

@@ -35,4 +35,8 @@ class OwnerPriceLogisticDetail extends Model
     { //城市
         return $this->hasOne(City::class,"id","city_id");
     }
+    public function ownerPriceLogistic()
+    {   //物流
+        return $this->belongsTo(OwnerPriceLogistic::class,"owner_price_logistic_id","id");
+    }
 }

+ 3 - 2
app/OwnerPriceOperation.php

@@ -18,9 +18,10 @@ class OwnerPriceOperation extends Model
         "remark",           //备注
         "priority",         //优先级 值越大越高
         "discount_count",   //减免值
-        "discount_date",    //减免阈值触发日
         "total_price",      //按单计价
         "total_discount_price",//按单计价减免
+        "operation",        //操作
+        "target_id",        //目标ID
     ];
     public static $features = null;
     public static $columnMapping = null;
@@ -29,7 +30,7 @@ class OwnerPriceOperation extends Model
     {   //出库规则
         return $this->hasMany(OwnerPriceOperationItem::class,"owner_price_operation_id","id");
     }
-    public function ownerPriceOperationOwners()
+    public function owners()
     {   //货主
         return $this->belongsToMany(Owner::class,"owner_price_operation_owner","owner_price_operation_id","owner_id");
     }

+ 4 - 0
app/OwnerPriceOperationItem.php

@@ -29,6 +29,10 @@ class OwnerPriceOperationItem extends Model
     {   //单位
         return $this->hasOne(Unit::class,"id","unit_id");
     }
+    public function ownerPriceOperation()
+    {   //作业计费
+        return $this->belongsTo(OwnerPriceOperation::class,"owner_price_operation_id","id");
+    }
 
 
     /* 格式化依据静态参数,在调用前设置  */

+ 2 - 0
app/OwnerStoragePriceModel.php

@@ -20,6 +20,8 @@ class OwnerStoragePriceModel extends Model
         "discount_value",   //减免值
         "unit_id",          //单位ID
         "time_unit_id",     //计时单位ID
+        "operation",        //操作
+        "target_id",        //目标ID
     ];
 
     public function unit()

+ 1 - 1
app/Services/OwnerAreaReportService.php

@@ -125,7 +125,7 @@ class OwnerAreaReportService
         }
         if ($createOwnerAreaReport){
             DB::table("owner_area_reports")->insert($createOwnerAreaReport);
-            LogService::log(__METHOD__,"客户管理-生成盘点记录",json_encode($createOwnerAreaReport));
+            LogService::log(__METHOD__,"项目管理-生成盘点记录",json_encode($createOwnerAreaReport));
         }
     }
 }

+ 88 - 2
app/Services/OwnerPriceDirectLogisticService.php

@@ -5,6 +5,7 @@ namespace App\Services;
 use App\Owner;
 use App\OwnerPriceDirectLogistic;
 use App\OwnerPriceDirectLogisticCar;
+use App\Services\common\QueryService;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Facades\DB;
 use App\Traits\ServiceAppAop;
@@ -23,13 +24,96 @@ class OwnerPriceDirectLogisticService
 
     public function create(array $params)
     {
+        $params["operation"] = "C";
         return OwnerPriceDirectLogistic::query()->create($params);
     }
 
+    /**
+     * 拷贝目标数据
+     *
+     * @param object|int $model
+     * @param array $values
+     * @param array|null $owners
+     * @param array $items
+     * @param bool $isLoadItem
+     *
+     * @return object|null
+     */
+    public function copy($model, $values = [], $owners = null, $items = [], $isLoadItem = true)
+    {
+        if (is_integer($model))$model = OwnerPriceDirectLogistic::query()->find($model);
+        if (!$model)return null;
+        $values["operation"] = "U";
+        $values["target_id"] = $model->id;
+        foreach ($model->getFillable() as $column){
+            if (!array_key_exists($column,$values))$values[$column] = $model[$column];
+        }
+        /** @var OwnerPriceDirectLogistic $copyModel */
+        $copyModel = OwnerPriceDirectLogistic::query()->create($values);
+
+        if ($owners===null){
+            $query = DB::raw("SELECT * FROM owner_price_direct_logistic_owner WHERE owner_price_direct_logistic_id = {$model->id}");
+            $owners = array_column(DB::select($query),"owner_id");
+        }
+        $copyModel->owners()->sync($owners);
+        $insert = [];
+        if ($isLoadItem){
+            $model->loadMissing("details");
+            /** @var \stdClass $model */
+            foreach ($model->details as $item){
+                $columns = ["car_type_id", "base_fee", "additional_fee"];
+                if ($items[$item->id] ?? false){
+                    foreach ($columns as $column){
+                        if (!array_key_exists($column,$items[$item->id]))$items[$item->id][$column] = $item[$column];
+                    }
+                    $obj = $items[$item->id];
+                    unset($items[$item->id]);
+                }else{
+                    /** @var OwnerPriceDirectLogisticCar $item */
+                    $obj = $item->toArray();
+                    unset($obj["id"]);
+                }
+                $obj["owner_price_direct_logistic_id"] = $copyModel->id;
+                $insert[] = $obj;
+            }
+        }else{
+            foreach ($items as $item){
+                $item["owner_price_direct_logistic_id"] = $copyModel->id;
+                $insert[] = $item;
+            }
+        }
+        if ($insert)OwnerPriceDirectLogisticCar::query()->insert($insert);
+        return $copyModel;
+    }
+
+    /**
+     * 审核或恢复目标集
+     *
+     * @param bool $isAudit
+     * @param integer|null|array $ownerId
+     * @param integer|null|array $ids
+     */
+    public function auditOrRecover($isAudit = true, $ownerId = null, $ids = null)
+    {
+        if (!$ownerId && !$ids)return;
+        $result = app(QueryService::class)->priceModelAuditOrRecoverQuery($isAudit,OwnerPriceDirectLogistic::query(),$ownerId,$ids);
+        if ($result["delete"])$this->destroy($result["delete"]);
+        if ($result["update"])OwnerPriceDirectLogistic::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
+    }
+
     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();
+        if (!is_array($id))$id = [$id];
+        OwnerPriceDirectLogisticCar::query()->whereIn("owner_price_direct_logistic_id",$id)->delete();
+
+        $query = "IN (";
+        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
+        $query .= "{$id[count($id)-1]})";
+
+        $sql = "SELECT * FROM owner_price_direct_logistic_owner WHERE owner_price_direct_logistic_id {$query}";
+        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
+        DB::table("owner_price_direct_logistic_owner")->whereIn("owner_price_direct_logistic_id",$id)->delete();
+        app("OwnerService")->refreshRelevance($owners,4,true);
         return OwnerPriceDirectLogistic::destroy($id);
     }
 
@@ -105,6 +189,8 @@ class OwnerPriceDirectLogisticService
         }])->whereHas("owners",function ($query)use($owner_id){
             /** @var Builder $query */
             $query->where("id",$owner_id);
+        })->where(function(Builder $query){
+            $query->whereNull("operation")->orWhere("operation","");
         })->first();
         if (!$model || !$model->details)return -1;
         if ($amount < $model->base_km)$amount = $model->base_km;

+ 95 - 3
app/Services/OwnerPriceExpressService.php

@@ -6,6 +6,7 @@ use App\Logistic;
 use App\Owner;
 use App\OwnerPriceExpress;
 use App\OwnerPriceExpressProvince;
+use App\Services\common\QueryService;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Facades\DB;
 use App\Traits\ServiceAppAop;
@@ -29,6 +30,85 @@ class OwnerPriceExpressService
         return OwnerPriceExpress::query()->with($withs)->find($id);
     }
 
+    /**
+     * 拷贝目标数据
+     *
+     * @param object|int $model
+     * @param array $values
+     * @param array|null $owners
+     * @param array|null $logistics
+     * @param array $items
+     * @param bool $isLoadItem
+     *
+     * @return object|null
+     */
+    public function copy($model, $values = [], $owners = null, $logistics = null, $items = [], $isLoadItem = true)
+    {
+        if (is_integer($model))$model = OwnerPriceExpress::query()->find($model);
+        if (!$model)return null;
+        $values["operation"] = "U";
+        $values["target_id"] = $model->id;
+        foreach ($model->getFillable() as $column){
+            if (!array_key_exists($column,$values))$values[$column] = $model[$column];
+        }
+        /** @var OwnerPriceExpress $copyModel */
+        $copyModel = OwnerPriceExpress::query()->create($values);
+
+        if ($owners===null){
+            $query = DB::raw("SELECT * FROM owner_price_express_owner WHERE owner_price_express_id = {$model->id}");
+            $owners = array_column(DB::select($query),"owner_id");
+        }
+        $copyModel->owners()->sync($owners);
+        if ($logistics===null){
+            $query = DB::raw("SELECT * FROM owner_price_express_logistic WHERE owner_price_express_id = {$model->id}");
+            $logistics = array_column(DB::select($query),"logistic_id");
+        }
+        $copyModel->logistics()->sync($logistics);
+        $insert = [];
+        if ($isLoadItem){
+            $model->loadMissing("details");
+            /** @var \stdClass $model */
+            foreach ($model->details as $item){
+                $columns = ["province_id","initial_weight_price","additional_weight_price"];
+                if ($items[$item->id] ?? false){
+                    foreach ($columns as $column){
+                        if (!array_key_exists($column,$items[$item->id]))$items[$item->id][$column] = $item[$column];
+                    }
+                    $obj = $items[$item->id];
+                    unset($items[$item->id]);
+                }else{
+                    /** @var OwnerPriceExpressProvince $item */
+                    $obj = $item->toArray();
+                    unset($obj["id"]);
+                }
+                $obj["owner_price_express_id"] = $copyModel->id;
+                $insert[] = $obj;
+            }
+        }else{
+            foreach ($items as $item){
+                $item["owner_price_express_id"] = $copyModel->id;
+                $insert[] = $item;
+            }
+        }
+        if ($insert)OwnerPriceExpressProvince::query()->insert($insert);
+        return $copyModel;
+    }
+
+    /**
+     * 审核或恢复目标集
+     *
+     * @param bool $isAudit
+     * @param integer|null|array $ownerId
+     * @param integer|null|array $ids
+     */
+    public function auditOrRecover($isAudit = true, $ownerId = null, $ids = null)
+    {
+        if (!$ownerId && !$ids)return;
+        $result = app(QueryService::class)->priceModelAuditOrRecoverQuery($isAudit,OwnerPriceExpress::query(),$ownerId,$ids);
+        if ($result["delete"])$this->destroy($result["delete"]);
+        if ($result["update"])OwnerPriceExpress::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
+    }
+
     public function updateDetail(array $params, array $values)
     {
         $query = OwnerPriceExpressProvince::query();
@@ -40,6 +120,7 @@ class OwnerPriceExpressService
 
     public function create(array $params)
     {
+        $params["operation"] = "U";
         return OwnerPriceExpress::query()->create($params);
     }
 
@@ -102,9 +183,18 @@ class OwnerPriceExpressService
 
     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();
+        if (!is_array($id))$id = [$id];
+        OwnerPriceExpressProvince::query()->whereIn("owner_price_express_id",$id)->delete();
+
+        $query = "IN (";
+        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
+        $query .= "{$id[count($id)-1]})";
+
+        $sql = "SELECT * FROM owner_price_express_owner WHERE owner_price_express_id {$query}";
+        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
+        DB::table("owner_price_express_owner")->whereIn("owner_price_express_id",$id)->delete();
+        app("OwnerService")->refreshRelevance($owners,2,true);
+        DB::table("owner_price_express_logistic")->whereIn("owner_price_express_id",$id)->delete();
         return OwnerPriceExpress::destroy($id);
     }
 
@@ -160,6 +250,8 @@ sql
         })->whereHas("logistics",function ($query)use($logistic_id){
             /** @var Builder $query */
             $query->where("id",$logistic_id);
+        })->where(function(Builder $query){
+            $query->whereNull("operation")->orWhere("operation","");
         })->first();
         if (!$model || !$model->details)return -1;
         if ($weight <= $model->initial_weight)return $model->details[0]->initial_weight_price;

+ 97 - 6
app/Services/OwnerPriceLogisticService.php

@@ -4,6 +4,7 @@ namespace App\Services;
 
 use App\OwnerPriceLogistic;
 use App\OwnerPriceLogisticDetail;
+use App\Services\common\QueryService;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Facades\DB;
 use App\Traits\ServiceAppAop;
@@ -21,6 +22,7 @@ class OwnerPriceLogisticService
 
     public function create(array $params)
     {
+        $params["operation"] = "U";
         return OwnerPriceLogistic::query()->create($params);
     }
 
@@ -38,14 +40,101 @@ class OwnerPriceLogisticService
         return $query->update($values);
     }
 
+    /**
+     * 拷贝目标数据
+     *
+     * @param object|int $model
+     * @param array $values
+     * @param array|null $owners
+     * @param array|null $logistics
+     * @param array $items
+     * @param bool $isLoadItem
+     *
+     * @return object|null
+     */
+    public function copy($model, $values = [], $owners = null, $logistics = null, $items = [], $isLoadItem = true)
+    {
+        if (is_integer($model))$model = OwnerPriceLogistic::query()->find($model);
+        if (!$model)return null;
+        $values["operation"] = "U";
+        $values["target_id"] = $model->id;
+        foreach ($model->getFillable() as $column){
+            if (!array_key_exists($column,$values))$values[$column] = $model[$column];
+        }
+        /** @var OwnerPriceLogistic $copyModel */
+        $copyModel = OwnerPriceLogistic::query()->create($values);
+
+        if ($owners===null){
+            $query = DB::raw("SELECT * FROM owner_price_logistic_owner WHERE owner_price_logistic_id = {$model->id}");
+            $owners = array_column(DB::select($query),"owner_id");
+        }
+        $copyModel->owners()->sync($owners);
+        if ($logistics===null){
+            $query = DB::raw("SELECT * FROM owner_price_logistic_logistic WHERE owner_price_logistic_id = {$model->id}");
+            $logistics = array_column(DB::select($query),"logistic_id");
+        }
+        $copyModel->logistics()->sync($logistics);
+        $insert = [];
+        if ($isLoadItem){
+            $model->loadMissing("details");
+            /** @var \stdClass $model */
+            foreach ($model->details as $item){
+                $columns = ["unit_id", "range", "province_id", "city_id", "unit_price", "delivery_fee", "initial_fee", "initial_amount", "rate",];
+                if ($items[$item->id] ?? false){
+                    foreach ($columns as $column){
+                        if (!array_key_exists($column,$items[$item->id]))$items[$item->id][$column] = $item[$column];
+                    }
+                    $obj = $items[$item->id];
+                    unset($items[$item->id]);
+                }else{
+                    /** @var OwnerPriceLogisticDetail $item */
+                    $obj = $item->toArray();
+                    unset($obj["id"]);
+                }
+                $obj["owner_price_logistic_id"] = $copyModel->id;
+                $insert[] = $obj;
+            }
+        }else{
+            foreach ($items as $item){
+                $item["owner_price_logistic_id"] = $copyModel->id;
+                $insert[] = $item;
+            }
+        }
+        if ($insert)OwnerPriceLogisticDetail::query()->insert($insert);
+        return $copyModel;
+    }
+
+    /**
+     * 审核或恢复目标集
+     *
+     * @param bool $isAudit
+     * @param integer|null|array $ownerId
+     * @param integer|null|array $ids
+     */
+    public function auditOrRecover($isAudit = true, $ownerId = null, $ids = null)
+    {
+        if (!$ownerId && !$ids)return;
+        $result = app(QueryService::class)->priceModelAuditOrRecoverQuery($isAudit,OwnerPriceLogistic::query(),$ownerId,$ids);
+        if ($result["delete"])$this->destroy($result["delete"]);
+        if ($result["update"])OwnerPriceLogistic::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
+    }
+
     public function destroy($id)
     {
-        DB::transaction(function ()use($id){
-            DB::table("owner_price_logistic_logistic")->where("owner_price_logistic_id",$id)->delete();
-            DB::table("owner_price_logistic_owner")->where("owner_price_logistic_id",$id)->delete();
-            OwnerPriceLogisticDetail::query()->where("owner_price_logistic_id",$id)->delete();
-            OwnerPriceLogistic::destroy($id);
-        });
+        if (!is_array($id))$id = [$id];
+        OwnerPriceLogisticDetail::query()->whereIn("owner_price_logistic_id",$id)->delete();
+
+        $query = "IN (";
+        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
+        $query .= "{$id[count($id)-1]})";
+
+        $sql = "SELECT * FROM owner_price_logistic_owner WHERE owner_price_logistic_id {$query}";
+        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
+        DB::table("owner_price_logistic_owner")->whereIn("owner_price_logistic_id",$id)->delete();
+        app("OwnerService")->refreshRelevance($owners,3,true);
+        DB::table("owner_price_logistic_logistic")->whereIn("owner_price_logistic_id",$id)->delete();
+
+        return OwnerPriceLogistic::destroy($id);
     }
 
     public function updateDetail(array $params, array $values)
@@ -127,6 +216,8 @@ class OwnerPriceLogisticService
         })->whereHas("logistics",function ($query)use($logistic_id){
             /** @var Builder $query */
             $query->where("id",$logistic_id);
+        })->where(function(Builder $query){
+            $query->whereNull("operation")->orWhere("operation","");
         })->first();
         if (!$model || !$model->details)return -1;
         $fee = $model->pick_up_price + $model->fuel_price + $model->service_price; //服务费

+ 98 - 3
app/Services/OwnerPriceOperationService.php

@@ -50,10 +50,93 @@ class OwnerPriceOperationService
         return array_column($arr,"id");
     }
 
+    /**
+     * 拷贝目标数据
+     *
+     * @param object|int $model
+     * @param array $values
+     * @param array $items
+     * @param array|null $owners
+     * @param bool $isLoadItem
+     *
+     * @return object|null
+     */
+    public function copy($model, $values = [], $owners = null, $items = [], $isLoadItem = true)
+    {
+        if (is_integer($model))$model = OwnerPriceOperation::query()->find($model);
+        if (!$model)return null;
+        $values["operation"] = "U";
+        $values["target_id"] = $model->id;
+        foreach ($model->getFillable() as $column){
+            if (!array_key_exists($column,$values))$values[$column] = $model[$column];
+        }
+        if ($owners === null){
+            $query = DB::raw("SELECT * FROM owner_price_operation_owner WHERE owner_price_operation_id = {$model->id}");
+            $owners = array_column(DB::select($query),"owner_id");
+        }
+        /** @var OwnerPriceOperation $copyModel */
+        $copyModel = OwnerPriceOperation::query()->create($values);
+        $copyModel->owners()->sync($owners);
+        $insert = [];
+        if ($isLoadItem){
+            $model->load("items");
+            /** @var \stdClass $model */
+            foreach ($model->items as $item){
+                $columns = ["strategy","amount","unit_id","unit_price","feature","priority","discount_price"];
+                if ($items[$item->id] ?? false){
+                    foreach ($columns as $column){
+                        if (!array_key_exists($column,$items[$item->id]))$items[$item->id][$column] = $item[$column];
+                    }
+                    $obj = $items[$item->id];
+                    unset($items[$item->id]);
+                }else{
+                    /** @var OwnerPriceOperationItem $item */
+                    $obj = $item->toArray();
+                    unset($obj["id"]);
+                }
+                $obj["owner_price_operation_id"] = $copyModel->id;
+                $insert[] = $obj;
+            }
+        }else{
+            foreach ($items as $item){
+                $item["owner_price_operation_id"] = $copyModel->id;
+                $item["discount_price"] = implode(",",$item["discount_price"]) ?? null;
+                $insert[] = $item;
+            }
+        }
+        if ($insert)OwnerPriceOperationItem::query()->insert($insert);
+        return $copyModel;
+    }
+
+    /**
+     * 审核或恢复目标集
+     *
+     * @param bool $isAudit
+     * @param integer|null|array $ownerId
+     * @param integer|null|array $ids
+     */
+    public function auditOrRecover($isAudit = true, $ownerId = null, $ids = null)
+    {
+        if (!$ownerId && !$ids)return;
+        $result = app(QueryService::class)->priceModelAuditOrRecoverQuery($isAudit,OwnerPriceOperation::query(),$ownerId,$ids);
+        if ($result["delete"])$this->destroy($result["delete"]);
+        if ($result["update"])OwnerPriceOperation::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
+    }
+
     public function destroy($id)
     {
-        OwnerPriceOperationItem::query()->where("owner_price_operation_id",$id)->delete();
-        DB::table("owner_price_operation_owner")->where("owner_price_operation_id",$id)->delete();
+        if (!is_array($id))$id = [$id];
+        OwnerPriceOperationItem::query()->whereIn("owner_price_operation_id",$id)->delete();
+
+        $query = "IN (";
+        for ($i=0;$i<count($id)-1;$i++)$query .= "{$id[$i]},";
+        $query .= "{$id[count($id)-1]})";
+
+        $sql = "SELECT * FROM owner_price_operation_owner WHERE owner_price_operation_id {$query}";
+        $owners = array_column(DB::select(DB::raw($sql)),"owner_id");
+        DB::table("owner_price_operation_owner")->whereIn("owner_price_operation_id",$id)->delete();
+        app("OwnerService")->refreshRelevance($owners,1,true);
+
         return OwnerPriceOperation::destroy($id);
     }
 
@@ -63,6 +146,7 @@ class OwnerPriceOperationService
      */
     public function create(array $params)
     {
+        $params["operation"] = "C";
         return OwnerPriceOperation::query()->create($params);
     }
 
@@ -77,6 +161,15 @@ class OwnerPriceOperationService
         return $query;
     }
 
+    public function update(array $params, array $values)
+    {
+        $query = OwnerPriceOperation::query();
+        foreach ($params as $column => $value){
+            $query->where($column,$value);
+        }
+        return $query->update($values);
+    }
+
     public function destroyItem($id)
     {
         return OwnerPriceOperationItem::query()->where("owner_price_operation_id",$id)->delete();
@@ -117,9 +210,11 @@ class OwnerPriceOperationService
         $rules = OwnerPriceOperation::query()->with(["items"=>function($query){
             /** @var Builder $query */
             $query->orderByRaw("CASE strategy  WHEN '起步' THEN 1 WHEN '默认' THEN 2 WHEN '特征' THEN 3 END DESC,priority");
-        }])->where("operation_type",$type)->whereHas("ownerPriceOperationOwners",function ($query)use($owner_id){
+        }])->where("operation_type",$type)->whereHas("owners",function ($query)use($owner_id){
                 /** @var Builder $query */
                 $query->where("id",$owner_id);
+        })->where(function(Builder $query){
+            $query->whereNull("operation")->orWhere("operation","");
         })->orderByRaw("strategy desc,priority desc")->get(); //货主下的全部规则
 
         if (!$rules)return -2;  //规则不存在跳出

+ 25 - 4
app/Services/OwnerService.php

@@ -374,17 +374,17 @@ sql
      * @param bool $isDestroy
      *
      */
-    public function refreshRelevance($owner, $type, $isDestroy)
+    public function refreshRelevance($owner, $type, $isDestroy = false)
     {
         if (!$owner)return;
         if (!is_array($owner))$owner = [$owner];
-        $owners = Owner::query()->select("id","relevance")->find($owner);
+        $owners = Owner::query()->select("id","relevance")->whereIn("id",$owner)->get();
         $update = [["id","relevance"]];
         foreach ($owners as $ow){
             $relevance = $ow->relevance ?? [];
-            $index = array_search($type,$ow->relevance);
+            $index = array_search($type,$relevance);
             $exist = $index===false ? false : true;
-            if ($exist && $isDestroy){
+            if ($exist && $isDestroy && !$this->isExistModel($ow->id,$type)){
                 $arr = array_splice($relevance,$index,1);
                 $update[] = [
                     "id"=>$ow->id,
@@ -401,4 +401,25 @@ sql
         }
         if (count($update)>1)app(BatchUpdateService::class)->batchUpdate("owners",$update);
     }
+
+    private function isExistModel($owner, $type):bool
+    {
+        switch ($type){
+            case 0:
+                $table = "owner_storage_price_model_owner";
+                break;
+            case 1:
+                $table = "owner_price_operation_owner";
+                break;
+            case 2:
+                $table = "owner_price_logistic_owner";
+                break;
+            case 3:
+                $table = "owner_price_express_owner";
+                break;
+            default:
+                $table = "owner_price_direct_logistic_owner";
+        }
+        return DB::selectOne(DB::raw("SELECT 1 FROM {$table} WHERE owner_id = ? LIMIT 1"),[$owner]) ? true : false;
+    }
 }

+ 60 - 2
app/Services/OwnerStoragePriceModelService.php

@@ -5,6 +5,8 @@ namespace App\Services;
 use App\Order;
 use App\OwnerReport;
 use App\OwnerStoragePriceModel;
+use App\Services\common\QueryService;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Facades\DB;
 use App\Traits\ServiceAppAop;
 
@@ -27,9 +29,53 @@ class OwnerStoragePriceModelService
 
     public function create(array $params)
     {
+        $params["operation"] = "C";
         return OwnerStoragePriceModel::query()->create($params);
     }
 
+    /**
+     * 拷贝目标数据
+     *
+     * @param object|int $model
+     * @param array $values
+     * @param array|null $owners
+     *
+     * @return object|null
+     */
+    public function copy($model, $values = [], $owners = null)
+    {
+        if (is_integer($model))$model = OwnerStoragePriceModel::query()->find($model);
+        if (!$model)return null;
+        $values["operation"] = "U";
+        $values["target_id"] = $model->id;
+        foreach ($model->getFillable() as $column){
+            if (!array_key_exists($column,$values))$values[$column] = $model[$column];
+        }
+        if ($owners===null){
+            $query = DB::raw("SELECT * FROM owner_storage_price_model_owner WHERE owner_storage_price_model_id = {$model->id}");
+            $owners = array_column(DB::select($query),"owner_id");
+        }
+        /** @var OwnerStoragePriceModel $model */
+        $model = OwnerStoragePriceModel::query()->create($values);
+        $model->owners()->sync($owners);
+        return $model;
+    }
+
+    /**
+     * 审核或恢复目标集
+     *
+     * @param bool $isAudit
+     * @param integer|null|array $ownerId
+     * @param integer|null|array $ids
+     */
+    public function auditOrRecover($isAudit = true, $ownerId = null, $ids = null)
+    {
+        if (!$ownerId && !$ids)return;
+        $result = app(QueryService::class)->priceModelAuditOrRecoverQuery($isAudit,OwnerStoragePriceModel::query(),$ownerId,$ids);
+        if ($result["delete"])$this->destroy($result["delete"]);
+        if ($result["update"])OwnerStoragePriceModel::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
+    }
+
     public function update(array $params, array $values)
     {
         $query = OwnerStoragePriceModel::query();
@@ -45,7 +91,19 @@ class OwnerStoragePriceModelService
     }
     public function destroy($id)
     {
-        DB::delete(DB::raw("DELETE FROM owner_storage_price_model_owner WHERE owner_storage_price_model_id = ?"),[$id]);
+        $sql = "SELECT * FROM owner_storage_price_model_owner WHERE owner_storage_price_model_id ";
+        if (is_array($id)){
+            $query = "IN (";
+            for ($i=0;$i<count($id)-1;$i++)$query .= "?,";
+            $query .= "?)";
+        }else{
+            $query = "= ?";
+            $id = [$id];
+        }
+        $owners = array_column(DB::select(DB::raw($sql.$query),$id),"owner_id");
+        DB::delete(DB::raw("DELETE FROM owner_storage_price_model_owner WHERE owner_storage_price_model_id ".$query),$id);
+        app("OwnerService")->refreshRelevance($owners,0,true);
+
         return OwnerStoragePriceModel::destroy($id);
     }
 
@@ -53,7 +111,7 @@ class OwnerStoragePriceModelService
     public function calculationAmount(OwnerStoragePriceModel $model, $area, $owner_id = null, $month = null)
     {
         /** @var \stdClass $model */
-        if (!$model || !$area) return 0;
+        if (!$model || !$area || $model->operation) return 0;
         if ($area < $model->minimum_area) $area = $model->minimum_area;
         switch ($model->discount_type){
             case "按单减免":

+ 35 - 1
app/Services/common/QueryService.php

@@ -4,8 +4,8 @@ namespace App\Services\common;
 
 
 use Carbon\Carbon;
-use Illuminate\Http\Request;
 use App\Traits\ServiceAppAop;
+use Illuminate\Database\Eloquent\Builder;
 
 
 class QueryService
@@ -77,4 +77,38 @@ class QueryService
         return $query;
     }
 
+    public function priceModelAuditOrRecoverQuery($isAudit, Builder $query, $ownerId, $ids)
+    {
+        $query = $query->whereNotNull("operation")->where("operation","!=","");
+        if ($ownerId) $query->whereHas("owners",function ($query)use($ownerId){
+            /** @var Builder $query */
+            if (is_array($ownerId))$query->whereIn("id",$ownerId);
+            else $query->where("id",$ownerId);
+        });
+        if ($ids){
+            if (is_array($ids))$query->whereIn("id",$ids);
+            else $query->where("id",$ids);
+        }
+        $delete = [];
+        $update = [];
+        if ($isAudit){
+            foreach ($query->get() as $model){
+                if ($model->operation == "D"){
+                    $delete[] = $model->id;
+                    continue;
+                }
+                if ($model->operation == "U")$delete[] = $model->target_id;
+                $update[] = $model->id;
+            }
+        }else{
+            foreach ($query->get() as $model){
+                if ($model->operation == "D"){
+                    $update[] = $model->id;
+                    continue;
+                }
+                $delete[] = $model->id;
+            }
+        }
+        return ["delete"=>$delete,"update"=>$update];
+    }
 }

+ 59 - 0
database/migrations/2021_03_09_172210_change_price_model_table.php

@@ -0,0 +1,59 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangePriceModelTable extends Migration
+{
+
+    protected $tables = ["owner_storage_price_models","owner_price_operations","owner_price_logistics","owner_price_expresses","owner_price_direct_logistics"];
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        foreach(\App\Authority::query()->where("name","like","客户管理%")->get() as $authority){
+            $name =  mb_substr($authority->name,2);
+            $authority->update(["name"=>"项目".$name,"alias_name"=>"项目".$name]);
+        };
+        foreach ($this->tables as $table){
+            Schema::table($table,function (Blueprint $table){
+                $table->char("operation",1)->index()->nullable()->comment("操作类型");
+                $table->bigInteger("target_id")->index()->nullable()->comment("目标ID");
+            });
+        }
+        \App\Authority::query()->firstOrCreate(["name"=>"项目管理-项目-计费模型-审核"],["name"=>"项目管理-项目-计费模型-审核","alias_name"=>"项目管理-项目-计费模型-审核"]);
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        foreach(\App\Authority::query()->where("name","like","项目管理%")->get() as $authority){
+            $name =  mb_substr($authority->name,2);
+            $authority->update(["name"=>"客户".$name,"alias_name"=>"客户".$name]);
+        };
+        foreach ($this->tables as $table){
+            Schema::table($table,function (Blueprint $table){
+                $table->dropColumn("operation",1);
+                $table->dropColumn("target_id");
+            });
+        }
+        \App\Authority::query()->where("name","项目管理-项目-计费模型-审核")->delete();
+    }
+
+    /*TODO 可回滚数据功能:1.增加两个字段 operation(哪种类型操作) target_id(映射目标)
+                        2.新增操作:未审核时增加operation为C
+                        修改前提,对应的映射目标不可被查看修改
+                        3.修改操作:当前修改对象是否为被标记过对象,是->直接修改当前对象 否->生成标记对象
+                        3.删除操作:当前删除对象是否为被标记过对象,是->目标是否存在(是->删除当前对象,将目标对象标记为删除 否->将当前对象标记为删除) 否->将当前对象标记为删除
+        审核操作:被标记为C的删除标记信息 被标记为U的删除目标对象与当前对象的标记信息 被标记为D的直接删除
+        恢复操作:被标记为C的直接删除 被标记为U的删除当前对象 被标记为D的删除当前对象的标记信息
+    */
+}

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

@@ -1,5 +1,5 @@
 @extends('layouts.app')
-@section('title')客户管理@endsection
+@section('title')项目管理@endsection
 
 @section("content")
     @component('customer.project.menu')@endcomponent

+ 3 - 3
resources/views/customer/menu.blade.php

@@ -2,15 +2,15 @@
 <div class="container-fluid nav2" id="nav2">
     <div class="card">
         <ul class="nav nav-pills">
-            @can('客户管理-项目')
+            @can('项目管理-项目')
             <li class="nav-item">
                 <a target="customer/project/area" class="nav-link" href="{{url('customer/project/area')}}" :class="{active:isActive('project',2)}">项目</a>
             </li>@endcan
-            @can('客户管理-客户')
+            @can('项目管理-客户')
             <li class="nav-item">
                 <a target="customer/customer" class="nav-link" href="{{url('customer/customer')}}" :class="{active:isActive('customer',2)}">客户</a>
             </li>@endcan
-            @can('客户管理-相关设置')
+            @can('项目管理-相关设置')
             <li class="nav-item">
                 <a target="customer/relating" class="nav-link" href="{{url('customer/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
             </li>

+ 4 - 4
resources/views/customer/project/area.blade.php

@@ -1,6 +1,6 @@
 @extends('layouts.app')
 @section('title')
-    用仓盘点-客户管理
+    用仓盘点-项目管理
 @endsection
 @section('content')
     @component('customer.project.menu')@endcomponent
@@ -36,7 +36,7 @@
                     <td>
                         <span v-if="area.status=='编辑中'">
                             <button class="btn btn-sm btn-outline-info" @click="edit(area,i)">编辑</button>
-                            @can("客户管理-项目-用仓盘点-审核")<button class="btn btn-sm btn-outline-success" v-if="area.accountingArea" @click="audit(i)">审核</button>@endcan
+                            @can("项目管理-项目-用仓盘点-审核")<button class="btn btn-sm btn-outline-success" v-if="area.accountingArea" @click="audit(i)">审核</button>@endcan
                         </span>
                         <span v-if="area.status=='已完成'" class="text-success font-weight-bold">@{{ area.status }}</span>
                         <span v-if="area.status=='已审核'" class="text-primary font-weight-bold">@{{ area.status }}</span>
@@ -131,13 +131,13 @@
                     </div>
                     <div class="row">
                         <div class="col-10 offset-1">
-                            @can('客户管理-项目-用仓盘点-审核')<button type="button" @click.stop="submitArea(i)" class="btn btn-sm btn-outline-primary w-100">提交编辑</button>@endcan
+                            @can('项目管理-项目-用仓盘点-审核')<button type="button" @click.stop="submitArea(i)" class="btn btn-sm btn-outline-primary w-100">提交编辑</button>@endcan
                         </div>
                     </div>
                 </div>
                 <div class="row mt-2" v-if="area.status=='编辑中'">
                     <div class="col-10 offset-1">
-                        @can('客户管理-项目-用仓盘点-审核')<button type="button" @click.stop="audit(i)" class="btn btn-sm btn-outline-success w-100">审核</button>@endcan
+                        @can('项目管理-项目-用仓盘点-审核')<button type="button" @click.stop="audit(i)" class="btn btn-sm btn-outline-success w-100">审核</button>@endcan
                     </div>
                 </div>
             </div>

+ 128 - 63
resources/views/customer/project/create.blade.php

@@ -1,5 +1,5 @@
 @extends('layouts.app')
-@section('title')项目编辑-客户管理@endsection
+@section('title')项目编辑-项目管理@endsection
 @section("head")<link href="{{ mix('css/animation.css') }}" rel="stylesheet">@endsection
 @section('content')
     @component('customer.project.menu')
@@ -197,6 +197,7 @@
                 searchItem:{},//搜索子项集
                 searchBase:5,//搜索基数
                 hover:{},//可悬浮列表
+                audit:{},
             },
             mounted(){
                 let type = "{{$type ?? ''}}";
@@ -426,56 +427,76 @@
                             break;
                     }
                 },
+                //重载作业费
+                _overrideOperation(operation){
+                    if (operation.discount_count){
+                        if (operation.discount_count) operation.discount_count = operation.discount_count.split(",");
+                        if (operation.total_discount_price) operation.total_discount_price = operation.total_discount_price.split(",");
+                        operation.isDiscount = true;
+                    }
+                    operation.items.forEach((item,j)=>{
+                        if (item.discount_price) operation.items[j].discount_price = item.discount_price.split(",");
+                    });
+                    if (operation.total_price)operation.isSingle = true;
+                    return operation;
+                },
+                //重载快递费
+                _overrideExpress(express){
+                    express.logistics.forEach((logistic,j)=>{
+                        express.logistics[j] = logistic.id;
+                    });
+                    return JSON.parse(JSON.stringify(express).replace(/details/g,"items"));
+                },
+                //重载物流费
+                _overrideLogistic(logistic){
+                    logistic.logistics.forEach((l,j)=>{
+                        logistic.logistics[j] = l.id;
+                    });
+                    return JSON.parse(JSON.stringify(logistic).replace(/details/g,"items"));
+                },
+                //重载直发费
+                _overrideDirectLogistic(directLogistic){
+                    return JSON.parse(JSON.stringify(directLogistic).replace(/details/g,"items"));
+                },
                 //加载计费模型
                 _loadPriceModel(){
                     let url = "{{url('customer/project/getPriceModel')}}";
                     let params = {id:this.ownerTemp.id};
                     window.tempTip.postBasicRequest(url,params,res=>{
+                        let audit = {};
+                        if (res.storage_audit_count)audit.storage = true;
+                        if (res.operation_audit_count)audit.operation = true;
+                        if (res.express_audit_count)audit.express = true;
+                        if (res.logistic_audit_count)audit.logistic = true;
+                        if (res.direct_logistic_audit_count)audit.directLogistic = true;
+                        this.audit = audit;
                         if (res.owner_storage_price_models.length>0)this.selectedModel.storage = res.owner_storage_price_models;
                         if (res.owner_price_operations.length>0){
                             this._loadOperation();
-                            res.owner_price_operations.forEach((operation,i)=>{
-                                if (operation.discount_count){
-                                    if (operation.discount_count) res.owner_price_operations[i].discount_count = operation.discount_count.split(",");
-                                    if (operation.total_discount_price) res.owner_price_operations[i].total_discount_price = operation.total_discount_price.split(",");
-                                    operation.isDiscount = true;
-                                }
-                                operation.items.forEach((item,j)=>{
-                                    if (item.discount_price) res.owner_price_operations[i].items[j].discount_price = item.discount_price.split(",");
-                                });
-                                if (operation.total_price)operation.isSingle = true;
-                            });
+                            res.owner_price_operations.forEach(operation=>{operation = this._overrideOperation(operation);});
                             this.selectedModel.operation = res.owner_price_operations;
                         }
                         if (res.owner_price_expresses.length>0){
                             this._loadExpress();
                             res.owner_price_expresses.forEach((express,i)=>{
-                                express.logistics.forEach((logistic,j)=>{
-                                    express.logistics[j] = logistic.id;
-                                });
-                                res.owner_price_expresses[i] = JSON.parse(JSON.stringify(express).replace(/details/g,"items"));
+                                express = this._overrideExpress(express);
                                 this.upList['express-item-'+i] = true;
                             });
                             this.selectedModel.express = res.owner_price_expresses;
                         }
                         if (res.owner_price_logistics.length>0){
                             if (res.owner_price_expresses.length===0)this._loadLogistic();
-                            else {
-                                this._getUnits();
-                                this._getCities();
-                            }
+                            else {this._getUnits();this._getCities();}
                             res.owner_price_logistics.forEach((logistic,i)=>{
-                                logistic.logistics.forEach((l,j)=>{
-                                    logistic.logistics[j] = l.id;
-                                });
-                                res.owner_price_logistics[i] = JSON.parse(JSON.stringify(logistic).replace(/details/g,"items"));
+                                logistic = this._overrideLogistic(logistic);
                                 this.upList['logistic-item-'+i] = true;
                             });
                             this.selectedModel.logistic = res.owner_price_logistics;
                         }
                         if (res.owner_price_direct_logistics.length>0){
+                            this._loadDirectLogistic();
                             this.upList["directLogistic-item"] = true;
-                            this.selectedModel.directLogistic = JSON.parse(JSON.stringify(res.owner_price_direct_logistics[0]).replace(/details/g,"items"));
+                            this.selectedModel.directLogistic = this._overrideDirectLogistic(res.owner_price_direct_logistics[0]);
                         }
                         setTimeout(()=> {
                             $(".up").slideUp();
@@ -605,8 +626,10 @@
                             this.errors = res.errors;
                             return;
                         }
-                        if (this.model.storage.id) this.selectedModel.storage[this.model.storage.index] = this.model.storage;
-                        else {
+                        if (this.model.storage.id){
+                            if (res) this.selectedModel.storage[this.model.storage.index] = this.model.storage;
+                            else this.$set(this.selectedModel.storage,this.model.storage.index,res);
+                        }else {
                             this.model.storage.id = res;
                             this.selectedModel.storage.unshift(this.model.storage);
                         }
@@ -622,6 +645,7 @@
                             time_unit_id : "",
                         };
                         this.errors = {};
+                        this.audit.storage = true;
                     });
                 },
                 _verifyOperation() {
@@ -713,6 +737,7 @@
                         else this.selectedModel.operation.push(res);
                         this._resetOperation();
                         this.errors = {};
+                        this.audit.operation = true;
                     });
                 },
                 _verifyOperationItem(itemIndex){//验证作业费子项信息完整
@@ -775,8 +800,10 @@
                         this.model.express.items.forEach((item,i)=>{
                             item.id = res.details[i].id;
                         });
-                        if (this.model.express.id) this.selectedModel.express[this.model.express.index] = this.model.express;
-                        else{
+                        if (this.model.express.id){
+                            if (res.operation) this.model.express.id = res.id;
+                            this.selectedModel.express[this.model.express.index] = this.model.express;
+                        }else{
                             this.model.express.id = res.id;
                             this.selectedModel.express.unshift(this.model.express);
                         }
@@ -790,6 +817,7 @@
                         this.errors = {};
                         this.importError = [];
                         $(".selectpicker").filter('.express').selectpicker('val',[]);
+                        this.audit.express = true;
                     });
                 },
                 _verifyLogistic(){
@@ -815,8 +843,10 @@
                         this.model.logistic.items.forEach((item,i)=>{
                             item.id = res.details[i].id;
                         });
-                        if (this.model.logistic.id) this.selectedModel.logistic[this.model.logistic.index] = this.model.logistic;
-                        else {
+                        if (this.model.logistic.id){
+                            if (res.operation) this.model.logistic.id = res.id;
+                            this.selectedModel.logistic[this.model.logistic.index] = this.model.logistic;
+                        }else {
                             this.model.logistic.id = res.id;
                             this.selectedModel.logistic.unshift(this.model.logistic);
                         }
@@ -829,6 +859,7 @@
                         this.errors = {};
                         this.importError = [];
                         $(".selectpicker").filter('.logistic').selectpicker('val',[]);
+                        this.audit.logistic = true;
                     });
                 },
                 _verifyDirectLogistic(){
@@ -857,6 +888,7 @@
                         };
                         this.errors = {};
                         this.importError = [];
+                        this.audit.directLogistic = true;
                     });
                 },
                 //增加作业费特征子项
@@ -961,25 +993,6 @@
                         return "已更新特征";
                     },true);
                 },
-                /*//渲染作业费子项
-                _renderingOperationItem(index){
-                    let domId = "operation-"+index;
-                    let trId = "operation-tr-"+index;
-                    let itemId = "operation-item-"+index;
-                    let html = "<tr class='d-none' id='"+trId+"'><td></td><td colspan='5'>"+
-                        "<div id='"+itemId+"'><table class='table table-sm'>"+
-                        "<th>子策略</th><th>数量</th><th>单位</th><th>单价</th><th>特征</th></th>";
-                    this.selectedModel.operation[index].items.forEach(item=> {
-                        html = this._createOperationItemList(html,item.strategy,item.amount,this.poolMapping.units[item.unit_id],item.unit_price,item.featureFormat ? item.featureFormat : '');
-                    });
-                    html += "</table></div></td></tr>";
-                    $("#"+domId).after(html);
-                    $("#"+itemId).slideUp();
-                },
-                _createOperationItemList(html,strategy,amount,unit,unit_price,feature){
-                    html += "<tr><td>"+strategy+"</td><td>"+amount+"</td><td>"+unit+"</td><td>"+unit_price+"</td><td><div class='text-overflow-warp-100'>"+feature+"</div></td></tr>";
-                    return html;
-                },*/
                 //移入移出时更改长文本显示效果
                 textClass(event,isOver){
                     event = event.target.children[0];
@@ -1022,14 +1035,14 @@
                 //导入快递子项
                 importExpress(e){
                     let file=e.target.files[0];
+                    window.tempTip.setDuration(3000);
                     if (!file){
-                        tempTip.setDuration(3000);
-                        tempTip.show("未选择文件");
+                        window.tempTip.show("未选择文件");
                         return;
                     }
                     let formData = new FormData();
                     formData.append("file",file);
-                    axios.post('{{url('maintenance/priceModel/express/import')}}',formData,{
+                    window.axios.post('{{url('maintenance/priceModel/express/import')}}',formData,{
                         'Content-Type':'multipart/form-data'
                     }).then(res=>{
                             if (res.data.success) {
@@ -1041,15 +1054,13 @@
                                     if (unique)this.model.express.items.push(data);
                                 });
                                 this.importError = res.data.errors;
-                                tempTip.setDuration(3000);
-                                tempTip.showSuccess("导入成功!");
+                                window.tempTip.setDuration(2000);
+                                window.tempTip.showSuccess("导入成功!");
                                 return;
                             }
-                            tempTip.setDuration(3000);
-                            tempTip.show(res.data.data);
+                            window.tempTip.show(res.data.data);
                         }).catch(err=> {
-                        tempTip.setDuration(3000);
-                        tempTip.show("网络错误:"+err);
+                        window.tempTip.show("网络错误:"+err);
                     })
                 },
                 //物流详情列表modal
@@ -1391,6 +1402,7 @@
                     window.tempTip.confirm("您确定要删除仓储计费“"+item.name+"”吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelStorage')}}",{id:item.id},res=>{
                             this.$delete(this.selectedModel.storage,index);
+                            this.audit.storage = true;
                             return "删除“"+item.name+"”成功";
                         });
                     });
@@ -1400,6 +1412,7 @@
                     window.tempTip.confirm("您确定要删除作业计费“"+item.name+"”吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelOperation')}}",{id:item.id},res=>{
                             this.$delete(this.selectedModel.operation,index);
+                            this.audit.operation = true;
                             return "删除“"+item.name+"”成功";
                         });
                     });
@@ -1408,7 +1421,9 @@
                 deleteOperationItem(item,index,parentIndex){
                     window.tempTip.confirm("您确定要删除该作业子项吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelOperationItem')}}",{id:item.id},res=>{
-                            this.$delete(this.selectedModel.operation[parentIndex].items,index);
+                            if (res) this.$set(this.selectedModel.operation,parentIndex,this._overrideOperation(res));
+                            else this.$delete(this.selectedModel.operation[parentIndex].items,index);
+                            this.audit.operation = true;
                             return "删除成功";
                         });
                     });
@@ -1418,6 +1433,7 @@
                     window.tempTip.confirm("您确定要删除该快递计费“"+item.name+"”吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelExpress')}}",{id:item.id},res=>{
                             this.$delete(this.selectedModel.express,index);
+                            this.audit.express = true;
                             return "删除“"+item.name+"”成功";
                         });
                     });
@@ -1426,7 +1442,9 @@
                 deleteExpressItem(item,index,parentIndex){
                     window.tempTip.confirm("您确定要删除该快递计费子项吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelExpressItem')}}",{id:item.id},res=>{
-                            this.$delete(this.selectedModel.express[parentIndex].items,index);
+                            if (res) this.$set(this.selectedModel.express,parentIndex,this._overrideExpress(res));
+                            else this.$delete(this.selectedModel.express[parentIndex].items,index);
+                            this.audit.express = true;
                             return "删除成功";
                         });
                     });
@@ -1436,6 +1454,7 @@
                     window.tempTip.confirm("您确定要删除该物流计费“"+item.name+"”吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelLogistic')}}",{id:item.id},res=>{
                             this.$delete(this.selectedModel.logistic,index);
+                            this.audit.logistic = true;
                             return "删除“"+item.name+"”成功";
                         });
                     });
@@ -1444,7 +1463,9 @@
                 deleteLogisticItem(item,index,parentIndex){
                     window.tempTip.confirm("您确定要删除该物流计费子项吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelLogisticItem')}}",{id:item.id},res=>{
-                            this.$delete(this.selectedModel.logistic[parentIndex].items,index);
+                            if (res) this.$set(this.selectedModel.logistic,parentIndex,this._overrideLogistic(res));
+                            else this.$delete(this.selectedModel.logistic[parentIndex].items,index);
+                            this.audit.logistic = true;
                             return "删除成功";
                         });
                     });
@@ -1454,6 +1475,7 @@
                     window.tempTip.confirm("您确定要删除该直发车计费“"+item.name+"”吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelDirectLogistic')}}",{id:item.id},res=>{
                             this.selectedModel.directLogistic = {};
+                            this.audit.directLogistic = true;
                             return "删除“"+item.name+"”成功";
                         });
                     });
@@ -1462,7 +1484,9 @@
                 deleteDirectLogisticItem(item,index){
                     window.tempTip.confirm("您确定要删除该直发车计费子项吗?",()=>{
                         window.tempTip.postBasicRequest("{{url('maintenance/priceModel/apiDelDirectLogisticItem')}}",{id:item.id},res=>{
-                            this.$delete(this.selectedModel.directLogistic.items,index);
+                            if (res) this.$set(this.selectedModel,"directLogistic",this._overrideDirectLogistic(res));
+                            else this.$delete(this.selectedModel.directLogistic.items,index);
+                            this.audit.directLogistic = true;
                             return "删除成功";
                         });
                     });
@@ -1566,6 +1590,47 @@
                     this.$delete(this.model.operation.total_discount_price,index);
                     this.$delete(this.model.operation.discount_count,index);
                 },
+                //审核或恢复
+                auditOrRecoverModel(type,isAudit = true){
+                    let url = "{{url('maintenance/priceModel/auditOrRecoverModel')}}";
+                    let param = {owner_id:this.ownerTemp.id,type:type,isAudit:isAudit};
+                    window.tempTip.confirm("确定要"+(isAudit ? '审核' : '恢复')+"上次的全部操作吗?",()=>{
+                        window.tempTip.postBasicRequest(url,param,res=>{
+                            switch (type){
+                                case "storage":
+                                    this.selectedModel.storage = res;
+                                    break;
+                                case "operation":
+                                    this._loadOperation();
+                                    res.forEach(operation=>{operation = this._overrideOperation(operation);});
+                                    this.selectedModel.operation = res;
+                                    break;
+                                case "express":
+                                    this._loadExpress();
+                                    res.forEach((express,i)=>{
+                                        express = this._overrideExpress(express);
+                                        this.upList['express-item-'+i] = true;
+                                    });
+                                    this.selectedModel.express = res;
+                                    break;
+                                case "logistic":
+                                    this._loadLogistic();
+                                    res.forEach((logistic,i)=>{
+                                        logistic = this._overrideLogistic(logistic);
+                                        this.upList['logistic-item-'+i] = true;
+                                    });
+                                    this.selectedModel.logistic = res;
+                                    break;
+                                case "directLogistic":
+                                    this._loadDirectLogistic();
+                                    this.upList["directLogistic-item"] = true;
+                                    this.selectedModel.directLogistic = this._overrideDirectLogistic(res[0]);
+                                    break;
+                            }
+                            this.$set(this.audit,type,false);
+                        })
+                    })
+                },
             },
         });
     </script>

+ 3 - 3
resources/views/customer/project/index.blade.php

@@ -1,5 +1,5 @@
 @extends('layouts.app')
-@section('title')项目列表-客户管理@endsection
+@section('title')项目列表-项目管理@endsection
 
 @section('content')
     @component('customer.project.menu')@endcomponent
@@ -70,7 +70,7 @@
                     <td>@{{ owner.customer_name }}</td>
                     <td>@{{ owner.user_owner_group_name }}</td>
                     <td>@{{ owner.user_work_group_name }}</td>
-                    <td><b>@{{ owner.relevance.length }}</b>/5</td>
+                    <td><b>@{{owner.relevance.length}}</b>/5</td>
                     <td>@{{ owner.created_at }}</td>
                     <td>@{{ owner.customer_company_name }}</td>
                     <td>@{{ owner.is_activation }}</td>
@@ -98,7 +98,7 @@
                 owners : [
                     @foreach($owners as $owner)
                     {   id : "{{$owner->id}}",
-                        relevance:{!! $owner->relevance ?? [] !!},
+                        relevance:{!! $owner->relevance ?? "[]"  !!},
                         customer_name:"{{$owner->customer ? $owner->customer->name : ''}}",
                         //tax_rate  : "{{--{{$owner->tax_rate}}--}}",
                         name : "{{$owner->name}}",

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

@@ -4,15 +4,15 @@
     <div class="container-fluid nav3">
         <div class="card menu-third" >
             <ul class="nav nav-pills">
-                @can('客户管理-项目-面积')
+                @can('项目管理-项目-面积')
                     <li class="nav-item">
                         <a target="customer/project/area" class="nav-link" href="{{url('customer/project/area')}}" :class="{active:isActive('area',3)}">用仓盘点</a>
                     </li> @endcan
-                @can('客户管理-项目-查询')
+                @can('项目管理-项目-查询')
                 <li class="nav-item">
                     <a target="customer/project/index" class="nav-link" href="{{url('customer/project/index')}}" :class="{active:isActive('index',3)}">列表</a>
                 </li> @endcan
-                @can('客户管理-项目-查询')
+                @can('项目管理-项目-查询')
                 <li class="nav-item">
                     <a target="customer/project/create" class="nav-link" href="{{url('customer/project/create')}}" :class="{active:isActive('create',3)}">录入</a>
                 </li> @endcan

+ 45 - 15
resources/views/customer/project/part/_three.blade.php

@@ -1,9 +1,15 @@
 <div class="row">
     <div class="col-6" id="parent">
         <div class="card" id="storage-card">
-            <div class="card-header bg-light-info">
-                <span class="pull-left font-weight-bold cursor-pointer text-secondary" @click="show('storage')"><span class="fa fa-align-justify"></span>&nbsp;仓储</span>
-                <span class="pull-right small mb-0 text-secondary" v-if="selectedModel.storage.length>0">双击下方已添加内容可编辑</span>
+            <div class="card-header bg-light-info row">
+                <div class="col-3 pull-left font-weight-bold cursor-pointer text-secondary" @click="show('storage')"><span class="fa fa-align-justify"></span>&nbsp;仓储</div>
+                <div class="col-6 text-center">
+                    <div v-if="audit.storage">
+                        @can("项目管理-项目-计费模型-审核")<button class="btn btn-sm btn-success" type="button" @click="auditOrRecoverModel('storage')">审核</button>
+                        <button class="btn btn-sm btn-danger" type="button" @click="auditOrRecoverModel('storage',false)">恢复</button>@endcan
+                    </div>
+                </div>
+                <div class="col-3 pull-right small mb-0 text-secondary" v-if="selectedModel.storage.length>0">双击下方已添加内容可编辑</div>
             </div>
             <div class="card-body" id="storage">
                 <table class="table table-sm">
@@ -35,9 +41,15 @@
             </div>
         </div>
         <div class="card" id="operation-card">
-            <div class="card-header bg-light-info">
-                <span class="pull-left font-weight-bold cursor-pointer text-secondary" @click="show('operation')"><span class="fa fa-align-justify"></span>&nbsp;作业</span>
-                <span class="pull-right small mb-0 text-secondary" v-if="selectedModel.operation.length>0">双击下方已添加内容可编辑</span>
+            <div class="card-header bg-light-info row">
+                <div class="col-3 pull-left font-weight-bold cursor-pointer text-secondary" @click="show('operation')"><span class="fa fa-align-justify"></span>&nbsp;作业</div>
+                <div class="col-6 text-center">
+                    <div v-if="audit.operation">
+                        @can("项目管理-项目-计费模型-审核")<button class="btn btn-sm btn-success" type="button" @click="auditOrRecoverModel('operation')">审核</button>
+                        <button class="btn btn-sm btn-danger" type="button" @click="auditOrRecoverModel('operation',false)">恢复</button>@endcan
+                    </div>
+                </div>
+                <div class="col-3 pull-right small mb-0 text-secondary" v-if="selectedModel.operation.length>0">双击下方已添加内容可编辑</div>
             </div>
             <div class="card-body" id="operation">
                 <div class="container-fluid">
@@ -146,9 +158,15 @@
             </div>
         </div>
         <div class="card" id="express-card">
-            <div class="card-header bg-light-info">
-                <span class="pull-left font-weight-bold cursor-pointer text-secondary" @click="show('express')"><span class="fa fa-align-justify"></span>&nbsp;快递</span>
-                <span class="pull-right small mb-0 text-secondary" v-if="selectedModel.express.length>0">双击下方已添加内容可编辑</span>
+            <div class="card-header bg-light-info row">
+                <div class="col-3 pull-left font-weight-bold cursor-pointer text-secondary" @click="show('express')"><span class="fa fa-align-justify"></span>&nbsp;快递</div>
+                <div class="col-6 text-center">
+                    <div v-if="audit.express">
+                        @can("项目管理-项目-计费模型-审核")<button class="btn btn-sm btn-success" type="button" @click="auditOrRecoverModel('express')">审核</button>
+                        <button class="btn btn-sm btn-danger" type="button" @click="auditOrRecoverModel('express',false)">恢复</button>@endcan
+                    </div>
+                </div>
+                <div class="col-3 pull-right small mb-0 text-secondary" v-if="selectedModel.express.length>0">双击下方已添加内容可编辑</div>
             </div>
             <div class="card-body" id="express">
                 <table class="table table-sm">
@@ -204,9 +222,15 @@
             </div>
         </div>
         <div class="card" id="logistic-card">
-            <div class="card-header bg-light-info">
-                <span class="pull-left font-weight-bold cursor-pointer text-secondary" @click="show('logistic')"><span class="fa fa-align-justify"></span>&nbsp;物流</span>
-                <span class="pull-right small mb-0 text-secondary" v-if="selectedModel.logistic.length>0">双击下方已添加内容可编辑</span>
+            <div class="card-header bg-light-info row">
+                <div class="col-3 pull-left font-weight-bold cursor-pointer text-secondary" @click="show('logistic')"><span class="fa fa-align-justify"></span>&nbsp;物流</div>
+                <div class="col-6 text-center">
+                    <div v-if="audit.logistic">
+                        @can("项目管理-项目-计费模型-审核")<button class="btn btn-sm btn-success" type="button" @click="auditOrRecoverModel('logistic')">审核</button>
+                        <button class="btn btn-sm btn-danger" type="button" @click="auditOrRecoverModel('logistic',false)">恢复</button>@endcan
+                    </div>
+                </div>
+                <div class="col-3 pull-right small mb-0 text-secondary" v-if="selectedModel.logistic.length>0">双击下方已添加内容可编辑</div>
             </div>
             <div class="card-body" id="logistic">
                 <table class="table table-sm">
@@ -285,9 +309,15 @@
             </div>
         </div>
         <div class="card" id="directLogistic-card">
-            <div class="card-header bg-light-info">
-                <span class="pull-left font-weight-bold cursor-pointer text-secondary" @click="show('directLogistic')"><span class="fa fa-align-justify"></span>&nbsp;直发</span>
-                <span class="pull-right small mb-0 text-secondary" v-if="selectedModel.directLogistic.name">双击下方已添加内容可编辑</span>
+            <div class="card-header bg-light-info row">
+                <div class="col-3 pull-left font-weight-bold cursor-pointer text-secondary" @click="show('directLogistic')"><span class="fa fa-align-justify"></span>&nbsp;直发</div>
+                <div class="col-6 text-center">
+                    <div v-if="audit.directLogistic">
+                        @can("项目管理-项目-计费模型-审核")<button class="btn btn-sm btn-success" type="button" @click="auditOrRecoverModel('directLogistic')">审核</button>
+                        <button class="btn btn-sm btn-danger" type="button" @click="auditOrRecoverModel('directLogistic',false)">恢复</button>@endcan
+                    </div>
+                </div>
+                <div class="col-3 pull-right small mb-0 text-secondary" v-if="selectedModel.directLogistic.name">双击下方已添加内容可编辑</div>
             </div>
             <div class="card-body" id="directLogistic" @dblclick="editDirectLogistic()" style="cursor: pointer">
                 <div class="row">

+ 1 - 1
resources/views/finance/billConfirmation.blade.php

@@ -1,5 +1,5 @@
 @extends('layouts.app')
-@section('title')账单确认-客户管理@endsection
+@section('title')账单确认-项目管理@endsection
 
 @section('content')
     @component('finance.menu')@endcomponent

+ 1 - 1
resources/views/finance/instantBill.blade.php

@@ -1,5 +1,5 @@
 @extends('layouts.app')
-@section('title')即时账单-客户管理@endsection
+@section('title')即时账单-客户项目@endsection
 
 @section('content')
     @component('finance.menu')@endcomponent

+ 2 - 2
resources/views/layouts/menu.blade.php

@@ -37,11 +37,11 @@
                                     :class="{active:isActive('process',1)}">
                     <span class="fa fa-hand-scissors-o" style="color: #726e1b"></span>
                     二次加工管理</a></li> @endcan
-        @can('客户管理')
+        @can('项目管理')
             <li class="nav-item"><a href="{{url("customer/project/area")}}" class="nav-link" target="customer/project/area"
                                     :class="{active:isActive('customer',1)}">
                     <span class="fa fa-address-book-o" style="color: #72441b"></span>
-                    客户管理</a></li> @endcan
+                    项目管理</a></li> @endcan
         @can('结算管理')
             <li class="nav-item"><a href="{{url("finance/instantBill")}}" class="nav-link" target="finance/instantBill"
                                     :class="{active:isActive('finance',1)}">

+ 1 - 1
resources/views/maintenance/priceModel/operation/create.blade.php

@@ -198,7 +198,7 @@
             data:{
                 model:{
                     id: "{{isset($model) ? $model->id : ''}}",
-                    owner_id:{!! old('owner_id') ? json_encode(old('owner_id')) : (isset($model) ? json_encode(array_column($model->ownerPriceOperationOwners->toArray(),"id")) : '[]') !!},
+                    owner_id:{!! old('owner_id') ? json_encode(old('owner_id')) : (isset($model) ? json_encode(array_column($model->owners->toArray(),"id")) : '[]') !!},
                     operation_type:"{{old('operation_type') ?? (isset($model) ? $model->operation_type : '')}}",
                     strategy:"{{old('strategy') ?? (isset($model) ? $model->strategy : '')}}",
                     name:"{{old('name') ?? (isset($model) ? $model->name : '')}}",

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

@@ -151,7 +151,7 @@
                         totalPrice : "{{$model->total_price}}",
                         totalDiscountPrice : "{{$model->total_discount_price}}" ? "{{$model->total_discount_price}}".split(",") : ["/"],
                         createdAt : "{{$model->created_at}}",
-                        owners : {!! $model->ownerPriceOperationOwners !!},
+                        owners : {!! $model->owners !!},
                     },
                     @endforeach
                 ],

+ 1 - 1
resources/views/personnel/menu.blade.php

@@ -10,7 +10,7 @@
                 <li class="nav-item">
                     <a target="personnel/checking-in/createReplenishClock" class="nav-link" href="{{url('personnel/checking-in/createReplenishClock')}}" :class="{active:isActive('checking-in',2)}">打卡相关</a>
                 </li> @endcan
-            @can('客户管理-项目-报表')
+            @can('项目管理-项目-报表')
                 <li class="nav-item">
                     <a target="personnel/report" class="nav-link" href="{{url('personnel/report')}}" :class="{active:isActive('report',2)}">绩效</a>
                 </li> @endcan

+ 2 - 0
routes/web.php

@@ -174,6 +174,8 @@ Route::group(['prefix'=>'maintenance'],function(){
         Route::post('apiDelLogisticItem','PriceModelController@apiDelLogisticItem');
         Route::post('apiDelDirectLogistic','PriceModelController@apiDelDirectLogistic');
         Route::post('apiDelDirectLogisticItem','PriceModelController@apiDelDirectLogisticItem');
+        //审核或恢复计费模型
+        Route::post('auditOrRecoverModel','PriceModelController@auditOrRecoverModel');
     });
     Route::group(['prefix'=>'unit'],function(){
         Route::post('getUnits','UnitController@getUnits');

Деякі файли не було показано, через те що забагато файлів було змінено