소스 검색

运输管理-BUG修复
即时账单-队列处理
波次修复

Zhouzhendong 5 년 전
부모
커밋
cad4f456ea

+ 58 - 0
app/Http/Controllers/TestController.php

@@ -175,8 +175,66 @@ class TestController extends Controller
         return view("test");
     }
     public function a(){
+
         return array(null,null);
     }
+    public function restoreWaybill()
+    {
+        ini_set('max_execution_time', 2500);
+        $waybills = Waybill::query()->whereNotNull("wms_bill_number")->whereNull("order_id")->get();
+        foreach ($waybills as $waybill){
+            $order = Order::query()->where("code",$waybill->wms_bill_number)->first();
+            $waybill->update(["order_id"=>$order->id]);
+        }
+    }
+    public function restoreBatch()
+    {
+        $wave = DB::connection("oracle")->selectOne(DB::raw("select * from DOC_WAVE_HEADER where WAVENO = 'W210421000141'"));
+        if ($wave){
+            $owner = app("OwnerService")->codeGetOwner($wave->customerid);
+            Batch::query()->where("code","W210421000141")->update([
+                "wms_status" => $this->wms_status($wave),
+                "wms_type"=>$wave->descr,
+                "created_at"=>$wave->addtime,
+                "updated_at"=>$wave->edittime,
+                "owner_id"=>$owner->id,
+            ]);
+            $wave = Batch::query()->where("code","W210421000141")->first();
+            if ($wave){
+                $ordernos = array_column(DB::connection("oracle")->select(DB::raw("select orderno from DOC_WAVE_DETAILS where WAVENO = 'W210421000141'")),"orderno");
+                Order::query()->whereIn("code",$ordernos)->update([
+                    "batch_id"=>$wave->id
+                ]);
+            }
+        }
+    }
+    /**
+     * @param $wave
+     * @return string
+     */
+    public function wms_status($wave): string
+    {
+        switch ($wave->wavestatus) {
+            case 00:
+                $wms_status = '创建';
+                break;
+            case 40:
+                $wms_status = '部分收货';
+                break;
+            case 90:
+                $wms_status = '取消';
+                break;
+            case 99:
+                $wms_status = '完成';
+                break;
+            case 62:
+                $wms_status = '部分装箱';
+                break;
+            default:
+                $wms_status = (string)$wave->wavestatus;
+        }
+        return $wms_status;
+    }
     public function supplementMarchOwnerReport()
     {
         $ows = OwnerAreaReport::query()->select("owner_id")->where("counting_month",'like',"2021-03%")->get();

+ 2 - 0
app/Http/Controllers/api/thirdPart/flux/WaybillController.php

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\api\thirdPart\flux;
 
 use App\City;
 use App\Http\Controllers\Controller;
+use App\Jobs\HandleExceptionWaybill;
 use App\Order;
 use App\Owner;
 use App\Services\RegionService;
@@ -116,6 +117,7 @@ class WaybillController extends Controller
                 $waybill->waybill_number=$waybill_number;
                 $waybill->update();
             }
+            if (!$waybill->order_id && $waybill->wms_bill_number)dispatch(new HandleExceptionWaybill($waybill))->delay(now()->addMinutes(15));
             //回传FLUX
             $this->accomplishToWMS($waybill);
         }

+ 44 - 0
app/Jobs/HandleExceptionWaybill.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Order;
+use App\Waybill;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+class HandleExceptionWaybill implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    /** @var Waybill|\stdClass */
+    protected $waybill;
+    /**
+     * Create a new job instance.
+     *
+     * @param Waybill $waybill
+     *
+     * @return void
+     */
+    public function __construct(Waybill $waybill)
+    {
+        $this->waybill = $waybill;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     *
+     * @throws
+     */
+    public function handle()
+    {
+        $order = Order::query()->where("code",$this->waybill->wms_bill_number)->first();
+        if ($order)$this->waybill->update(["order_id"=>$order->id]);
+        else throw new \Exception("order does not exist");
+    }
+}

+ 41 - 0
app/Jobs/HandlePastBill.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Services\OwnerPriceOperationService;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+class HandlePastBill implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    protected $arr;
+    /**
+     * Create a new job instance.
+     *
+     * @param array $arr
+     *
+     * @return void
+     */
+    public function __construct(array $arr)
+    {
+        $this->arr = $arr;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @param OwnerPriceOperationService $service
+     *
+     * @return void
+     */
+    public function handle(OwnerPriceOperationService $service)
+    {
+        list($rule,$owner,$discountIndex,$pivot) = $this->arr;
+        $service->handlePastBill($rule,$owner,$discountIndex,$pivot);
+    }
+}

+ 2 - 2
app/OwnerPriceOperation.php

@@ -17,9 +17,9 @@ class OwnerPriceOperation extends Model
         "feature",          //特征
         "remark",           //备注
         "priority",         //优先级 值越大越高
-        "discount_count",   //减免值
+        "discount_count",   //减免值 array
         "total_price",      //按单计价
-        "total_discount_price",//按单计价减免
+        "total_discount_price",//按单计价减免 array
         "operation",        //操作
         "target_id",        //目标ID
         "type_mark",        //类型标记

+ 8 - 5
app/Services/OwnerPriceOperationService.php

@@ -3,6 +3,7 @@
 namespace App\Services;
 
 use App\Feature;
+use App\Jobs\HandlePastBill;
 use App\OwnerFeeDetail;
 use App\OwnerPriceOperation;
 use App\OwnerPriceOperationItem;
