Przeglądaj źródła

运费计算:BUG修复

Zhouzhendong 5 lat temu
rodzic
commit
7dfd2db02f

+ 2 - 0
app/DeliveryAppointment.php

@@ -2,6 +2,7 @@
 
 namespace App;
 
+use App\Traits\ModelTimeFormat;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
@@ -9,6 +10,7 @@ use App\Traits\ModelLogChanging;
 class DeliveryAppointment extends Model
 {
     use ModelLogChanging;
+    use ModelTimeFormat;
 
     protected $fillable=[
         "user_id",

+ 86 - 1
app/Http/Controllers/DeliveryAppointmentController.php

@@ -9,12 +9,15 @@ use App\DeliveryAppointment;
 use App\DeliveryAppointmentCar;
 use App\DeliveryAppointmentDetail;
 use App\Imports\AppointmentDetail;
+use App\Services\common\ExportService;
+use App\Services\common\QueryService;
 use App\Warehouse;
 use Carbon\Carbon;
 use Carbon\CarbonPeriod;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Validator;
 
 class DeliveryAppointmentController extends Controller
@@ -23,11 +26,18 @@ class DeliveryAppointmentController extends Controller
 
     public function list()
     {
-        $owners = app("UserService")->getPermittingOwnerIds(Auth::id());
+        if(!Gate::allows('入库管理-客户预约-预约管理')){ return view("exception.authority");  }
+        $list = app("DeliveryAppointmentService")->query(request()->input())
+            ->paginate(request("paginate") ?? 50);
+
+        $warehouses = Warehouse::query()->select("id","name")->get();
+        $owners = app("OwnerService")->getIntersectPermitting();
+        return view("store.deliveryAppointment.list",compact("list","warehouses","owners"));
     }
 
     public function appointment()
     {
+        if(!Gate::allows('入库管理-客户预约-预约')){ return view("exception.authority");  }
         $owners = app("OwnerService")->getIntersectPermitting();
         $cars = CarType::query()->get();
         $warehouses = Warehouse::query()->select("id","name")->get();
@@ -45,6 +55,7 @@ class DeliveryAppointmentController extends Controller
      */
     public function getCapacity()
     {
+        $this->gate("入库管理-客户预约-预约");
         $model = request("model");
         $errors = $this->appointmentValidator($model)->errors();
         if (count($errors)>0)$this->success(["errors"=>$errors]);
@@ -88,6 +99,7 @@ class DeliveryAppointmentController extends Controller
      */
     public function submitAppointment()
     {
+        $this->gate("入库管理-客户预约-预约");
         $model = request("model");
         $selectDate = request("date");
         $details = request("details");
@@ -191,6 +203,7 @@ class DeliveryAppointmentController extends Controller
      */
     public function showAppointmentInfo()
     {
+        if(!Gate::allows('入库管理-客户预约-预约')){ return view("exception.authority");  }
         $key = request("k");
         $len = strlen($key);
         $id = substr($key,5,$len-32);
@@ -202,4 +215,76 @@ class DeliveryAppointmentController extends Controller
         if (!$appointment || $appointment->user_id != Auth::id())return view("exception.404");
         return view("store.deliveryAppointment.success",compact("appointment"));
     }
+
+    /**
+     *  取消预约
+     */
+    public function cancel()
+    {
+        $this->gate("入库管理-客户预约-预约");
+        $id = request("id");
+        if (!$id)$this->error("非法参数");
+        DeliveryAppointment::query()->where("status",0)->where("id",$id)->update(["status"=>1]);
+        $this->success(1);
+    }
+
+    /**
+     * 导出
+     */
+    public function export()
+    {
+        if(!Gate::allows('入库管理-客户预约-预约管理')){ return view("exception.authority");  }
+        if (request("checkAllSign")){
+            $params = request()->input();
+            unset($params["checkAllSign"]);
+            $query = app("DeliveryAppointmentService")->query($params);
+        }else $query = app("DeliveryAppointmentService")->query(["id"=>request("id")]);
+        /** @var Builder $query */
+        $list = $query->with(["owner","warehouse"])->get();
+        $row = ["状态","货主","预约时间","仓库","预约号","车牌号","车型",
+            "司机姓名","司机电话","吨","立方","箱数","采购单号","ASN单号","商品名称","条码","数量","创建时间"];
+        foreach ($list as &$data){
+            $appointment = "";
+            $number = "";
+            $carType = "";
+            $driverName = "";
+            $driverPhone = "";
+            $commodityName = "";
+            $commodityCode = "";
+            $amount = "";
+            foreach ($data->cars as $car){
+                $appointment .= $car->appointment_number."\r\n";
+                $number .= $car->license_plate_number."\r\n";
+                $carType .= ($car->car->name ?? '')."\r\n";
+                $driverName .= ($car->driver_name ?? '')."\r\n";
+                $driverPhone .= ($car->driver_phone ?? '')."\r\n";
+            }
+            foreach ($data->details as $detail){
+                $commodityName .= ($detail->commodity->name ?? $detail->name)."\r\n";
+                $commodityCode .= ($detail->commodity->barcodes->code ?? $detail->bar_code)."\r\n";
+                $amount .= $detail->amount."\r\n";
+            }
+            $data = [
+                DeliveryAppointment::STATUS[$data->status],
+                $data->owner->name ?? '',
+                $data->appointment_date,
+                $data->warehouse->name ?? '',
+                $appointment,
+                $number,
+                $carType,
+                $driverName,
+                $driverPhone,
+                $data->tonne,
+                $data->cubic_meter,
+                $data->box_amount,
+                $data->procurement_number,
+                $data->asn_number,
+                $commodityName,
+                $commodityCode,
+                $amount,
+                $data->created_at
+            ];
+        }
+        return app(ExportService::class)->json($row,$list,"预约记录");
+    }
 }

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

@@ -158,7 +158,8 @@ class TestController extends Controller
         dd(Region::query()->where("id",">=",404)->where("id","<=",432)->delete());
     }
     public function tt1(){
-       return view("store.deliveryAppointment.success");
+       $a = DeliveryAppointment::query()->with("cars")->with("details")->get();
+       dd($a);
     }
     public function zzd(){
         ini_set('max_execution_time',2500);

+ 22 - 0
app/Services/DeliveryAppointmentService.php

@@ -4,15 +4,37 @@ namespace App\Services;
 
 use App\CommodityBarcode;
 use App\DeliveryAppointmentDetail;
+use App\Services\common\QueryService;
 use App\Traits\ServiceAppAop;
 use App\DeliveryAppointment;
 use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\Auth;
 
 class DeliveryAppointmentService
 {
     use ServiceAppAop;
     protected $modelClass=DeliveryAppointment::class;
 
+    /**
+     * 搜索QUERY
+     *
+     * @param array $params
+     *
+     * @return Builder
+     */
+    public function query(array $params)
+    {
+        $owners = app("UserService")->getPermittingOwnerIds(Auth::user());
+        return app(QueryService::class)->query($params,DeliveryAppointment::query(),[
+            'created_at_start' => ['alias' => 'created_at' , 'startDate' => ' 00:00:00'],
+            'appointment_date_start' => ['alias' => 'appointment_date' , 'startDate' => ' 00:00:00'],
+            'created_at_end' => ['alias' => 'created_at' , 'endDate' => ' 23:59:59'],
+            'appointment_date_end' => ['alias' => 'appointment_date' , 'endDate' => ' 23:59:59'],
+            "owner_id"=>['multi' => ','],
+            "id"=>['multi' => ','],
+        ])->orderByDesc("id")->whereIn("owner_id",$owners)->with(["cars.car","details.commodity.barcodes"]);
+    }
+
     /**
      * 根据吨,立方,SKU减产系数计算产能
      *

+ 1 - 1
app/Services/OwnerPriceExpressService.php

@@ -253,7 +253,7 @@ sql
         })->where(function(Builder $query){
             $query->whereNull("operation")->orWhere("operation","");
         })->first();
-        if (!$model || !$model->details)return -1;
+        if (!$model || count($model->details)<1)return -1;
         if ($weight <= $model->initial_weight)return $model->details[0]->initial_weight_price;
         $weight -= $model->initial_weight;
         return (ceil($weight/$model->additional_weight)*$model->details[0]->additional_weight_price)+$model->details[0]->initial_weight_price;

+ 35 - 0
database/migrations/2021_03_12_142125_add_authority_appointment_data.php

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddAuthorityAppointmentData extends Migration
+{
+    protected $authorities = [
+        "入库管理-客户预约-预约管理",
+    ];
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        foreach ($this->authorities as $authority){
+            \App\Authority::query()->firstOrCreate(["name"=>$authority],["name"=>$authority,"alias_name"=>$authority]);
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        foreach ($this->authorities as $authority){
+            \App\Authority::query()->where("name",$authority)->delete();
+        }
+    }
+}

+ 1 - 1
resources/views/store/deliveryAppointment/appointment.blade.php

@@ -1,5 +1,5 @@
 @extends('layouts.app')
-@section('title')客户预约-盘收一体@endsection
+@section('title')客户预约-客户预约@endsection
 
 @section('content')
     <span id="nav2">

+ 1 - 0
resources/views/store/deliveryAppointment/exhibition.blade.php

@@ -0,0 +1 @@
+<?php

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

@@ -0,0 +1,270 @@
+@extends('layouts.app')
+@section('title')预约管理-客户预约@endsection
+
+@section('content')
+    <span id="nav2">
+    @component('store.menu')@endcomponent
+    @component('store.deliveryAppointment.menu')@endcomponent
+    </span>
+    <div class="container-fluid d-none" id="container">
+        <div id="form"></div>
+        <div class="mt-1">
+            <button type="button" class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget" :class="[checkData.length>0?'btn-dark text-light':'']"
+                    data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">
+                导出Excel
+            </button>
+            <div class="dropdown-menu">
+                <a class="dropdown-item" @click="executeExport(false)" href="javascript:">导出勾选内容</a>
+                <a class="dropdown-item" @click="executeExport(true)" href="javascript:">导出所有页</a>
+            </div>
+        </div>
+        <table class="table table-striped table-hover text-nowrap">
+            <tr class="text-center">
+                <th>
+                    <label for="all" id="cloneCheckAll">
+                        <input id="all" type="checkbox" @click="checkAll($event)">全选
+                    </label>
+                </th>
+                <th>序号</th>
+                <th>操作</th>
+                <th>状态</th>
+                <th>货主</th>
+                <th>预约时间</th>
+                <th>仓库</th>
+                <th>
+                    <div class="row">
+                        <div class="col-12">车辆信息</div>
+                    </div>
+                    <div class="row">
+                        <div class="col-2">预约号</div>
+                        <div class="col-2">车牌号</div>
+                        <div class="col-3">车型</div>
+                        <div class="col-2">司机姓名</div>
+                        <div class="col-3">司机电话</div>
+                    </div>
+                </th>
+                <th>吨</th>
+                <th>立方</th>
+                <th>箱数</th>
+                <th>采购单号</th>
+                <th>ASN单号</th>
+                <th>
+                    <div class="row">
+                        <div class="col-12 text-center">明细单</div>
+                    </div>
+                    <div class="row">
+                        <div class="col-5 text-center">商品名称</div>
+                        <div class="col-4 text-center">条码</div>
+                        <div class="col-2 text-center">数量</div>
+                    </div>
+                </th>
+                <th>创建时间</th>
+            </tr>
+            <tr v-for="(info,i) in list">
+                <td>
+                    <label>
+                        <input class="checkItem" type="checkbox" :value="info.id" v-model="checkData">
+                    </label>
+                </td>
+                <td>@{{ i+1 }}</td>
+                <td><button type="button" @click="cancel(info.id,i)" class="btn btn-sm btn-outline-danger" v-if="info.status==0">取消预约</button></td>
+                <td>
+                    <label v-if="!poolMapping.status">
+                        <span class="fa fa-circle text-secondary">未知</span>
+                    </label>
+                    <label v-else>
+                        <small><span class="fa fa-circle" :class="info.status==0 ? 'text-info' : (info.status==2 ? 'text-success' : 'text-danger')"></span></small>
+                        @{{ poolMapping.status[info.status] }}
+                    </label>
+                </td>
+                <td>
+                    <label v-if="!poolMapping.owners"></label>
+                    <label v-else>@{{ poolMapping.owners[info.owner_id] }}</label>
+                </td>
+                <td class="text-primary">@{{ info.appointment_date }}&nbsp;&nbsp;@{{ info.period }}</td>
+                <td>
+                    <label v-if="!poolMapping.warehouses"></label>
+                    <label v-else>@{{ poolMapping.warehouses[info.warehouse_id] }}</label>
+                </td>
+                <td>
+                    <div v-if="info.cars.length>0">
+                        <div class="row">
+                            <div class="col-2 font-weight-bold">@{{ info.cars[0].appointment_number }}</div>
+                            <div class="col-2 text-secondary">@{{ info.cars[0].license_plate_number }}</div>
+                            <div class="col-3 text-secondary">@{{ info.cars[0].car ? info.cars[0].car.name : '' }}</div>
+                            <div class="col-2 text-secondary">@{{ info.cars[0].driver_name }}</div>
+                            <div class="col-3 text-secondary">@{{ info.cars[0].driver_phone }}</div>
+                        </div>
+                        <div class="up" :id="'item-'+info.id" v-show="info.cars.length>1">
+                            <div class="row" v-for="(car,i) in info.cars" v-if="i!==0">
+                                <div class="col-2 font-weight-bold">@{{ car.appointment_number }}</div>
+                                <div class="col-2 text-secondary">@{{ car.license_plate_number }}</div>
+                                <div class="col-3 text-secondary">@{{ car.car ? car.car.name : '' }}</div>
+                                <div class="col-2 text-secondary">@{{ car.driver_name }}</div>
+                                <div class="col-3 text-secondary">@{{ car.driver_phone }}</div>
+                            </div>
+                        </div>
+                        <div class="text-center m-auto small cursor-pointer" v-if="info.cars.length>1" @click="upAll(info.id)">
+                            <span class="fa" :class="upList[info.id] ? 'fa-angle-double-down' : 'fa-angle-double-right'" style="margin-top: 2px;"></span>&nbsp;
+                            <span v-if="upList[info.id]">收起其余@{{ info.cars.length-1 }}条</span>
+                            <span v-else>展开其余@{{ info.cars.length-1 }}条</span>
+                        </div>
+                    </div>
+                </td>
+                <td>@{{ info.tonne>0 ? info.tonne : '-' }}</td>
+                <td>@{{ info.cubic_meter>0 ? info.cubic_meter : '-' }}</td>
+                <td>@{{ info.box_amount>0 ? info.box_amount : '-' }}</td>
+                <td>@{{ info.procurement_number }}</td>
+                <td>@{{ info.asn_number }}</td>
+                <td>
+                    <div v-if="info.details.length>0">
+                        <div class="row">
+                            <div class="col-5 font-weight-bold">@{{ info.details[0].commodity_id ? (info.details[0].commodity ? info.details[0].commodity.name : '') : info.details[0].name }}</div>
+                            <div class="col-4 text-secondary">@{{ info.details[0] | getCommodity }}</div>
+                            <div class="col-2 text-secondary">@{{ info.details[0].amount }}</div>
+                        </div>
+                        <div class="up" :id="'detail-'+info.id" v-show="info.details.length>1">
+                            <div class="row" v-for="(detail,i) in info.details" v-if="i!==0">
+                                <div class="col-5 font-weight-bold">@{{ detail.commodity_id ? (detail.commodity ? detail.commodity.name : '') : detail.name }}</div>
+                                <div class="col-4 text-secondary">@{{ detail | getCommodity }}</div>
+                                <div class="col-2 text-secondary">@{{ detail.amount }}</div>
+                            </div>
+                        </div>
+                        <div class="text-center m-auto small cursor-pointer" v-if="info.details.length>1" @click="upAllDetail(info.id)">
+                            <span class="fa" :class="upListDetail[info.id] ? 'fa-angle-double-down' : 'fa-angle-double-right'" style="margin-top: 2px;"></span>&nbsp;
+                            <span v-if="upListDetail[info.id]">收起其余@{{ info.details.length-1 }}条</span>
+                            <span v-else>展开其余@{{ info.details.length-1 }}条</span>
+                        </div>
+                    </div>
+                </td>
+                <td>@{{ info.created_at }}</td>
+            </tr>
+        </table>
+    </div>
+@stop
+
+@section("lastScript")
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+    <script>
+        new Vue({
+            el:"#container",
+            data:{
+                list:[@foreach($list as $data)@json($data),@endforeach],
+                status:[],
+                warehouses:[],
+                owners:[@foreach($owners as $owner){name:"{{$owner->id}}",value:"{{$owner->name}}"},@endforeach],
+                checkData:[],
+                poolMapping:{},
+                upList:{},
+                upListDetail:{},
+                sum:Number("{{$list->total()}}"),
+            },
+            mounted(){
+                let status = [];
+                let statusMap = {};
+                let warehouses = [];
+                let warehouseMap = {};
+                let owners = [];
+                let ownerMap = [];
+
+                @foreach(\App\DeliveryAppointment::STATUS as $index=>$status)
+                status.push({name:"{{$index}}",value:"{{$status}}"});
+                statusMap["{{$index}}"] = "{{$status}}";
+                @endforeach
+                this.status = status;
+                this.$set(this.poolMapping,"status",statusMap);
+
+                @foreach($warehouses as $warehouse)
+                warehouses.push({name:"{{$warehouse->id}}",value:"{{$warehouse->name}}"});
+                warehouseMap["{{$warehouse->id}}"] = "{{$warehouse->name}}";
+                @endforeach
+                this.warehouses = warehouses;
+                this.poolMapping.warehouses = warehouseMap;
+
+                @foreach($owners as $owner)
+                owners.push({name:"{{$owner->id}}",value:"{{$owner->name}}"});
+                ownerMap["{{$owner->id}}"] = "{{$owner->name}}";
+                @endforeach
+                this.owners = owners;
+                this.poolMapping.owners = ownerMap;
+
+                $(".up").slideUp();
+                $("#container").removeClass("d-none");
+                this._renderingForm();
+            },
+            watch:{
+                checkData:{
+                    handler(){
+                        if (this.checkData.length === this.list.length) document.querySelector('#all').checked = true;
+                        else document.querySelector('#all').checked = false;
+                    },
+                    deep:true
+                },
+            },
+            methods: {
+                _renderingForm(){
+                    let data=[
+                        [
+                            {name:'created_at_start',type:'dateTime',tip:"选择显示创建日期的结束时间"},
+                            {name:'appointment_date_start',type:'dateTime',tip:"选择显示预约日期的结束时间"},
+                            {name:'owner_id',type:'select_multiple_select',tip:['输入关键词快速定位下拉列表,回车确定','选择要显示的客户'],
+                                placeholder:['货主','定位或多选货主'],data:this.owners},
+                            {name:'status',type:'select',placeholder: '状态',data:this.status},
+                        ],
+                        [
+                            {name:'created_at_end',type:'dateTime',tip:"选择显示创建日期的结束时间"},
+                            {name:'appointment_date_end',type:'dateTime',tip:"选择显示预约日期的结束时间"},
+                            {name:'warehouse_id',type:'select',placeholder: '仓库',data:this.warehouses},
+                        ],
+                    ];
+                    let form = new query({
+                        el:"#form",
+                        condition:data,
+                    });
+                    form.init();
+                },
+                upAll(id){
+                    let dom = "#item-"+id;
+                    if (this.upList[id]) $(dom).slideUp();
+                    else $(dom).slideDown();
+                    this.$set(this.upList,id,!this.upList[id]);
+                },
+                upAllDetail(id){
+                    let dom = "#detail-"+id;
+                    if (this.upListDetail[id]) $(dom).slideUp();
+                    else $(dom).slideDown();
+                    this.$set(this.upListDetail,id,!this.upListDetail[id]);
+                },
+                cancel(id,index){
+                    window.tempTip.confirm("确定要取消该次预约吗?此操作不可逆,请谨慎选择",()=>{
+                        window.tempTip.postBasicRequest("{{url('store/deliveryAppointment/cancel')}}",{id:id},res=>{
+                            this.$set(this.list[index],"status",res);
+                            return "成功取消该单预约";
+                        })
+                    })
+                },
+                checkAll(e){
+                    if (e.target.checked){
+                        this.checkData = [];
+                        this.list.forEach((el)=>{
+                            this.checkData.push(el.id);
+                        });
+                    }else this.checkData = [];
+                },
+                executeExport(isAll){
+                    let url = '{{url('store/deliveryAppointment/export')}}';
+                    let token='{{ csrf_token() }}';
+                    excelExport(isAll,this.checkData,url,this.sum,token);
+                },
+            },
+            filters:{
+                getCommodity(detail){
+                    if (!detail.commodity_id)return detail.name;
+                    if (detail.commodity && detail.commodity.barcodes.length>0)return detail.commodity.barcodes[0].code;
+                    return "";
+                },
+            },
+        });
+    </script>
+@stop

+ 2 - 2
resources/views/store/deliveryAppointment/success.blade.php

@@ -5,7 +5,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <link rel="icon" href="{{asset('icon/faviconc.ico')}}" type="image/x-icon"/>
 
-    <title>预约成功</title>
+    <title>预约成功-客户预约</title>
     <link href="{{ mix('css/app.css') }}" rel="stylesheet">
     <style>
         .font{
@@ -34,7 +34,7 @@
             @endforeach
             <div class="mt-5">
                 <div class="mt-5 mb-4 row">
-                    <div class="col-6 text-right h5 font-weight-bold"><a href="#">查看预约列表</a></div>
+                    <div class="col-6 text-right h5 font-weight-bold"><a href="{{url('store/deliveryAppointment/list')}}">查看预约列表</a></div>
                     <div class="col-6 text-left h5 font-weight-bold"><a href="{{url('store/deliveryAppointment/appointment')}}">继续预约车辆</a></div>
                 </div>
                 <span class="fa fa-diamond text-primary"></span>&nbsp;请牢记您的预约码,预约码仅预约当天有效!

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

@@ -398,7 +398,6 @@
                     },
                     deep:true
                 },
-
             },
             mounted:function(){
                 $(".tooltipTarget").tooltip({'trigger':'hover'});

+ 2 - 0
routes/web.php

@@ -424,6 +424,8 @@ Route::group(['prefix'=>'store'],function(){
         Route::post('submitAppointment','DeliveryAppointmentController@submitAppointment');
         Route::get('showAppointmentInfo','DeliveryAppointmentController@showAppointmentInfo');
         Route::get('list','DeliveryAppointmentController@list');
+        Route::post('cancel','DeliveryAppointmentController@cancel');
+        Route::any('export','DeliveryAppointmentController@export');
         Route::group(['prefix'=>'appointment'],function(){
             Route::post('import','DeliveryAppointmentController@import');
         });