Просмотр исходного кода

Merge branch 'zzd'

# Conflicts:
#	app/Http/Controllers/TestController.php
zhouzhendong 4 лет назад
Родитель
Сommit
aa698deb92

+ 1 - 1
app/Batch.php

@@ -12,7 +12,7 @@ class Batch extends Model
     use ModelLogChanging;
 
     protected $fillable = [
-        'id','code','type', 'wms_type', 'status', 'wms_status', 'wms_created_at',"remark","owner_id",
+        'id','code','type', 'wms_type', 'status', 'wms_status', 'wms_created_at',"remark","owner_id","split_size"
     ];
 
     const WMS_STATUS = [

+ 95 - 8
app/Http/Controllers/TestController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use App\Authority;
 use App\Batch;
 use App\Commodity;
+use App\CommodityBarcode;
 use App\CommodityMaterialBoxModel;
 use App\Components\AsyncResponse;
 use App\Components\Database;
@@ -12,6 +13,7 @@ use App\Components\ErrorPush;
 use App\ErrorTemp;
 use App\Feature;
 use App\Http\ApiControllers\LoginController;
+use App\Http\Controllers\api\thirdPart\haochuang\SortingController;
 use App\Http\Controllers\api\thirdPart\syrius\beans\StorageTypeCell;
 use App\Http\Controllers\api\thirdPart\syrius\beans\StorageTypeRelation;
 use App\Http\Controllers\api\thirdPart\syrius\beans\Task;
@@ -23,7 +25,6 @@ use App\Http\Requests\AndroidGateRequest;
 use App\Http\Requests\OrderDelivering;
 use App\Jobs\BatchTaskJob;
 use App\Jobs\CacheShelfTaskJob;
-use App\Jobs\LogisticYDSync;
 use App\Jobs\OrderCreateInstantBill;
 use App\Jobs\OrderCreateWaybill;
 use App\Jobs\SettlementBillReportJob;
@@ -40,13 +41,16 @@ use App\Notifications\RoutineNotification;
 use App\OracleDOCASNHeader;
 use App\OracleDOCOrderHeader;
 use App\OracleDocOrderPackingSummary;
+use App\OracleDOCWaveDetails;
 use App\Order;
 use App\OrderBin;
+use App\OrderCommodity;
 use App\OrderIssue;
 use App\OrderIssueProcessLog;
 use App\OrderPackage;
 use App\Owner;
 use App\OwnerAreaReport;
+use App\OwnerBillReport;
 use App\OwnerFeeDetail;
 use App\OwnerFeeDetailLogistic;
 use App\OwnerFeeExpress;
@@ -57,16 +61,18 @@ use App\OwnerFeeStorage;
 use App\OwnerPriceExpress;
 use App\OwnerPriceOperation;
 use App\OrderPackageCountingRecord;
-use App\OwnerUserWorkgroupArchive;
+use App\OwnerReport;
 use App\ProcurementCheckSheet;
 use App\RejectedBill;
 use App\SeeLog;
 use App\Services\AuthorityService;
 use App\Services\BatchService;
 use App\Services\CacheShelfService;
+use App\Services\common\BatchUpdateService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Services\ForeignZhenCangService;
 use App\Services\LogisticService;
+use App\Services\LogService;
 use App\Services\NotificationService;
 use App\Services\OracleDOCOrderHeaderService;
 use App\Services\OrderPackageCommoditiesService;
@@ -76,6 +82,7 @@ use App\Services\OrderService;
 use App\Services\OwnerFeeTotalService;
 use App\Services\OwnerLogisticFeeReportService;
 use App\Services\OwnerPriceOperationService;
+use App\Services\OwnerService;
 use App\Services\OwnerStoreFeeReportService;
 use App\Services\OwnerStoreOutFeeReportService;
 use App\Services\ReviewService;
@@ -83,6 +90,7 @@ use App\Services\StationService;
 use App\Services\StorageService;
 use App\Services\StoreService;
 use App\Services\SyriusTaskService;
+use App\SortingStation;
 use App\Station;
 use App\StationTask;
 use App\StationTaskMaterialBox;
@@ -100,6 +108,7 @@ use Carbon\Carbon;
 use Carbon\CarbonPeriod;
 use Decimal\Decimal;
 use Doctrine\DBAL\Exception;
+use Firebase\JWT\ExpiredException;
 use Firebase\JWT\JWT;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
@@ -289,9 +298,92 @@ class TestController extends Controller
     }
     use Signature;
     private static $delayedHour = 48;