@@ -279,7 +280,7 @@ class OwnerPriceOperationService
             return $pivot ?? null;
         },1000);
         //进入历史单处理
-        if ($pivot && $sign)$this->handlePastBill($rule,$owner,$discountIndex,$pivot);
+        if ($pivot && $sign)dispatch(new HandlePastBill(array($rule,$owner,$discountIndex,$pivot)));
     }
 
     /** 参数顺序: 数量 匹配对象 列映射 货主ID 单位ID 类型 SKU .
@@ -312,6 +313,8 @@ class OwnerPriceOperationService
      *      增加一级二级特征,零头价,满减按总件,附加费用等
      * 八. 2021-04-19 zzd
      *      增加税率计算,改变返回值数据结构,增加封顶费
+     * 九. 2021-04-21 zzd
+     *      排除掉order不存在包裹情况,预设输出值为null防止返回0,历史账单处理推进队列防止超时
      */
     public function matching($matchObject, $columnMapping, $ownerId, $type = '出库', $typeMark = null)
     {
@@ -321,7 +324,7 @@ class OwnerPriceOperationService
 
         //建立一组返回变量
         $id = null;
-        $money = 0;
+        $money = null;
         $taxFee = null;
 
         if ($type == '出库')$total = app("OrderService")->getOrderQuantity($ownerId);//获取该货主本月C端单量
@@ -389,9 +392,9 @@ class OwnerPriceOperationService
         }
         $nextObj = strstr($columnMapping[8],".",true);
         $first = $matchObject[$need] ?? false;
