Преглед изворни кода

客户管理页面完善,欠缺测试与物流快递表合并

Zhouzhendong пре 5 година
родитељ
комит
1e6e131719

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

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

+ 182 - 3
app/Http/Controllers/PriceModelController.php

@@ -3,9 +3,11 @@
 namespace App\Http\Controllers;
 
 use App\Imports\ExpressImport;
+use App\Imports\OwnerPriceDirectLogisticDetailImport;
 use App\Imports\OwnerPriceLogisticDetailImport;
 use App\Owner;
 use App\OwnerOutStorageRule;
+use App\OwnerPriceDirectLogistic;
 use App\OwnerPriceExpress;
 use App\OwnerPriceExpressProvince;
 use App\OwnerPriceLogistic;
@@ -591,7 +593,7 @@ class PriceModelController extends Controller
 
     public function expressExport($id)
     {
-        if(!Gate::allows('计费模型-物流-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        if(!Gate::allows('计费模型-快递-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
         $model = app("OwnerPriceExpressService")->find($id,[
             "owners","logistics","initialWeightUnit","additionalWeightUnit","details"=>function($query){
                 /** @var Builder $query */
@@ -634,6 +636,55 @@ class PriceModelController extends Controller
         return ["success"=>false,"data"=>"导入发生错误,数据无响应"];
     }
 
+    public function logisticExport($id)
+    {
+        if(!Gate::allows('计费模型-物流-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $model = app("OwnerPriceLogisticService")->find($id,[
+            "owners","logistics","unit","otherUnit","details"=>function($query){
+                /** @var Builder $query */
+                $query->with(["province","unit","city"]);
+            }]);
+        $row = ["客户","价格名称",
+            "单位一区间/".($model->unit ? $model->unit->name : ''),
+            "单位二区间/".($model->otherUnit ? $model->otherUnit->name : ''),
+            "提货费","燃油附加费","信息服务费","创建时间","承运商"];
+        $range = "";
+        foreach (explode(",",$model->unit_range) as $str){
+            $range .= $str."\r\n";
+        }
+        $otherRange = "";
+        foreach (explode(",",$model->other_unit_range) as $str){
+            $otherRange .= $str."\r\n";
+        }
+        $list = [[
+            implode(",",array_column($model->owners->toArray(),"name")),
+            $model->name,
+            $range,
+            $otherRange,
+            $model->pick_up_price,
+            $model->fuel_price,
+            $model->service_price,
+            $model->created_at,
+            implode(",",array_column($model->logistics->toArray(),"name")),
+        ],[
+            "单位","区间","省份","市","单价","送货费","起始计费","起始计数","费率"
+        ]];
+        foreach ($model->details as $detail){
+            $list[] = [
+                $detail->unit ? $detail->unit->name : '',
+                $detail->range,
+                $detail->province ? $detail->province->name : '',
+                $detail->city ? $detail->city->name : '',
+                $detail->unit_price,
+                $detail->delivery_fee,
+                $detail->initial_fee,
+                $detail->initial_amount,
+                $detail->rate ? $detail->rate."%" : '',
+            ];
+        }
+        return app(ExportService::class)->json($row,$list,"物流计费模型");
+    }
+
     public function logisticUpdateDetail(Request $request)
     {
         if(!Gate::allows('计费模型-物流-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
@@ -718,17 +769,145 @@ class PriceModelController extends Controller
 
     public function directLogisticIndex(){
         if(!Gate::allows('计费模型-直发-查询')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.directLogistic.index');
+        $models = app("OwnerPriceDirectLogisticService")->paginate();
+        return response()->view('maintenance.priceModel.directLogistic.index',compact("models"));
     }
 
     public function directLogisticCreate(){
         if(!Gate::allows('计费模型-直发-录入')){ return redirect('denied');  }
-        return response()->view('maintenance.priceModel.directLogistic.create');
+        $owners = app("OwnerService")->getSelection();
+        return response()->view('maintenance.priceModel.directLogistic.create',compact("owners"));
     }
 
     public function directLogisticStore(Request $request)
     {
         if(!Gate::allows('计费模型-直发-录入')){ return redirect('denied');  }
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $this->directLogisticValidator($request->input())->validate();
+        /** @var OwnerPriceDirectLogistic $model */
+        $model = app("OwnerPriceDirectLogisticService")->create([
+            "name" => $request->input("name"),
+            "base_km" => $request->input("base_km"),
+        ]);
+        $model->owners()->sync($request->input("owner_id"));
+        return response()->redirectTo("maintenance/priceModel/directLogistic")->with("successTip","创建“".$request->input("name")."”成功");
+    }
+
+    public function directLogisticDestroy($id)
+    {
+        if(!Gate::allows('计费模型-直发-删除')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $row = app("OwnerPriceDirectLogisticService")->destroy($id);
+        if ($row == 1)return ["success"=>true];
+        return ["success"=>false,"data"=>"影响了“".$row."”行"];
+    }
+
+    public function directLogisticEdit($id)
+    {
+        if(!Gate::allows('计费模型-直发-编辑')){ return redirect('denied');  }
+        $owners = app("OwnerService")->getSelection();
+        $model = app("OwnerPriceDirectLogisticService")->find($id)->append("owner_id");
+        return response()->view('maintenance.priceModel.directLogistic.create',compact("model","owners"));
+    }
+
+    public function directLogisticUpdate($id, Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-编辑')){ return redirect('denied');  }
+        $request->offsetSet("owner_id",explode(",",$request->input("owner_id")));
+        $this->directLogisticValidator($request->input(),$id)->validate();
+        app("OwnerPriceDirectLogisticService")->update(["id"=>$id],[
+            "name" => $request->input("name"),
+            "base_km" => $request->input("base_km"),
+        ]);
+        $model = new OwnerPriceDirectLogistic();
+        $model->id = $id;
+        $model->owners()->sync($request->input("owner_id"));
+        return response()->redirectTo("maintenance/priceModel/directLogistic")->with("successTip","修改“".$request->input("name")."”成功");
+    }
+
+    public function directLogisticGetDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-查询')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $model = new OwnerPriceDirectLogistic();
+        $model->id = $request->input("id");
+        $model->load(["details"=>function($query){
+            /** @var Builder $query */
+            $query->with("carType");
+        }]);
+        return ["success"=>true,"data"=>$model->details];
+    }
+
+    public function directLogisticImport(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-录入')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $fileSuffix=$request->file('file')->getClientOriginalExtension();
+        if ($fileSuffix != 'xlsx' && $fileSuffix != 'xls' && $fileSuffix != 'csv')
+            return ['success'=>false,'data'=>'不支持该文件类型'];
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
+        $fileSuffix = ucwords($fileSuffix);
+        $model = new OwnerPriceDirectLogistic();
+        $model->id = $request->input("id");
+        $model->load("details");
+        Excel::import(new OwnerPriceDirectLogisticDetailImport($model),$request->file('file')->path(),null,$fileSuffix);
+        if (Cache::has('directLogistic'))return Cache::pull('directLogistic');
+
+        return ["success"=>false,"data"=>"导入发生错误,数据无响应"];
+    }
+
+    public function directLogisticUpdateDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-编辑')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $detail = $request->input("detail");
+        if ($detail["id"]){
+            app('OwnerPriceDirectLogisticService')->updateDetail(["id"=>$detail["id"]],[
+                "base_fee" => $detail["base_fee"],
+                "additional_fee" => $detail["additional_fee"],
+            ]);
+        }else{
+            $row = app('OwnerPriceDirectLogisticService')->isExistDetail([
+                "owner_price_direct_logistic_id"=>$request->input("id"),
+                "car_type_id"=>$detail["car_type_id"],
+            ]);
+            if ($row>0)return ["success"=>false,"data"=>"已存在该计费模型"];
+            /** @var OwnerPriceExpressProvince $detail */
+            $detail = app('OwnerPriceDirectLogisticService')->createDetail([
+                "owner_price_direct_logistic_id"=>$request->input("id"),
+                "car_type_id"=>$detail["car_type_id"],
+                "base_fee" => $detail["base_fee"],
+                "additional_fee" => $detail["additional_fee"],
+            ]);
+            $detail->load("carType");
+        }
+        return ["success"=>true,"data"=>$detail];
+    }
+
+    public function directLogisticDestroyDetail(Request $request)
+    {
+        if(!Gate::allows('计费模型-直发-删除')){ return ["success"=>false,"data"=>"无权操作"];  }
+        $id = $request->input("id");
+        if (!$id)return ["success"=>false,"data"=>"非法参数"];
+        app("OwnerPriceDirectLogisticService")->destroyDetail($id);
+        return ["success"=>true];
+    }
+
+    private function directLogisticValidator(array $params, $id= null)
+    {
+        return Validator::make($params,[
+            'name'=>['required',$id?"unique:owner_price_direct_logistics,name,$id":'unique:owner_price_direct_logistics,name'],
+            'base_km'=>['required','numeric','min:0'],
+            'owner_id'=>[function ($attribute, $value, $fail)use($id) {
+                $owners = app("OwnerPriceDirectLogisticService")->getExistOwnerName($value,$id);
+                if ($owners)$fail("(".implode(',',$owners).') 已经绑定直发计费模型');
+            }],
+        ],[
+            'required'=>':attribute 为必填项',
+            'unique' => ':attribute 已存在',
+            'numeric' => ':attribute 必须为数字',
+            'min' => ':attribute 不得为负',
+        ],[
+            'name' =>"名称",
+            'base_km'  =>"起步公里数",
+        ]);
     }
 
 }

+ 1 - 1
app/Http/Controllers/TestController.php

@@ -93,7 +93,7 @@ class TestController extends Controller
     }
 
     public function test4(){
-        dd(Unit::query()->whereIn('name',[])->get());
+        dd(mb_strpos("续费(KM)","续1费"));
 
     }
 

+ 135 - 0
app/Imports/OwnerPriceDirectLogisticDetailImport.php

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

+ 2 - 1
app/Imports/OwnerPriceLogisticDetailImport.php

@@ -140,7 +140,7 @@ class OwnerPriceLogisticDetailImport implements ToCollection,WithHeadingRow
             $item["市"] = $cityMap[$item["市"]];
             $key = $item["计数单位"]."_".$item["计数区间"]."_".$item["省份"]."_".$item["市"];
             if (isset($existInsert[$key])){
-                $errors[] = "第“".($index+2)."”行重复条目";
+                $errors[] = "第“".($index+2)."”行与第“".$existInsert[$key]."”行重复";
                 continue;
             }
 
@@ -169,6 +169,7 @@ class OwnerPriceLogisticDetailImport implements ToCollection,WithHeadingRow
                 "rate" => $item["费率"],
                 "created_at" => $date,
             ];
+            $existInsert[$key] = $index+2;
         }
         if (count($update) > 1){
             app(BatchUpdateService::class)->batchUpdate("owner_price_logistic_details",$update);

+ 11 - 1
app/OwnerPriceDirectLogistic.php

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

+ 2 - 0
app/Providers/AppServiceProvider.php

@@ -37,6 +37,7 @@ use App\Services\OwnerAreaReportService;
 use App\Services\OwnerBillReportService;
 use App\Services\OwnerFeeDetailService;
 use App\Services\OwnerOutStorageRuleService;
+use App\Services\OwnerPriceDirectLogisticService;
 use App\Services\OwnerPriceExpressService;
 use App\Services\OwnerPriceLogisticService;
 use App\Services\OwnerPriceOperationService;
@@ -157,6 +158,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerBillReportService',OwnerBillReportService::class);
         app()->singleton('OwnerPriceExpressService',OwnerPriceExpressService::class);
         app()->singleton('OwnerPriceLogisticService',OwnerPriceLogisticService::class);
+        app()->singleton('OwnerPriceDirectLogisticService',OwnerPriceDirectLogisticService::class);
 
         $this->loadingOrderModuleService();
         $this->loadingBasedModuleService();

+ 83 - 0
app/Services/OwnerPriceDirectLogisticService.php

@@ -0,0 +1,83 @@
+<?php 
+
+namespace App\Services; 
+
+use App\Owner;
+use App\OwnerPriceDirectLogistic;
+use App\OwnerPriceDirectLogisticCar;
+use Illuminate\Support\Facades\DB;
+
+Class OwnerPriceDirectLogisticService
+{ 
+    public function paginate()
+    {
+        return OwnerPriceDirectLogistic::query()->with("owners")->paginate(50);
+    }
+
+    public function create(array $params)
+    {
+        return OwnerPriceDirectLogistic::query()->create($params);
+    }
+
+    public function destroy($id)
+    {
+        OwnerPriceDirectLogisticCar::query()->where("owner_price_direct_logistic_id",$id)->delete();
+        DB::table("owner_price_direct_logistic_owner")->where("owner_price_direct_logistic_id",$id)->delete();
+        return OwnerPriceDirectLogistic::destroy($id);
+    }
+
+    public function find($id)
+    {
+        return OwnerPriceDirectLogistic::query()->find($id);
+    }
+
+    public function update(array $params, array $values)
+    {
+        $query = OwnerPriceDirectLogistic::query();
+        foreach ($params as $column=>$param){
+            $query->where($column,$param);
+        }
+        return $query->update($values);
+    }
+
+    public function updateDetail(array $params, array $values)
+    {
+        $query = OwnerPriceDirectLogisticCar::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->update($values);
+    }
+
+    public function isExistDetail(array $params)
+    {
+        $query = OwnerPriceDirectLogisticCar::query();
+        foreach ($params as $column => $param){
+            $query->where($column,$param);
+        }
+        return $query->count();
+    }
+
+    public function createDetail(array $params)
+    {
+        return OwnerPriceDirectLogisticCar::query()->create($params);
+    }
+
+    public function destroyDetail($id)
+    {
+        return OwnerPriceDirectLogisticCar::destroy($id);
+    }
+
+    public function getExistOwnerName($owner_id, $id) :array
+    {
+        if (!is_array($owner_id))$owner_id = [$owner_id];
+        $owners = Owner::query()->withCount(["ownerPriceDirectLogistics"=>function($query)use($id){
+            if ($id)$query->where("id","!=",$id);
+        }])->whereIn("id",$owner_id)->get();
+        $arr = [];
+        foreach ($owners as $owner){
+            if ($owner->owner_price_direct_logistics_count > 0)$arr[] = $owner->name;
+        }
+        return $arr;
+    }
+}

+ 2 - 2
app/Services/OwnerPriceLogisticService.php

@@ -17,9 +17,9 @@ Class OwnerPriceLogisticService
         return OwnerPriceLogistic::query()->create($params);
     }
 
-    public function find($id)
+    public function find($id, $withs=[])
     {
-        return OwnerPriceLogistic::query()->find($id);
+        return OwnerPriceLogistic::query()->with($withs)->find($id);
     }
 
     public function update(array $params, array $values)

+ 69 - 0
resources/views/maintenance/priceModel/directLogistic/_detailModal.blade.php

@@ -0,0 +1,69 @@
+<div class="modal fade" tabindex="-1" role="dialog" id="detailModal" v-if="models[index]">
+    <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
+        <div class="modal-content">
+            <div class="modal-header">
+                <div class="row w-100">
+                    <input id="file" type="file" style="display:none" accept=".csv, .xlsx, .xls" @change="importDetail($event)"/>
+                    @can("计费模型-直发-录入")<button type="button" class="btn btn-sm btn-outline-info col-1" @click="selectFile()">导入</button>@endcan
+                    <div class="font-weight-bolder offset-3">“<label class="text-primary">@{{ models[index].name }}</label>”物流收费标准</div>
+                </div>
+            </div>
+            <div class="modal-body">
+                <div class="w-100 text-center mb-1" v-if="errors.length > 0">
+                    <button class="btn btn-sm btn-danger mb-1" @click="isShowError = true" v-if="!isShowError">@{{ errors.length }}条错误,点击展开</button>
+                    <button class="btn btn-sm btn-dark mb-1" @click="isShowError = false" v-else>收起错误展示</button>
+                    <div v-if="isShowError" class="container-fluid text-danger font-weight-bolder">
+                        <div class="row text-left">
+                            <div class="col-6" v-for="error in errors">@{{ error }}</div>
+                        </div>
+                    </div>
+                </div>
+                <div class="w-100 text-primary text-center mt-0" v-else>
+                    <div class="small"><b class="text-dark font-weight-bold">导入导出表头示例:</b>车型,起步费,续费(包含续费即可,不限制全称)</div>
+                </div>
+                <table class="table table-sm table-bordered">
+                    <tr class="text-success">
+                        <th>操作</th>
+                        <th>车型</th>
+                        <th>起步费</th>
+                        <th>续费(元/KM)</th>
+                        <th>操作</th>
+                    </tr>
+                    <tr v-for="(detail,i) in details[models[index].id]">
+                        <td>
+                            <div v-if="detail.edit">
+                                <button type="button" class="btn btn-sm btn-success" @click="submitDetail(detail)">确定</button>
+                                <button type="button" class="btn btn-sm btn-danger" @click="delDetail(detail,i)">取消</button>
+                            </div>
+                            <div v-else>
+                                @can("计费模型-直发-录入")<button type="button" class="btn btn-sm btn-outline-info" @click="addDetail()" v-if="i == 0">新增</button>@endcan
+                                @can("计费模型-直发-编辑")<button type="button" class="btn btn-sm btn-outline-primary" v-if="detail.id" @click="updateDetail(detail)">修改</button>@endcan
+                            </div>
+                        </td>
+                        <td>
+                            <label v-if="detail.edit && !detail.id">
+                                <select class="form-control form-control-sm col-6" v-model="detail.car_type_id" style="min-width: 80px">
+                                    <option v-for="car in carTypes" :value="car.id">@{{ car.name }}</option>
+                                </select>
+                            </label>
+                            <label v-else>@{{ detail.car_type ? detail.car_type.name : '' }}</label>
+                        </td>
+                        <td>
+                            <label v-if="detail.edit"><input type="number" min="0" step="0.001" class="form-control form-control-sm"
+                                     :id="'base_fee-'+detail.id" v-model="detail.base_fee" :data="detail.base_fee"></label>
+                            <label v-else>@{{ detail.base_fee }}</label>
+                        </td>
+                        <td>
+                            <label v-if="detail.edit"><input type="number" min="0" step="0.001" class="form-control form-control-sm"
+                                     :id="'additional_fee-'+detail.id"  v-model="detail.additional_fee" :data="detail.additional_fee"></label>
+                            <label v-else>@{{ detail.additional_fee }}</label>
+                        </td>
+                        <td>
+                            @can("计费模型-直发-编辑")<button type="button" class="btn btn-sm btn-outline-danger" @click="deletePriceModel(detail.id,i)" v-if="detail.id">删</button>@endcan
+                        </td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+    </div>
+</div>

+ 23 - 0
resources/views/maintenance/priceModel/directLogistic/create.blade.php

@@ -19,11 +19,28 @@
                 <label for="name" class="col-2"><b class="text-danger">* </b>价格名称</label>
                 <input id="name" v-model="model.name" type="text" name="name" required class="col-6 form-control"
                        :class="errors.name ? 'is-invalid' : ''">
+                <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.name">
+                    <strong>@{{ errors.name[0] }}</strong>
+                </span>
             </div>
             <div class="row mt-3">
                 <label for="base_km" class="col-2"><b class="text-danger">* </b>起步公里数</label>
                 <input id="base_km" v-model="model.base_km" type="number" min="0" step="1.00" name="base_km" class="col-3 form-control" required
                        :class="errors.base_km ? 'is-invalid' : ''">
+                <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.base_km">
+                    <strong>@{{ errors.base_km[0] }}</strong>
+                </span>
+            </div>
+            <div class="row mt-3">
+                <label class="col-2" for="owner_id">项目</label>
+                <select id="owner_id" class="selectpicker" multiple data-live-search="true" title="项目(多选)"
+                        v-model="model.owner_id" :class="errors.owner_id ? 'is-invalid' : ''">
+                    <option v-for="owner in owners" :value="owner.id">@{{ owner.name }}</option>
+                </select>
+                <span class="invalid-feedback mt-0 offset-2" role="alert" v-if="errors.owner_id">
+                    <strong>@{{ errors.owner_id[0] }}</strong>
+                </span>
+                <label hidden><input name="owner_id" type="text" :value="model.owner_id"></label>
             </div>
             <div class="row mt-3 offset-1">
                 <button type="submit" class="btn btn-success col-7">提交</button>
@@ -39,9 +56,15 @@
             data:{
                 model:{
                     id: "{{isset($model) ? $model->id : ''}}",
+                    owner_id:{!! old('owner_id') ? json_encode(old('owner_id')) : (isset($model) ? json_encode($model->owner_id) : '[]') !!},
                     name:"{{old('name') ?? (isset($model) ? $model->name : '')}}",
                     base_km:"{{old('base_km') ?? (isset($model) ? $model->base_km : '')}}",
                 },
+                owners:[
+                    @foreach($owners as $owner)
+                    {id:"{{$owner->id}}",name:"{{$owner->name}}"},
+                    @endforeach
+                ],
                 errors:{!! $errors !!},
             },
         });

+ 198 - 3
resources/views/maintenance/priceModel/directLogistic/index.blade.php

@@ -7,17 +7,35 @@
         @component('maintenance.priceModel.directLogistic.menu')@endcomponent
     </div>
     <div class="container-fluid mt-2" id="container">
+        @include("maintenance.priceModel.directLogistic._detailModal")
+        @if(Session::has('successTip'))
+            <div class="alert alert-success h1">{{Session::get('successTip')}}</div>
+        @endif
         <table class="table table-hover table-striped text-nowrap">
             <tr>
                 <th>序号</th>
                 <th>操作</th>
                 <th>价格名称</th>
+                <th>项目</th>
                 <th>起步公里数</th>
                 <th>录入时间</th>
                 <th>操作</th>
             </tr>
-            <tr v-for="model in models">
-                <td></td>
+            <tr v-for="(model,i) in models">
+                <td>@{{ i+1 }}</td>
+                <td>
+                    <button class="btn btn-sm btn-info" @click="showDetailModal(model,i)">维护详情</button>
+                </td>
+                <td>@{{ model.name }}</td>
+                <td>
+                    <small v-for="owner in model.owners" class="font-weight-bold">@{{ owner.name }}<br></small>
+                </td>
+                <td>@{{ model.baseKm }}</td>
+                <td>@{{ model.createdAt }}</td>
+                <td>
+                    @can("计费模型-直发-编辑")<button type="button" class="btn btn-sm btn-outline-info" @click="edit(model.id)">编辑</button>@endcan
+                    @can("计费模型-直发-删除")<button type="button" class="btn btn-sm btn-outline-danger" @click="deleteModel(model,i)">删除</button>@endcan
+                </td>
             </tr>
         </table>
     </div>
@@ -28,7 +46,184 @@
         new Vue({
             el:"#container",
             data:{
-                models : [],
+                models : [
+                    @foreach($models as $model)
+                    {id:"{{$model->id}}",name:"{{$model->name}}",baseKm:"{{$model->base_km}}",createdAt:"{{$model->created_at}}",owners:{!! $model->owners !!}},
+                    @endforeach
+                ],
+                index:"",
+                carTypes : null,
+                errors:{!! $errors !!},
+                isShowError : false,
+                details : [],
+            },
+            methods:{
+                _dataReady(){
+                    if (this.carTypes === null){
+                        window.axios.post("{{url('maintenance/carType/get')}}")
+                            .then(res=>{
+                                this.carTypes = res.data;
+                                this.$forceUpdate();
+                            }).catch(err=>{
+                            window.tempTip.setDuration(3000);
+                            window.tempTip.setIndex(1099);
+                            window.tempTip.show("网络错误:"+err);
+                        });
+                    }
+                },
+                showDetailModal(model,index){
+                    this._dataReady();
+                    this.index = index;
+                    if (this.details[model.id]){
+                        $("#detailModal").modal("show");
+                        return;
+                    }
+                    window.axios.post("{{url('maintenance/priceModel/directLogistic/getDetail')}}", {id:model.id})
+                        .then(res=>{
+                            if (res.data.success){
+                                this.details[model.id] = res.data.data;
+                                this.$forceUpdate();
+                                $("#detailModal").modal("show");
+                                return;
+                            }
+                            window.tempTip.setDuration(3000);
+                            window.tempTip.show(res.data.data);
+                        }).catch(err=>{
+                        window.tempTip.setDuration(3000);
+                        window.tempTip.show("网络错误:"+err);
+                    });
+                },
+                edit(id){
+                    window.location.href = "{{url('maintenance/priceModel/directLogistic')}}/"+id+"/edit";
+                },
+                deleteModel(model,index){
+                    window.tempTip.confirm("确定要删除“"+model.name+"”吗?",()=>{
+                        window.axios.delete('{{url('maintenance/priceModel/directLogistic')}}/'+model.id)
+                            .then(res=>{
+                                if (res.data.success){
+                                    this.$delete(this.models,index);
+                                    tempTip.setDuration(2000);
+                                    tempTip.showSuccess("删除"+model.name+"成功");
+                                    return;
+                                }
+                                tempTip.setDuration(3000);
+                                tempTip.show(res.data.data);
+                            }).catch(err=> {
+                            tempTip.setDuration(3000);
+                            tempTip.show("网络错误:"+err);
+                        })
+                    });
+                },
+                selectFile(){
+                    $("#file").click();
+                },
+                importDetail(e){
+                    let file=e.target.files[0];
+                    if (!file){
+                        tempTip.setDuration(3000);
+                        tempTip.setIndex(1099);
+                        tempTip.show("未选择文件");
+                        return;
+                    }
+                    let id = this.models[this.index].id;
+                    let formData = new FormData();
+                    formData.append("file",file);
+                    formData.append("id",id);
+                    window.tempTip.setIndex(1099);
+                    window.tempTip.setDuration(9999);
+                    window.tempTip.waitingTip("执行中,请耐心等候......");
+                    axios.post('{{url('maintenance/priceModel/directLogistic/import')}}',formData,{
+                        'Content-Type':'multipart/form-data'
+                    })
+                        .then(res=>{
+                            if (res.data.success) {
+                                this.details[id] = res.data.data;
+                                this.errors = res.data.errors;
+                                tempTip.cancelWaitingTip();
+                                tempTip.setDuration(2000);
+                                tempTip.showSuccess("导入成功!");
+                                return;
+                            }
+                            tempTip.cancelWaitingTip();
+                            tempTip.setDuration(3000);
+                            tempTip.show(res.data.data);
+                        }).catch(err=> {
+                        tempTip.cancelWaitingTip();
+                        tempTip.setDuration(3000);
+                        tempTip.show("网络错误:"+err);
+                    })
+                },
+                addDetail(){
+                    this._dataReady();
+                    this.details[this.models[this.index].id].unshift({
+                        "id" : "",
+                        "car_type_id" : "",
+                        "base_fee" : "",
+                        "additional_fee" : "",
+                        "edit" : true,
+                    });
+                    this.$forceUpdate();
+                },
+                delDetail(detail,index){
+                    if (detail.id){
+                        detail.base_fee = $("#base_fee-"+detail.id).attr('data');
+                        detail.additional_fee = $("#additional_fee-"+detail.id).attr('data');
+                        detail.edit = false;
+                    }else{
+                        this.$delete(this.details[this.models[this.index].id],index);
+                    }
+                    this.$forceUpdate();
+                },
+                updateDetail(detail){
+                    detail["edit"] = true;
+                    this.$forceUpdate();
+                },
+                submitDetail(detail){
+                    tempTip.setIndex(1099);
+                    window.axios.post('{{url('maintenance/priceModel/directLogistic/updateDetail')}}',{id:this.models[this.index].id,detail:detail})
+                        .then(res=>{
+                            if (res.data.success) {
+                                tempTip.setDuration(2000);
+                                if (detail.id){
+                                    tempTip.showSuccess("修改成功");
+                                }else{
+                                    detail.id = res.data.data.id;
+                                    detail.car_type = res.data.data.car_type;
+                                    tempTip.showSuccess("新增成功");
+                                }
+                                detail.edit = false;
+                                this.$forceUpdate();
+                                return;
+                            }
+                            tempTip.setDuration(3000);
+                            tempTip.show(res.data.data);
+                        }).catch(err=> {
+                        tempTip.setDuration(3000);
+                        tempTip.setIndex(1099);
+                        tempTip.show("网络错误:"+err);
+                    })
+                },
+                deletePriceModel(id,index){
+                    window.tempTip.setIndex(1099);
+                    window.tempTip.confirm("确定要删除该车型计费模型吗?",()=>{
+                        window.axios.post('{{url('maintenance/priceModel/directLogistic/destroyDetail')}}',{id:id})
+                            .then(res=>{
+                                if (res.data.success){
+                                    this.$delete(this.details[this.models[this.index].id],index);
+                                    tempTip.setDuration(2000);
+                                    tempTip.showSuccess("删除成功");
+                                    this.$forceUpdate();
+                                    return;
+                                }
+                                tempTip.setDuration(3000);
+                                tempTip.show(res.data.data);
+                            }).catch(err=> {
+                            tempTip.setDuration(3000);
+                            tempTip.setIndex(1099);
+                            tempTip.show("网络错误:"+err);
+                        })
+                    });
+                },
             },
         });
     </script>

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

@@ -1,5 +1,5 @@
 @extends('layouts.app')
-@section('title')计费模型-快递计费@endsection
+@section('title')计费模型-物流计费@endsection
 
 @section('content')
     <div id="nav2">

+ 3 - 3
resources/views/maintenance/priceModel/logistic/_detailModal.blade.php

@@ -5,7 +5,7 @@
                 <div class="row w-100">
                     <input id="file" type="file" style="display:none" accept=".csv, .xlsx, .xls" @change="importDetail($event)"/>
                     @can("计费模型-物流-录入")<button type="button" class="btn btn-sm btn-outline-info col-1" @click="selectFile()">导入</button>@endcan
-                    <button type="button" class="btn btn-sm btn-outline-dark col-1">导出</button>
+                    <button type="button" class="btn btn-sm btn-outline-dark col-1" @click="exportDetail()">导出</button>
                     <div class="font-weight-bolder offset-3">“<label class="text-primary">@{{ models[index].name }}</label>”物流收费标准</div>
                 </div>
             </div>
@@ -43,8 +43,8 @@
                                 <button type="button" class="btn btn-sm btn-danger" @click="delDetail(detail,i)">取消</button>
                             </div>
                             <div v-else>
-                                @can("计费模型-作业-录入")<button type="button" class="btn btn-sm btn-outline-info" @click="addDetail()" v-if="i == 0">新增</button>@endcan
-                                @can("计费模型-作业-编辑")<button type="button" class="btn btn-sm btn-outline-primary" v-if="detail.id" @click="updateDetail(detail)">修改</button>@endcan
+                                @can("计费模型-物流-录入")<button type="button" class="btn btn-sm btn-outline-info" @click="addDetail()" v-if="i == 0">新增</button>@endcan
+                                @can("计费模型-物流-编辑")<button type="button" class="btn btn-sm btn-outline-primary" v-if="detail.id" @click="updateDetail(detail)">修改</button>@endcan
                             </div>
                         </td>
                         <td>

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

@@ -298,6 +298,9 @@
                         })
                     });
                 },