+    function process(Request $request): array
+    {
+        $station_id = $request->input('station_id');
+        $batch_id = $request->input('batch_id');
+        $childIndex = null;
+        $arr = explode('-',$batch_id);
+        if (count($arr)==2){
+            $batch_id = $arr[0];
+            $childIndex = (int)$arr[1];
+        }
+
+        $s = new SortingController();
+        // 同步orderCommodity
+        $s->syncOrder($batch_id);
+
+        /** @var Batch|\stdClass $batch */
+        $batch=Batch::query()->where('code',$batch_id)->orderBy('id','desc')->first();
+        $data=[
+            'result'=>'success',
+            'station_id'=>$station_id,
+            'batch_id'=>$batch_id,
+            'orders'=>[]
+        ];
+        if ($childIndex!==null && $batch->split_size){
+            $start = (($childIndex-1)*$batch->split_size)+1;
+            $end = $childIndex*$batch->split_size;
+            $sql = <<<SQL
+SELECT ORDERNO
+FROM (SELECT T.ORDERNO, ROWNUM AS NO
+FROM (SELECT ORDERNO FROM DOC_WAVE_DETAILS WHERE WAVENO = '{$batch_id}' ORDER BY SEQNO) T)
+WHERE NO BETWEEN {$start} AND {$end}
+SQL;
+            $waves = DB::connection("oracle")->select(DB::raw($sql));
+            $codes = array_column($waves,'orderno');
+            $orders = Order::query()->whereIn("code",$codes)->get();
+        }else $orders = $batch->orders()->get();
+
+        $ordersSorted=$orders->sortBy(function(Order $order){
+            return $order->bin()->first()['number'];
+        });
+        $ordersSorted->each(function(Order $order)use(&$data,$request){
+            if($order['status']=='取消')return;
+            $orderData=[
+                'order_id'=>$order['code'],
+                'owner'=>$order->owner()->first()['code'],
+                'status'=>$order['status']=='未处理'?'available':$order['status'],
+                'created_at'=>$order['created_at']->toDateTimeString(),
+                'bin'=>(function()use($order){
+                    $bin=$order->bin()->first()['number']??'';
+                    if(!$bin){
+                        $bin=OracleDOCWaveDetails::query()->where('orderno', 'SO201230003574')->get('seqno')->first()['seqno']??'';
+                        dump('BIN 缺失');
+                        return $bin;
+                    }
+                    return $bin;
+                })(),
+                'barcodes'=>[]
+            ];
+            $order->orderCommodities()->each(function(OrderCommodity $orderCommodity)use(&$orderData,$request){
+                $commodity=$orderCommodity->commodity()->first();
+                if(!$commodity){
+                    dump("没订单");
+                    return;
+                }
+                $barcodeStr=$commodity->barcodes()->get()->map(function(CommodityBarcode $barcode){
+                    return $barcode['code'];
+                })->filter(function($code){
+                    return $code&&(!preg_match('/[\x{4e00}-\x{9fa5}]/u',$code));
+                })->join(',');
+                $orderData['barcodes'][]=[
+                    'id'=>$orderCommodity['id']??'',
+                    'barcode_id'=>$barcodeStr??'',
+                    'name'=>$commodity['name']??'',
+                    'sku'=>$commodity['sku']??'',
+                    'amount'=>$orderCommodity['amount']??'',
+                    'location'=>$orderCommodity['location']??'',
+                ];
+            });
+            $data['orders'][]=$orderData;
+        });
+        return $data;
+    }
     public function test(Request $request)
     {
-
+        $request->offsetSet("station_id",'123456789');
+        dd($this->process($request));
         echo 'Now memory_get_usage: ' . memory_get_usage() . '<br />';
         $t1 = microtime(true);
 // ... 执行代码 ...
@@ -770,9 +862,4 @@ sql;
        $foreignZhenCangService=app('ForeignZhenCangService');;
        $foreignZhenCangService->broadcastBatch($batches);
     }
-
-    public function clear_logistic_yd_sync_register_cache_flag()
-    {
-        Cache::tags([LogisticYDSync::TAG])->flush();
-    }
 }