-        if ($first && is_array($first))$first = reset($first);
-        else return $matchObject;
-        if (!$first)return $matchObject;
+        if ($first===false)return $matchObject;
+        if (!$first)return $first;
+        if (is_array($first))$first = reset($first);
         if ($nextObj && is_array($first[$nextObj])){
             $result = [];
             foreach ($matchObject[$need] as $arr)$result = array_merge($result,$arr[$nextObj]);

+ 556 - 54
resources/views/test.blade.php

@@ -44,11 +44,11 @@
             </div>
             <div class="modal-body">
                 <div class="row">
-                    <label class="col-3 text-right h4"><span class="badge badge-success">新增</span></label>
+                    <label class="col-1 text-right h4"><span class="badge badge-success">新增</span></label>
                     <label class="col-1 h3 text-success" style="bottom: 0.25rem">
                         <span class="fa fa-long-arrow-right"></span>
                     </label>
-                    <div class="col-8 border-bottom border-success">
+                    <div class="col-10 border-bottom border-success">
                         <div v-if="selectedAudit=='storage'" v-for="s in auditList.storage.C">
                             <div><b>@{{ s.name }}</b><span class="text-muted">(@{{ s.counting_type }}-@{{ s.using_type }})</span></div>
                         </div>
@@ -70,11 +70,11 @@
                     </div>
                 </div>
                 <div class="row">
-                    <label class="col-3 text-right h4"><span class="badge badge-danger">删除</span></label>
+                    <label class="col-1 text-right h4"><span class="badge badge-danger">删除</span></label>
                     <label class="col-1 h3 text-danger" style="bottom: 0.25rem">
                         <span class="fa fa-long-arrow-right"></span>
                     </label>
-                    <div class="col-8 border-bottom border-danger">
+                    <div class="col-10 border-bottom border-danger">
                         <div v-if="selectedAudit=='storage'" v-for="s in auditList.storage.D">
                             <table class="table table-sm">
                                 <tr class="text-center">
@@ -99,32 +99,112 @@
                                     <td>@{{ s.unit_id }}</td>
                                     <td>@{{ s.time_unit_id }}</td>
                                     <td>
-                                        <div>
-                                            <div class="float-left">
-                                                <small v-for="(a,i) in s.amount_interval" v-if="i!=s.amount_interval.length-1">@{{ a }}-@{{ s.amount_interval[i+1] }}(@{{ s.price[i] }}元)<br></small>
-                                                <small>@{{ s.amount_interval[s.amount_interval.length-1] }}&nbsp;+<br></small>
-                                            </div>
-                                            <div class="float-left">
-                                                <span class="float-left fa fa-long-arrow-right" style="margin-top: 1em"></span>
-                                                <div class="float-left">
-                                                    <small v-for="(a,i) in s.amount_interval" v-if="i!=s.amount_interval.length-1">@{{ a }}-@{{ s.amount_interval[i+1] }}(@{{ s.price[i] }}元)<br></small>
-                                                    <small>@{{ s.amount_interval[s.amount_interval.length-1] }}&nbsp;+<br></small>
-                                                </div>
-                                            </div>
+                                        <div class="float-left small">
+                                            <span v-for="(a,i) in s.amount_interval" v-if="i!=s.amount_interval.length-1">@{{ a }}-@{{ s.amount_interval[i+1] }}(@{{ s.price[i] }}元)<br></span>
+                                            <span>@{{ s.amount_interval[s.amount_interval.length-1] }}&nbsp;+(@{{ s.price[s.amount_interval.length-1] }}元)<br></span>
                                         </div>
                                     </td>
-                                    <td>@{{ s.tax_rate_id }}%</td>
+                                    <td>@{{ s.tax_rate_id }}</td>
                                 </tr>
                             </table>
                         </div>
-                        <div v-if="selectedAudit=='operation'" v-for="s in auditList.operation.C">
-                            <div><b>@{{ s.name }}</b><span class="text-muted">(@{{ s.operation_type }}-@{{ s.strategy }})</span></div>
+                        <div v-if="selectedAudit=='operation'" v-for="s in auditList.operation.D">
+                            <table class="table table-sm">
+                                <tr>
+                                    <th>名称</th>
+                                    <th>作业类型</th>
+                                    <th>策略</th>
+                                    <th>特征</th>
+                                    <th>按单价</th>
+                                    <th>按单减免单价</th>
+                                    <th>减免值</th>
+                                    <th>类型</th>
+                                    <th>附加费</th>
+                                    <th>附加费单位</th>
+                                    <th>封顶费</th>
+                                    <th>备注</th>
+                                    <th>税率</th>
+                                </tr>
+                                <tr>
+                                    <td>@{{ s.name }}</td>
+                                    <td>@{{ s.operation_type }}</td>
+                                    <td>@{{ s.strategy }}</td>
+                                    <td>@{{ s.feature }}</td>
+                                    <td>@{{ s.total_price }}</td>
+                                    <td>
+                                        <div class="float-left small">
+                                            <span v-for="(a,i) in s.total_discount_price">@{{ a }}元<br></span>
+                                        </div>
+                                    </td>
+                                    <td>
+                                        <div class="float-left small">
+                                            <span v-for="(a,i) in s.discount_count" v-if="i!=s.discount_count.length-1">@{{ a }}-@{{ s.discount_count[i+1] }}<br></span>
+                                            <span>@{{ s.discount_count[s.discount_count.length-1] }}&nbsp;+<br></span>
+                                        </div>
+                                    </td>
+                                    <td>@{{ s.type_mark }}</td>
+                                    <td>@{{ s.surcharge }}</td>
+                                    <td>@{{ s.surcharge_unit_id }}</td>
+                                    <td>@{{ s.max_fee }}</td>
+                                    <td>@{{ s.remark }}</td>
+                                    <td>@{{ s.tax_rate_id }}</td>
+                                </tr>
+                            </table>
                         </div>
-                        <div v-if="selectedAudit=='express'" v-for="s in auditList.express.C">
-                            <div><b>@{{ s.name }}</b></div>
+                        <div v-if="selectedAudit=='express'" v-for="s in auditList.express.D">
+                            <table class="table table-sm">
+                                <tr>
+                                    <th>名称</th>
+                                    <th>首重</th>
+                                    <th>续重</th>
+                                    <th>数量-重量</th>
+                                    <th>税率</th>
+                                </tr>
+                                <tr>
+                                    <td>@{{ s.name }}</td>
+                                    <td>@{{ s.initial_weight }}</td>
+                                    <td>@{{ s.additional_weight }}</td>
+                                    <td>
+                                        <span v-for="(a,i) in s.amount_interval" v-if="i!=s.amount_interval.length-1">@{{ a }}-@{{ s.amount_interval[i+1] }}/单(
+                                            <span v-for="(w,j) in s.weight_interval[i]" v-if="j!=s.weight_interval[i].length">@{{ w }}-@{{ s.weight_interval[i][j+1] }}/KG,</span>
+                                            @{{ s.weight_interval[i][s.weight_interval[i].length-1] }}&nbsp;+/KG)<br></span>
+                                        <span>@{{ s.amount_interval[s.amount_interval.length-1] }}&nbsp;+/单(
+                                            <span v-for="(w,j) in s.weight_interval[s.amount_interval.length-1]" v-if="j!=s.weight_interval[s.amount_interval.length-1].length">@{{ w }}-@{{ s.weight_interval[s.amount_interval.length-1][j+1] }}/KG,</span>
+                                            @{{ s.weight_interval[s.amount_interval.length-1][s.weight_interval[s.amount_interval.length-1].length-1] }}&nbsp;+/KG)<br></span>
+                                    </td>
+                                    <td>@{{ s.tax_rate_id }}</td>
+                                </tr>
+                            </table>
                         </div>
-                        <div v-if="selectedAudit=='logistic'" v-for="s in auditList.logistic.C">
-                            <div><b>@{{ s.name }}</b></div>
+                        <div v-if="selectedAudit=='logistic'" v-for="s in auditList.logistic.D">
+                            <table class="table table-sm">
+                                <tr>
+                                    <th>名称</th>
+                                    <th>单位一</th>
+                                    <th>单位一区间</th>
+                                    <th>单位二</th>
+                                    <th>单位二区间</th>
+                                    <th>提货费</th>
+                                    <th>燃油附加费</th>
+                                    <th>服务费</th>
+                                    <th>税率</th>
+                                </tr>
+                                <tr>
+                                    <td>@{{ s.name }}</td>
+                                    <td>@{{ s.unit_id }}</td>
+                                    <td>
+                                        <span class="small" v-for="u in s.unit_range">@{{ u }}<br></span>
+                                    </td>
+                                    <td>@{{ s.other_unit_id }}</td>
+                                    <td>
+                                        <span class="small" v-for="u in s.other_unit_range">@{{ u }}<br></span>
+                                    </td>
+                                    <td>@{{ s.pick_up_price }}</td>
+                                    <td>@{{ s.fuel_price }}</td>
+                                    <td>@{{ s.service_price }}</td>
+                                    <td>@{{ s.tax_rate_id }}</td>
+                                </tr>
+                            </table>
                         </div>
                         <div v-if="selectedAudit=='directLogistic'" v-for="s in auditList.directLogistic.C">
                             <div><b>@{{ s.name }}</b><span class="text-muted">(起步:@{{ s.base_km }}KM)</span></div>
@@ -135,29 +215,77 @@
                     </div>
                 </div>
                 <div class="row">
-                    <label class="col-3 text-right h4"><span class="badge badge-primary">修改</span></label>
+                    <label class="col-1 text-right h4"><span class="badge badge-primary">修改</span></label>
                     <label class="col-1 h3 text-primary" style="bottom: 0.25rem">
                         <span class="fa fa-long-arrow-right"></span>
                     </label>
-                    <div class="col-8">
+                    <div class="col-10">
                         <div v-if="selectedAudit=='storage'" v-for="s in auditList.storage.U">
                             <table class="table table-sm">
                                 <tr>
-                                    <th v-for="(key,val) in auditList.mapping.storage">@{{ val }}</th>
+                                    <th v-for="(val,key) in auditList.mapping.storage">@{{ val }}</th>
                                 </tr>
                                 <tr>
-                                    <td v-for="(key,val) in auditList.mapping.storage" v-html="s[key]"></td>
+                                    <td v-for="(val,key) in auditList.mapping.storage" v-html="s[key]"></td>
                                 </tr>
                             </table>
                         </div>
-                        <div v-if="selectedAudit=='operation'" v-for="s in auditList.operation.C">
-                            <div><b>@{{ s.name }}</b><span class="text-muted">(@{{ s.operation_type }}-@{{ s.strategy }})</span></div>
+                        <div v-if="selectedAudit=='operation'" v-for="s in auditList.operation.U">
+                            <table class="table table-sm">
+                                <tr>
+                                    <th v-for="(val,key) in auditList.mapping.operation" v-if="key!='child'">@{{ val }}</th>
+                                    <th v-if="s.items.length>0" class="text-center">子项</th>
+                                </tr>
+                                <tr>
+                                    <td v-for="(val,key) in auditList.mapping.operation" v-if="key!='child'" v-html="s[key]"></td>
+                                    <td v-if="s.items.length>0">
+                                        <table class="table table-sm">
+                                            <tr><th v-for="(val,key) in auditList.mapping.operation.child">@{{ val }}</th></tr>
+                                            <tr v-for="item in s.items">
+                                                <td v-for="(val,key) in auditList.mapping.operation.child" v-html="item[key]"></td>
+                                            </tr>
+                                        </table>
+                                    </td>
+                                </tr>
+                            </table>
                         </div>
-                        <div v-if="selectedAudit=='express'" v-for="s in auditList.express.C">
-                            <div><b>@{{ s.name }}</b></div>
+                        <div v-if="selectedAudit=='express'" v-for="s in auditList.express.U">
+                            <table class="table table-sm">
+                                <tr>
+                                    <th v-for="(val,key) in auditList.mapping.express" v-if="key!='child'">@{{ val }}</th>
+                                    <th v-if="s.details.length>0" class="text-center">子项</th>
+                                </tr>
+                                <tr>
+                                    <td v-for="(val,key) in auditList.mapping.express" v-if="key!='child'" v-html="s[key]"></td>
+                                    <td v-if="s.details.length>0">
+                                        <table class="table table-sm">
+                                            <tr><th v-for="(val,key) in auditList.mapping.express.child">@{{ val }}</th></tr>
+                                            <tr v-for="item in s.details">
+                                                <td v-for="(val,key) in auditList.mapping.express.child" v-html="item[key]"></td>
+                                            </tr>
+                                        </table>
+                                    </td>
+                                </tr>
+                            </table>
                         </div>
-                        <div v-if="selectedAudit=='logistic'" v-for="s in auditList.logistic.C">
-                            <div><b>@{{ s.name }}</b></div>
+                        <div v-if="selectedAudit=='logistic'" v-for="s in auditList.logistic.U">
+                            <table class="table table-sm">
+                                <tr>
+                                    <th v-for="(val,key) in auditList.mapping.logistic" v-if="key!='child'">@{{ val }}</th>
+                                    <th v-if="s.details.length>0" class="text-center">子项</th>
+                                </tr>
+                                <tr>
+                                    <td v-for="(val,key) in auditList.mapping.logistic" v-if="key!='child'" v-html="s[key]"></td>
+                                    <td v-if="s.details.length>0">
+                                        <table class="table table-sm">
+                                            <tr><th v-for="(val,key) in auditList.mapping.logistic.child">@{{ val }}</th></tr>
+                                            <tr v-for="item in s.details">
+                                                <td v-for="(val,key) in auditList.mapping.logistic.child" v-html="item[key]"></td>
+                                            </tr>
+                                        </table>
+                                    </td>
+                                </tr>
+                            </table>
                         </div>
                         <div v-if="selectedAudit=='directLogistic'" v-for="s in auditList.directLogistic.C">
                             <div><b>@{{ s.name }}</b><span class="text-muted">(起步:@{{ s.base_km }}KM)</span></div>
@@ -187,22 +315,63 @@
                     "C":[{name:"笕尚退货",counting_type:"包仓",using_type:"恒温"},{name:"笕尚退货",counting_type:"包仓",using_type:"恒温"}],
                     "U":[{name:"笕尚退货",counting_type:"包仓",using_type:"恒温",
                         minimum_area:"200",price:["0.2"],discount_type:"无减免",target_id:"10",
-                        discount_value:"20",unit_id:"m²",time_unit_id:"日",tax_rate_id:"3",amount_interval:["2"]}],
+                        discount_value:"20",unit_id:"1",time_unit_id:"2",tax_rate_id:"1",amount_interval:["2"]}],
                     "D":[{name:"笕尚退货",counting_type:"包仓",using_type:"恒温",
                         minimum_area:"200",price:["0.2","0.1"],discount_type:"无减免",
                         discount_value:"20",unit_id:"m²",time_unit_id:"日",tax_rate_id:"3",amount_interval:["2","5"]}],
                     "H":{10:{name:"笕尚退货",counting_type:"包仓",using_type:"恒温",
                             minimum_area:"200",price:["0.1","0.2"],discount_type:"无减免",
-                            discount_value:"20",unit_id:"m²",time_unit_id:"日",tax_rate_id:"3",amount_interval:["2","5"]}},
+                            discount_value:"20",unit_id:"2",time_unit_id:"1",tax_rate_id:"2",amount_interval:["2","5"]}},
                 },
                 operation:{
                     "C":[{name:"笕尚入库",operation_type:"入库",strategy:"特征"},{name:"笕尚入库",operation_type:"入库",strategy:"特征"}],
+                    "D":[{name:"笕尚入库",operation_type:"入库",strategy:"特征",
+                        feature:"特征X",remark:"x",discount_count:[1,2],total_price:"222",total_discount_price:[1,2,3,4]
+                        ,type_mark:"退货单",surcharge:"58",surcharge_unit_id:"米",max_fee:"777",tax_rate_id:"5%"}],
+                    "U":[{name:"笕尚入库",operation_type:"入库",strategy:"特征",
+                        feature:"特征X",remark:"x",discount_count:[1,2],total_price:"222",total_discount_price:[1,2,3,4]
+                        ,type_mark:"退货单",surcharge:"58",surcharge_unit_id:"米",max_fee:"777",tax_rate_id:"5%",target_id:"10",
+                        items:[{id:"2",owner_price_operation_id:"5",strategy:"默认",amount:"21",unit_id:"8",unit_price:"9",feature:"11",priority:"0",discount_price:[5,6,7],odd_price:"5"},
+                            {id:"5",owner_price_operation_id:"5",strategy:"特征",amount:"22",unit_id:"8",unit_price:"9",feature:"13",priority:"0",discount_price:[5,6,7],odd_price:"5"},]}],
+                    "H":{10:{name:"笕尚入库1",operation_type:"入库",strategy:"特征",
+                        feature:"特征X",remark:"x",discount_count:[1,2,5],total_price:"222",total_discount_price:[1,2,4]
+                        ,type_mark:"退货单",surcharge:"58",surcharge_unit_id:"T",max_fee:"7771",tax_rate_id:"3%",
+                        items:[{id:"1",owner_price_operation_id:"5",strategy:"默认",amount:"21",unit_id:"8",unit_price:"9",feature:"11",priority:"0",discount_price:[5,6,7],odd_price:"5"},
+                            {id:"3",owner_price_operation_id:"5",strategy:"起步",amount:"21",unit_id:"8",unit_price:"9",feature:"11",priority:"0",discount_price:[5,6,7],odd_price:"5"},
+                            {id:"4",owner_price_operation_id:"5",strategy:"特征",amount:"21",unit_id:"8",unit_price:"9",feature:"11",priority:"0",discount_price:[5,6,7],odd_price:"5"},
+                        ]}},
                 },
                 express:{
                     "C":[{name:"笕尚快递"}],
+                    "D":[{name:"笕尚快递",initial_weight:"包仓",additional_weight:"恒温",
+                        amount_interval:[2,5],
+                        weight_interval:[[10,20],[]],tax_rate_id:"5%"}],
+                    "U":[{name:"笕尚快递",initial_weight:"1",additional_weight:"3",
+                        amount_interval:[2,5],
+                        weight_interval:[[10,20],[]],tax_rate_id:"5%",target_id:10,
+                    details:[{province_id:"河南",initial_weight_price:[[4]],additional_weight_price:[[5]]}]}],
+                    "H":{10:{name:"笕尚快递",initial_weight:"1",additional_weight:"2",
+                        amount_interval:[2,5],
+                        weight_interval:[[10,20],[]],tax_rate_id:"5%",
+                            details:[{province_id:"河南",initial_weight_price:[[5]],additional_weight_price:[[5]]}]}},
                 },
                 logistic:{
                     "C":[{name:"笕尚物流"}],
+                    "D":[{name:"笕尚物流",unit_range:["0-5","5-10"],unit_id:"5",other_unit_range:["0-5","5-10"],other_unit_id:"T"
+                        ,pick_up_price:"222",fuel_price:"22",service_price:"34",tax_rate_id:"6%",details:[
+                            {unit_id:"T",range:"0-10",province_id:"河北",city_id:"石家庄",unit_price:"22",delivery_fee:"170",
+                                rate:"20%"},
+                        ]}],
+                    "U":[{name:"笕尚物流",unit_range:["0-5","5-10"],unit_id:"5",other_unit_range:["0-5","5-10"],other_unit_id:"T"
+                        ,pick_up_price:"222",fuel_price:"22",service_price:"34",tax_rate_id:"6%",target_id:10,details:[
+                            {unit_id:"T",range:"0-10",province_id:"河北",city_id:"石家庄",unit_price:"22",delivery_fee:"170",
+                                rate:"20%"},
+                        ]}],
+                    "H":{10:{name:"笕尚物流",unit_range:["0-5","5-10"],unit_id:"5",other_unit_range:["0-5","5-10"],other_unit_id:"T"
+                        ,pick_up_price:"222",fuel_price:"22",service_price:"34",tax_rate_id:"6%",details:[
+                            {unit_id:"T",range:"0-10",province_id:"河北",city_id:"石家庄",unit_price:"22",delivery_fee:"170",
+                                rate:"21%"},
+                        ]}},
                 },
                 directLogistic:{
                     "C":[{name:"笕尚直发",base_km:"10"}],
@@ -222,44 +391,377 @@
                         "time_unit_id":"计时单位",
                         "amount_interval":"数量-单价",
                         "tax_rate_id":"税率",
-                    }
+                    },
+                    "operation":{
+                        name:"名称",
+                        operation_type:"作业类型",
+                        strategy:"策略",
+                        feature:"特征",
+                        total_price:"按单价",
+                        total_discount_price:"按单减免单价",
+                        discount_count:"减免值",
+                        type_mark:"类型",
+                        surcharge:"附加费",
+                        surcharge_unit_id:"附加费单位",
+                        max_fee:"封顶费",
+                        remark:"备注",
+                        tax_rate_id:"税率",
+                        child:{
+                            strategy:"子策略",
+                            amount:"起步数",
+                            unit_id:"单位",
+                            unit_price:"单价",
+                            feature:"特征",
+                            discount_price:"减免单价",
+                            odd_price:"零头价",
+                        }
+                    },
+                    "express":{
+                        name:"名称",
+                        initial_weight:"首重",
+                        additional_weight:"续重",
+                        weight_interval:"数量-重量",
+                        tax_rate_id:"税率",
+                        child:{
+                            province_id:"省",
+                            initial_weight_price:"初始单价",
+                            additional_weight_price:"续重单价",
+                        },
+                    },
+                    "logistic":{
+                        name:"名称",
+                        unit_id:"单位一",
+                        unit_range:"单位一区间",
+                        other_unit_id:"单位二",
+                        other_unit_range:"单位二区间",
+                        pick_up_price:"提货费",
+                        fuel_price:"燃油附加费",
+                        service_price:"服务费",
+                        tax_rate_id:"税率",
+                        child:{
+                            unit_id:"单位",
+                            range:"区间",
+                            province_id:"省份",
+                            city_id:"城市",
+                            unit_price:"单价",
+                            delivery_fee:"送货费",
+                            initial_fee:"起始计费",
+                            initial_amount:"起始计数",
+                            rate:"费率",
+                        },
+                    },
                 },
             },