+                exportDetail(){
+                    window.open("{{url('maintenance/priceModel/logistic/export')}}/"+this.models[this.index].id);
+                }
             },
         });
     </script>

+ 8 - 0
routes/web.php

@@ -128,6 +128,7 @@ Route::group(['prefix'=>'maintenance'],function(){
             Route::post('import','PriceModelController@logisticImport');
             Route::post('updateDetail','PriceModelController@logisticUpdateDetail');
             Route::post('destroyDetail','PriceModelController@logisticDestroyDetail');
+            Route::get('export/{id}','PriceModelController@logisticExport');
         });
         Route::get('logistic','PriceModelController@logisticIndex');
         Route::post('logistic','PriceModelController@logisticStore');
@@ -137,6 +138,10 @@ Route::group(['prefix'=>'maintenance'],function(){
             Route::delete('{id}','PriceModelController@directLogisticDestroy');
             Route::get('{id}/edit','PriceModelController@directLogisticEdit');
             Route::post('{id}/edit','PriceModelController@directLogisticUpdate');
+            Route::post('getDetail','PriceModelController@directLogisticGetDetail');
+            Route::post('import','PriceModelController@directLogisticImport');
+            Route::post('updateDetail','PriceModelController@directLogisticUpdateDetail');
+            Route::post('destroyDetail','PriceModelController@directLogisticDestroyDetail');
         });
         Route::get('directLogistic','PriceModelController@directLogisticIndex');
         Route::post('directLogistic','PriceModelController@directLogisticStore');