+ 64 - 0
app/Http/Controllers/WaveController.php

@@ -159,4 +159,68 @@ class WaveController extends Controller
         return $wms_status;
     }
 
+    public function split()
+    {
+        $codes = \request("codes",[]);
+        $splitSize = \request("splitSize");
+        if (!$codes || !$splitSize)$this->error("无记录");
+        if (!is_numeric($splitSize) || !is_int((int)$splitSize))$this->error("非法输入");
+        $size = Batch::query()->whereIn("code",$codes)->whereNull("split_size")->count();
+        if ($size!=count($codes))$this->error("波次不全或不允许二次分割");
+        Batch::query()->whereIn("code",$codes)->whereNull("split_size")->update([
+            "split_size" => $splitSize
+        ]);
+        $this->success();
+    }
+
+    public function printChild()
+    {
+        $codes = \request("codes",[]);
+        if (!$codes)$this->error("无记录");
+        $batches = [];
+        foreach (Batch::query()->select("code","split_size")->withCount("orders")
+                     ->whereIn("code",$codes)->whereNotNull("split_size")->get() as $batch){
+            if ($batch->orders_count==0)continue;
+            $batches[$batch->code] = (int)ceil($batch->orders_count/$batch->split_size);
+        }
+        $this->success($batches);
+    }
+
+    public function picking()
+    {
+        return view("order/wave/picking");
+    }
+
+    public function loadBatch()
+    {
+        $code = \request("code");
+        $batch = null;
+        if (!$code || !$batch = Batch::query()->select("id")->where("code",$code)->first())$this->error("无记录");
+        $sql = <<<SQL
+SELECT a.ORDERNO,a.QTY,s.ALTERNATE_SKU1 FROM ACT_ALLOCATION_DETAILS a
+    LEFT JOIN DOC_ORDER_HEADER o ON a.ORDERNO = o.ORDERNO
+    LEFT JOIN DOC_WAVE_DETAILS w ON o.ORDERNO = w.ORDERNO
+    LEFT JOIN BAS_SKU s ON a.SKU = s.SKU
+WHERE w.WAVENO = '{$code}' ORDER BY w.SEQNO;
+SQL;
+        $orders = DB::connection("oracle")->select(DB::raw($sql));
+        $result = [];
+        $currentList = [];
+        $slowPointer = 0;
+        $nodeSign = "";
+        foreach ($orders as $order){
+            if ($order->orderno!=$nodeSign){
+                if ($slowPointer==$batch->split_size){
+                    $result[] = $currentList;
+                    $currentList = [];
+                    $slowPointer = 0;
+                }
+                $slowPointer++;
+                $nodeSign = $order->orderno;
+            }
+            $currentList[] = ["barcode"=>$order->alternate_sku1,"qty"=>$order->qty];
+        }
+        if ($currentList)$result[] = $currentList;
+        $this->success($result);
+    }
 }

+ 22 - 2
app/Http/Controllers/api/thirdPart/haochuang/SortingController.php

@@ -70,11 +70,17 @@ class SortingController extends Controller
 //        if(!UserToken::getUser($token)){
 //            return ['result'=>'unauthority','fail_info'=>'无效令牌或令牌过期'];
 //        }
+        $childIndex = null;
+        $arr = explode('-',$batch_id);
+        if (count($arr)==2){
+            $batch_id = $arr[0];
+            $childIndex = (int)$arr[1];
+        }
 
         // 同步orderCommodity
         $this->syncOrder($batch_id);
 
-        /** @var Batch $batch */
+        /** @var Batch|\stdClass $batch */
         $batch=Batch::query()->where('code',$batch_id)->orderBy('id','desc')->first();
         $data=[
             'result'=>'success',
@@ -82,7 +88,21 @@ class SortingController extends Controller
             'batch_id'=>$batch_id,
             'orders'=>[]
         ];