-            selectedAudit:"storage"
+            selectedAudit:"logistic",
+            poolMapping:{
+                units:{1:"T",2:"G"},
+                taxRates:{1:"2",2:"3"},
+            }
         },
         mounted(){
-            let temp = {};
+            let temp = {"name":"名称"};
+            let font = "<div class='float-left'><span class='float-left fa fa-arrow-right text-info ml-2 mr-2'></span>";
             this.auditList.storage.U.forEach(data=>{
                 let tar = this.auditList.storage.H[data.target_id];
                 for (let key in this.auditList.mapping.storage){
-                    if (data[key]!==tar[key]){
+                    if (String(data[key])!==String(tar[key])){
                         if (!temp[key]) temp[key] = this.auditList.mapping.storage[key];
-                        data[key] = this.transformData(data[key],key)+this.transformData(tar[key],key);
-                    }else data[key] = this.transformData(data[key],key);
+                        data[key] = this.transformData(tar,key)+font+this.transformData(data,key,true)+"</div>";
+                    }else data[key] = this.transformData(data,key);
                 }
-                if (data["price"]!==tar["price"]){
-
+                if (String(data["price"])!==String(tar["price"]) && String(data["amount_interval"])===String(tar["amount_interval"])){
+                    data["amount_interval"] = this.transformData(tar,"amount_interval")+font+this.transformData(data,"amount_interval",true)+"</div>";
                 }
             });
             this.auditList.mapping.storage = temp;
+            temp={"name":"名称",child:{strategy:"子策略"}};
+            this.auditList.operation.U.forEach(data=>{
+                let tar = this.auditList.operation.H[data.target_id];
+                for (let key in this.auditList.mapping.operation){
+                    if (String(data[key])!==String(tar[key])){
+                        if (!temp[key]) temp[key] = this.auditList.mapping.operation[key];
+                        data[key] = this.transformData(tar,key)+font+this.transformData(data,key,true)+"</div>";
+                    }else data[key] = this.transformData(data,key);
+                }
+                let itemTem = {};
+                tar.items.forEach(item=>{
+                    if (!itemTem[item.strategy])itemTem[item.strategy] = [];
+                    itemTem[item.strategy].push(item);
+                });
+                let items = [];
+                let amount = 0;
+
+                data.items.forEach(item=>{
+                    if (itemTem[item.strategy]){
+                        let mark = true;
+                        for (let i=0;i<itemTem[item.strategy].length;i++){
+                            for (let key in this.auditList.mapping.operation.child){
+                                let oldStr = itemTem[item.strategy][i][key];
+                                let newStr = item[key];
+                                if (String(newStr)!==String(oldStr)){
+                                    mark = false;break;
+                                }
+                            }
+                            if (mark){
+                                item.operation = "H";
+                                itemTem[item.strategy].splice(i,1);
+                                if (itemTem[item.strategy].length===0)itemTem[item.strategy] = null;
+                                break;
+                            }
+                        }
+                    }//去重
+                });
+                data.items.forEach(item=>{
+                    if (item.operation!=='H'){
+                        if (!itemTem[item.strategy]){
+                            for (let key in this.auditList.mapping.operation.child)item[key] = this.transformData(item,key);
+                            item.operation = "C";
+                            items.unshift(item);
+                            amount++;
+                        }else{
+                            let tar = item.strategy;
+                            for (let key in this.auditList.mapping.operation.child){
+                                if (String(item[key])!==String(itemTem[tar][0][key])){
+                                    if (!temp.child[key]) temp.child[key] = this.auditList.mapping.operation.child[key];
+                                    item[key] = this.transformData(itemTem[tar][0],key)+font+this.transformData(item,key,true)+"</div>";
+                                }else item[key] = this.transformData(item,key);
+                            }
+                            item.operation = "U";
+                            items.push(item);
+                            itemTem[tar].splice(0,1);
+                            if (itemTem[tar].length===0) itemTem[tar] = null;
+                        }
+                    }
+                });
+                for (let key in itemTem){
+                    if (itemTem[key]){
+                        itemTem[key].forEach(item=>{
+                            for (let key in this.auditList.mapping.operation.child)item[key] = this.transformData(item,key);
+                            item.operation = "D";
+                            items.splice(amount,0,item);
+                            amount++;
+                        });
+                    }
+                }
+                data.items = items;
+            });
+            this.auditList.mapping.operation = temp;
+            temp={"name":"名称",child:{province_id:"省"}};
+            this.auditList.express.U.forEach(data=> {
+                let tar = this.auditList.express.H[data.target_id];
+                for (let key in this.auditList.mapping.express) {
+                    if (String(data[key]) !== String(tar[key])) {
+                        if (!temp[key]) temp[key] = this.auditList.mapping.express[key];
+                        data[key] = this.transformData(tar, key) + font + this.transformData(data, key, true) + "</div>";
+                    } else data[key] = this.transformData(data, key);
+                    if (String(data["amount_interval"])!==String(tar["amount_interval"]) && String(data["weight_interval"])===String(tar["weight_interval"])){
+                        data["weight_interval"] = this.transformData(tar,"weight_interval")+font+this.transformData(data,"weight_interval",true)+"</div>";
+                    }
+                }
+                let itemTem = {};
+                tar.details.forEach(item => {itemTem[item.province_id] = item;});
+                let items = [];
+                let amount = 0;
+                data.details.forEach(item=>{
+                    if (!itemTem[item.province_id]){
+                        for (let key in this.auditList.mapping.express.child)item[key] = this.transformData(item,key);
+                        item.operation = "C";
+                        items.unshift(item);
+                        amount++;
+                    }else{
+                        let mark = true;
+                        for (let key in this.auditList.mapping.express.child){
+                            if (String(item[key])!==String(itemTem[item.province_id][key])){
+                                mark = false;break;
+                            }
+                        }
+                        if (!mark){
+                            let tar = item.province_id;
+                            for (let key in this.auditList.mapping.express.child) {
+                                if (String(item[key]) !== String(itemTem[tar][key])) {
+                                    if (!temp.child[key]) temp.child[key] = this.auditList.mapping.express.child[key];
+                                    item[key] = this.transformData(itemTem[tar], key) + font + this.transformData(item, key, true) + "</div>";
+                                } else item[key] = this.transformData(item, key);
+                            }
+                            item.operation = "U";
+                            items.push(item);
+                            delete itemTem[tar];
+                        }else delete itemTem[item.province_id];
+
+                    }
+                });
+                for (let key in itemTem){
+                    for (let k in this.auditList.mapping.express.child)itemTem[key][k] = this.transformData(itemTem[key],k);
+                    itemTem[key].operation = "D";
+                    items.splice(amount,0,itemTem[key]);
+                    amount++;
+                }
+                data.details = items;
+            });
+            this.auditList.mapping.express = temp;
+            temp={name:"名称",child:{province_id:"省份",city_id:"城市"}};
+            this.auditList.logistic.U.forEach(data=> {
+                let tar = this.auditList.logistic.H[data.target_id];
+                for (let key in this.auditList.mapping.logistic) {
+                    if (String(data[key]) !== String(tar[key])) {
+                        if (!temp[key]) temp[key] = this.auditList.mapping.logistic[key];
+                        data[key] = this.transformData(tar, key) + font + this.transformData(data, key, true) + "</div>";
+                    } else data[key] = this.transformData(data, key);
+                }
+                let itemTem = this.logisticDataFormat(tar);
+                let dataTem = this.logisticDataFormat(data);
+                let items = [];
+                console.log(itemTem,dataTem)
+                for (let key in itemTem){
+                    if (dataTem[key]){
+                        for (let key2 in itemTem[key]){
+                            if (dataTem[key][key2]){
+                                for (let key3 in itemTem[key][key2]){
+                                    if (dataTem[key][key2][key3]){
+                                        for (let key4 in itemTem[key][key2][key3]){
+                                            if (dataTem[key][key2][key3][key4]){
+                                                let mark = true;
+                                                for (let key5 in this.auditList.mapping.logistic.child){
+                                                    if (String(dataTem[key][key2][key3][key4][key5]) !== String(itemTem[key][key2][key3][key4][key5])){
+                                                        if (!temp.child[key5]) temp.child[key5] = this.auditList.mapping.logistic.child[key5];
+                                                        mark=false;
+                                                        if (!temp.child[key5]) temp.child[key5] = this.auditList.mapping.logistic.child[key5];
+                                                        dataTem[key][key2][key3][key4][key5] = this.transformData(itemTem[key][key2][key3][key4], key5) + font + this.transformData(dataTem[key][key2][key3][key4], key5, true) + "</div>";
+                                                    } else dataTem[key][key2][key3][key4][key5] = this.transformData(dataTem[key][key2][key3][key4], key5);
+                                                }
+                                                if (!mark){
+                                                    dataTem[key][key2][key3][key4].operation = "U";
+                                                    items.push(dataTem[key][key2][key3][key4])
+                                                }
+                                                delete dataTem[key][key2][key3][key4];
+                                                delete itemTem[key][key2][key3][key4];
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                dataTem = this.logisticDataRestore(dataTem,"C");
+                dataTem.push.apply(dataTem,this.logisticDataRestore(itemTem,"D"));
+                dataTem.push.apply(dataTem,items);
+                data.details = dataTem;
+                console.log(data.details)
+            });
+            this.auditList.mapping.logistic = temp;
         },
         methods:{
-            transformData(val,key){
-                if (!val)return;
+            transformData(data,key,font=false){
+                if (!data[key])return;
+                let html = '<div class="float-left small ';
+                if (font)html += "text-primary font-weight-bold";
+                else html += "text-secondary";
+                html+='">';
                 switch (key) {
-                    case 'tax_rate_id':
-                        val += "%";
-                        break;
                     case "amount_interval":
-                        let html = '<div class="float-left">';
-                        val.forEach((am,i)=>{
-                            html += "<small>"+am+"-"+val[i+1]+"("+data["price"][i]+"元)</small>";
+                        data[key].forEach((am,i)=>{
+                            if (i!==data[key].length-1) html += "<span>"+am+"-"+data[key][i+1]+"("+data["price"][i]+"元)<br></span>";
                         });
-                        html += "<small>"+val[val.length-1]+" +("+data["price"][val.length-1]+"元)</small></div>";
-                        val = html;
+                        html += "<span>"+data[key][data[key].length-1]+" +("+data["price"][data[key].length-1]+"元)<br></span></div>";
+                        return html;
+                    case "total_discount_price":
+                        data[key].forEach(am=>{
+                            html += '<span>'+am+'元<br></span>'
+                        });
+                        return html+"</div>";
+                    case "discount_price":
+                        data[key].forEach(am=>{
+                            html += '<span>'+am+'元<br></span>'
+                        });
+                        return html+"</div>";
+                    case "discount_count":
+                        data[key].forEach((am,i)=>{
+                            if (i!==data[key].length-1)html += '<span>'+am+'-'+data[key][i+1]+'<br></span>'
+                        });
+                        html += '<span>'+data[key][data[key].length-1]+'&nbsp;+<br></span>';
+                        return html+"</div>";
+                    case "weight_interval":
+                        data[key].forEach((arr,i)=>{
+                            if (i!==data[key].length-1) html += '<span>'+data.amount_interval[i]+'-'+data.amount_interval[i+1]+'/单(';
+                            arr.forEach((w,j)=>{
+                                if (j!==arr.length-1)html += w+'-'+arr[j+1]+'/KG,';
+                            });
+                            html += (arr[arr.length-1] ? arr[arr.length-1] : 0)+'&nbsp;+/KG)<br></span>';
+                        });
+                        html += '<span>'+data.amount_interval[data.amount_interval.length-1]+'&nbsp;+/单(';
+                        let arr = data.weight_interval[data.weight_interval.length-1];
+                        arr.forEach((w,j)=>{
+                            if (j!==arr.length-1)html += w+'-'+arr[j+1]+'/KG,';
+                        });
+                        html += (arr[arr.length-1] ? arr[arr.length-1] : 0)+'&nbsp;+/KG)<br></span>';
+                        return html;
+                    case "initial_weight_price":
+                        data[key].forEach(arr=>{
+                            html += "<div class='float-left'>"+arr+"<br></div>";
+                        });
+                        return html;
+                    case "additional_weight_price":
+                        data[key].forEach(arr=>{
+                            html += "<div class='float-left'>"+arr+"<br></div>";
+                        });
+                        return html;
+                    case "unit_range":
+                        data[key].forEach(r=>{
+                            html += '<span class="small">'+r+'<br></span>';
+                        });
+                        return html;
+                    case "other_unit_range":
+                        data[key].forEach(r=>{
+                            html += '<span class="small">'+r+'<br></span>';
+                        });
+                        return html;
                 }
-                return val;
+                return html+= data[key]+"</div>";
+            },
+            logisticDataFormat(tar){
+                let obj={};
+                tar.details.forEach(item => {
+                    if (obj[item.province_id]){
+                        if (obj[item.province_id][item.city_id]){
+                            if (obj[item.province_id][item.city_id][item.unit_id]){
+                                obj[item.province_id][item.city_id][item.unit_id][item.range] = item;
+                            }else{
+                                let arr1={};
+                                arr1[item.range] = item;
+                                obj[item.province_id][item.city_id][item.unit_id] = arr1;
+                            }
+                        }else{
+                            let arr1={};
+                            arr1[item.range] = item;
+                            let arr2={};
+                            arr2[item.unit_id] = arr1;
+                            obj[item.province_id][item.city_id] = arr2;
+                        }
+                    }else{
+                        let arr1={};
+                        arr1[item.range] = item;
+                        let arr2={};
+                        arr2[item.unit_id] = arr1;
+                        let arr3={};
+                        arr3[item.city_id] = arr2;
+                        obj[item.province_id] = arr3;
+                    }
+                });
+                return obj;
             },
+            logisticDataRestore(tar,type,items=[],count=0){
+                if (count===4){
+                    tar["operation"] = type;
+                    items.push(tar);
+                } else{
+                    count++;
+                    for (let key in tar){
+                        this.logisticDataRestore(tar[key],type,items,count);
+                    }
+                }
+                return items;
+            }
         },
     });
 </script>