@@ -150,6 +155,9 @@ Route::group(['prefix'=>'maintenance'],function(){
     Route::group(['prefix'=>'city'],function(){
         Route::post('get','CitiesController@get');
     });
+    Route::group(['prefix'=>'carType'],function (){
+        Route::post('get','CarTypesController@get');
+    });
 
     Route::get('syncRedisLogs','LogController@syncRedisLogs');
     Route::resource('log', 'LogController');

+ 0 - 3
serves/excelExportGo/logs/2020-10-20.log

@@ -1,3 +0,0 @@
-
-[ERROR]   10:07:43
-   /api/controller/controller.go:184   称重统计数据json解析失败!

+ 0 - 5
serves/excelExportGo/logs/2020-11-04.log

@@ -1,5 +0,0 @@
-
-[ERROR]   15:26:32
-   /orm/query.go:11   SQL执行错误!(select owner_fee_details.*,(work_fee+logistic_fee) total, owners.name owner_name, customers.name customer_name, shops.name shop_name, process_methods.name process_method_name, logistics.name logistic_name from `owner_fee_details` left join `owners` on `owner_fee_details`.`owner_id` = `owners`.`id` left join `customers` on `owners`.`customer_id` = `customers`.`id` left join `shops` on `owner_fee_details`.`shop_id` = `shops`.`id` left join `process_methods` on `owner_fee_details`.`process_method_id` = `process_methods`.`id` left join `logistics` on `owner_fee_details`.`logistic_id` = `logistics`.`id` where `process_id` = '3,4' order by `id` desc)
-[ERROR]   15:28:59
-   /orm/query.go:11   SQL执行错误!(select owner_fee_details.*,(work_fee+logistic_fee) total, owners.name owner_name, customers.name customer_name, shops.name shop_name, process_methods.name process_method_name, logistics.name logistic_name from `owner_fee_details` left join `owners` on `owner_fee_details`.`owner_id` = `owners`.`id` left join `customers` on `owners`.`customer_id` = `customers`.`id` left join `shops` on `owner_fee_details`.`shop_id` = `shops`.`id` left join `process_methods` on `owner_fee_details`.`process_method_id` = `process_methods`.`id` left join `logistics` on `owner_fee_details`.`logistic_id` = `logistics`.`id` where `id` in ('3', '4') order by `id` desc)

+ 0 - 7
serves/excelExportGo/logs/2020-11-09.log

@@ -1,7 +0,0 @@
-
-[ERROR]   09:50:12
-   /orm/query.go:11   SQL执行错误!(select s_o_p.logistic_number, s_o_p_c.amount s_o_p_c_amount, s_c.sku s_c_sku,s_c.name s_c_name, order_issues.id order_issue_id from `order_packages` as `s_o_p` left join `order_package_commodities` as `s_o_p_c` on `s_o_p_c`.`order_package_id` = `s_o_p`.`id` left join `commodities` as `s_c` on `s_o_p_c`.`commodity_id` = `s_c`.`id` left join `order_issues` on `s_o_p`.`order_id` = `order_issues`.`second_order_id` WHERE s_o_p.client_code IN (BSCK2020110800433-1))
-[ERROR]   09:55:24
-   /orm/query.go:11   SQL执行错误!(select s_o_p.logistic_number, s_o_p_c.amount s_o_p_c_amount, s_c.sku s_c_sku,s_c.name s_c_name, order_issues.id order_issue_id from `order_packages` as `s_o_p` left join `orders` as `o_d` on `s_o_p`.`order_id` = `o_d`.`id` left join `order_package_commodities` as `s_o_p_c` on `s_o_p_c`.`order_package_id` = `s_o_p`.`id` left join `commodities` as `s_c` on `s_o_p_c`.`commodity_id` = `s_c`.`id` left join `order_issues` on `s_o_p`.`order_id` = `order_issues`.`second_order_id` WHERE o_d.client_code IN (BSCK2020110800433-1))
-[ERROR]   13:08:51
-   /orm/query.go:11   SQL执行错误!(select rejected_bill_items.remark,rejected_bill_items.amount rejected_bill_amount,rejected_bill_items.name_goods,rejected_bill_items.barcode_goods, order_issues.id order_issue_id from `rejected_bill_items` left join `order_issues` on `rejected_bill_items`.`logistic_number_return` = `order_issues`.`logistic_number_return` WHERE rejected_bill_items.logistic_number_return IN ('75404377502519'))

+ 0 - 2
serves/excelExportGo/orm/query.go

@@ -19,11 +19,9 @@ func query(sqlStr string,db *sql.DB)(list []map[string]string) {
 	values := make([]sql.RawBytes, length)
 	//保存的是values的内存地址
 	pointer := make([]interface{}, length)
-	//
 	for i := 0; i < length; i++ {
 		pointer[i] = &values[i]
 	}
-	//
 	for rows.Next() {
 		//把参数展开,把每一行的值存到指定的内存地址去,循环覆盖,values也就跟着被赋值了
 		err := rows.Scan(pointer...)