-        $ordersSorted=$batch->orders()->get()->sortBy(function(Order $order){
+        if ($childIndex!==null && $batch->split_size){
+            $start = (($childIndex-1)*$batch->split_size)+1;
+            $end = $childIndex*$batch->split_size;
+            $sql = <<<SQL
+SELECT ORDERNO
+FROM (SELECT T.ORDERNO, ROWNUM AS NO
+FROM (SELECT ORDERNO FROM DOC_WAVE_DETAILS WHERE WAVENO = '{$batch_id}' ORDER BY SEQNO) T)
+WHERE NO BETWEEN {$start} AND {$end}
+SQL;
+            $waves = DB::connection("oracle")->select(DB::raw($sql));
+            $codes = array_column($waves,'orderno');
+            $orders = Order::query()->whereIn("code",$codes)->get();
+        }else $orders = $batch->orders()->get();
+
+        $ordersSorted=$orders->sortBy(function(Order $order){
             return $order->bin()->first()['number'];
         });
         $ordersSorted->each(function(Order $order)use(&$data,$request){

+ 32 - 0
database/migrations/2021_11_08_152146_change_batches_add_column_partition_size.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangeBatchesAddColumnPartitionSize extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('batches', function (Blueprint $table) {
+            $table->integer("split_size")->nullable()->comment("分割大小");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('batches', function (Blueprint $table) {
+            $table->dropColumn("split_size");
+        });
+    }
+}

+ 7 - 0
resources/views/order/wave/_printBody.blade.php

@@ -0,0 +1,7 @@
+<div class="container" style="min-width: 400px;min-height: 600px" id="printContent" v-show="infoShow">
+    <div class="card">
+        <div class="card-body mt-4 text-center" v-for="(value, key) in splitGroupBySize">
+            <div v-for="index in value"><img class="mt-1" :id="key+'-'+index" alt="#" src="#"></div>
+        </div>
+    </div>
+</div>

+ 18 - 0
resources/views/order/wave/_split.blade.php

@@ -0,0 +1,18 @@
+<div class="modal fade" id="splitBatch" tabindex="-1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog modal-dialog-centered" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <div class="text-center font-weight-bold">分割波次</div>
+                <button type="button" class="close" data-dismiss="modal">&times;</button>
+            </div>
+            <div class="modal-body">
+                <div class="form-group m-5">
+                    <input class="form-control" type="number" step="1" v-model="splitSize" placeholder="子波次大小">
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button class="col-12 btn btn-primary" @click="splitBatch()">确定</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 109 - 0
resources/views/order/wave/picking.blade.php

@@ -0,0 +1,109 @@
+@extends('layouts.app')
+@section('title')波次分拣@endsection
+@section('content')
+    <div id="container" class="d-none container-fluid mt-2">
+        <div class="card">
+            <div class="card-header">
+                <b>波次信息</b>
+                <button  class="btn text-white btn-sm btn-info pull-right" @click="isShow=!isShow" data-toggle="collapse" data-target="#body">@{{ isShow ? '隐藏' : '显示' }}</button>
+            </div>
+            <div class="card-body collapse" id="body">
+                <div v-for="(val,index) in waves" class="mt-2">
+                    <div class="card-title font-weight-bold mb-0">@{{ batch+'-'+(index+1) }}</div>
+                    <div class="card-text text-muted small">
+                        <div v-for="(obj,i) in val" class="row m-0" style="border-bottom: RGB(247,247,247) 1px solid">
+                            <span class="col-6">@{{ obj.barcode }}</span>
+                            <span class="col-6">@{{ obj.qty }}</span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="card mt-2">
+                <div class="card-header row m-0">
+                    <b class="col-4">分拣信息</b>
+                    <input id="barcode" v-model="barcode" @keydown.enter="searchBarcode()" class="form-control form-control-sm rounded-pill col-6 offset-2" placeholder="条码"></input>
+                </div>
+                <div class="card-body">
+                    <div class="row border-info" style="height:60vh;overflow-y: auto">
+                        <div class="col-5 m-2 p-0" style="height: 80px;border: 1px solid #aaaaaa;z-index:100;position:relative;" v-for="index in waves.length"
+                             :style="[waveQtyMap['_'+(index-1)] && waveQtyMap['_'+(index-1)]>0 ? {boxShadow: '0 0 5px 5px rgba(19,193,137)'} : '']">
+                            <div class="text-center small font-weight-bold text-secondary">@{{ batch+'-'+index }}</div>
+                            <div style="display:flex;align-items:center;justify-content:center;" class="w-100 h-75 text-primary font-weight-bold">
+                                @{{ waveQtyMap['_'+(index-1)] ? waveQtyMap['_'+(index-1)] : '0' }}
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="bg-white w-100 row" id="searchBlock" style="position: fixed;top:0;left:0;
+            width: 100%; text-align: center; border-radius: 3px;">
+            <div class="position-relative offset-2 col-9 mt-3 mb-3">
+                <input id="loadBatch" class="form-control form-control-sm w-100 rounded-pill" @keydown.enter="loadBatch()" v-model="batch" type="text" placeholder="波次号"></input>
+                <a id="search" @click="loadBatch()"><button type="button" class="border btn btn-sm btn-primary text-white rounded-pill position-absolute" style="top: 0;right: 12px;">开始分拣</button></a>
+            </div>
+        </div>
+    </div>
+@endsection
+
+@section('lastScript')
+    <script>
+        new Vue({
+            el:"#container",
+            data:{
+                batch:"",
+                isShow:false,
+                waves:[],
+                waveQtyMap:{},
+            },
+            mounted:function(){
+                this.pageInit();
+                setTimeout(()=>{
+                    $("#container").removeClass('d-none');
+                },100);
+                setTimeout(()=>{
+                    $("#loadBatch").focus();
+                },200);
+            },
+            methods:{
+                //页面初始化
+                pageInit(){
+                    let element = document.getElementById("navbarSupportedContent").parentElement;
+                    element.className = "row";
+                    element.children[0].className += " col-5";
+                    element.children[0].href = "#";
+                    element.innerHTML = element.children[0].outerHTML;
+                    let e1 = document.getElementById("menu");
+                    let e2 = document.getElementById("demand-div");
+                    //let e3 = document.getElementsByClassName("navbar");
+                    if (e1)e1.remove();
+                    if (e2)e2.remove();
+                    //if (e3.length>0)e3[0].remove();
+                    element = document.getElementById("container");
+                    if (element)element.style.height = (window.innerHeight-100)+"px";
+                },
+                loadBatch(){
+                    window.tempTip.postBasicRequest("{{url('order/wave/loadBatch')}}",{code:this.batch},res=>{
+                        this.waves = res;
+                        $("#barcode").focus();
+                    })
+                },
+                searchBarcode(){
+                    let waveQtyMap = {};
+                    this.waves.forEach((wave,i)=>{
+                        wave.forEach(order=>{
+                            if (order.barcode === this.barcode){
+                                if (waveQtyMap['_'+i]===undefined)waveQtyMap['_'+i] = 1;
+                                else waveQtyMap['_'+i]++;
+                            }
+                        })
+                    })
+                    this.waveQtyMap = waveQtyMap;
+                    this.barcode = "";
+                    $("#barcode").focus();
+                },
+            }
+        });
+
+    </script>
+@endsection

+ 65 - 1
resources/views/order/wave/search.blade.php

@@ -40,6 +40,8 @@
 
 {{--                        <button type="button" class="btn btn-sm tooltipTarget btn-outline-dark" @click="batchCancelPrint">重置打印标记</button>--}}
                         <button type="button" class="btn btn-sm btn-outline-success" data-toggle="modal" data-target="#myModal">修复波次</button>
+                        <button type="button" class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#splitBatch">分割波次</button>
+                        <button type="button" class="btn btn-sm btn-outline-primary" @click="exePrint()">打印子波条码</button>
                     </td>
                 </tr>
 
@@ -95,10 +97,13 @@
                    :placeholder="'当前页数:'+'{{$param['currPage']}}'+'/'+'{{$param['pageTotal']}}'" title="去往指定页">
             <span class="text-muted m-1">共 {{$param['count']}} 条 </span>
         </div>
+        @include("order.wave._split")
+        @include("order.wave._printBody")
     </div>
 @endsection
 
 @section("lastScript")
+    <script type="text/javascript" src="{{mix('js/utilities/barcode.js')}}"></script>
     <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
     <script>
         let vueList = new Vue({
@@ -132,6 +137,9 @@
                 currPage:'{{$param['currPage']}}',
                 selectTr:'',
                 batchCodes:"",
+                splitSize:"",
+                infoShow:false,
+                splitGroupBySize:{},
             },
             mounted: function () {
                 $('#wave_div').removeClass('d-none')
@@ -275,7 +283,63 @@
                         return;
                     }
                     this.selectedWaveNo = waveNo;
-                }
+                },
+                splitBatch(){
+                    window.tempTip.setDuration(2000);
+                    if (this.checkData.length<1){
+                        window.tempTip.show("未选中记录行");
+                        return;
+                    }
+                    if (!this.splitSize){
+                        window.tempTip.show("未输入分割大小");
+                        return;
+                    }
+                    window.tempTip.postBasicRequest("{{url('order/wave/split')}}",{codes:this.checkData,split:this.splitSize},res=>{})
+                },
+                exePrint(){
+                    window.tempTip.setDuration(2000);
+                    if (this.checkData.length<1){
+                        window.tempTip.show("未选中记录行");
+                        return;
+                    }
+                    window.tempTip.postBasicRequest("{{url('order/wave/printChild')}}",{codes:this.checkData},res=>{
+                        this.splitGroupBySize = res;
+                        this.infoShow = true;
+                        setTimeout(()=>{
+                            for(let key  in this.splitGroupBySize){
+                                for (let i=1;i<=this.splitGroupBySize[key];i++){
+                                    window.setBarcode(key+'-'+i, "#"+key+"-"+i, 3, 70, true)
+                                }
+                            }
+                        },100);
+                        setTimeout(()=>{
+                            exe();
+                        },200);
+                    })
+                    let exe = ()=>{
+                        let iframe=document.getElementById("print-iframe");
+                        this.infoShow=true;
+                        if(!iframe){
+                            iframe = document.createElement('IFRAME');
+                            iframe.setAttribute("id", "print-iframe");
+                            iframe.setAttribute('style', 'position:absolute;width:0;height:0;left:-500px;top:-500px;');
+                            document.body.appendChild(iframe);
+                        }else iframe.contentWindow.document.getElementById("iframe-content").remove();
+                        let doc = iframe.contentWindow.document;
+                        let el = document.getElementById("printContent");
+                        doc.write('<LINK rel="stylesheet" type="text/css" href="{{ asset(mix("css/app.css")) }}">');
+                        doc.write('<div id="iframe-content">' + el.innerHTML + '</div>');
+                        doc.close();
+                        iframe.contentWindow.focus();
+                        this.infoShow=false;
+                        setTimeout(function () {
+                            iframe.contentWindow.print();
+                            if (navigator.userAgent.indexOf("MSIE") > 0){
+                                document.body.removeChild(iframe);
+                            }
+                        },200);
+                    };
+                },
             }
         });
     </script>

+ 1 - 0
resources/views/store/inStorage/androidIndex.blade.php

@@ -30,6 +30,7 @@
                 @can("入库管理-手持入库-收货")<a href="{{url('store/blindReceive')}}"><button class="btn btn-info w-75 h-25 mt-3 text-white" style="height: 60px"><h4>盲收</h4></button></a>@endcan
                 @can("运输管理-编辑")<a href="{{url('transport/waybill/android/shipment')}}"><button class="btn btn-info w-75 h-25 mt-3 text-white" style="height: 60px"><h4>运单发货</h4></button></a>@endcan
                 @can("运输管理-承运商调度")<a href="{{url('transport/waybill/delivering')}}"><button class="btn btn-info w-75 h-25 mt-3 text-white" style="height: 60px"><h4>运单调配</h4></button></a>@endcan
+                <a href="{{url('order/wave/picking')}}"><button class="btn btn-info w-75 h-25 mt-3 text-white" style="height: 60px"><h4>波次分拣</h4></button></a>
 
     <a href="{{ route('logout') }}" onclick="event.preventDefault();
                                                      document.getElementById('logout-form').submit();">

+ 4 - 0
routes/web.php

@@ -814,6 +814,10 @@ Route::group(['prefix'=>'package'],function(){
             Route::post('cancelPrinting','WaveController@cancelPrinting');
             Route::any('exportExcel','WaveController@exportExcelOnParams');
             Route::post('repairBatch','WaveController@repairBatch');
+            Route::post('split','WaveController@split');
+            Route::post('printChild','WaveController@printChild');
+            Route::get('picking','WaveController@picking');
+            Route::post('loadBatch','WaveController@loadBatch');
         });
         /** 问题件 */
         Route::group(['prefix'=>'issue'],function(){