Sfoglia il codice sorgente

Merge branch 'master' of ssh://baoshi56.com:10022/var/git/bswas into Haozi

haozi 5 anni fa
parent
commit
e523051994
100 ha cambiato i file con 2156 aggiunte e 768 eliminazioni
  1. 2 2
      .gitlab-ci.yml
  2. 51 0
      app/Console/Commands/CreateWeightStatistic.php
  3. 1 3
      app/Console/Commands/MakeTestCommand.php
  4. 43 13
      app/Console/Commands/SyncBatchTask.php
  5. 1 1
      app/Console/Commands/SyncOrderPackageLogisticRouteTask.php
  6. 3 0
      app/Console/Kernel.php
  7. 33 6
      app/Exceptions/Exception.php
  8. 5 1
      app/Filters/OrderIssueFilters.php
  9. 6 1
      app/Filters/OrderPackageFilters.php
  10. 74 2
      app/Http/Controllers/ControlPanelController.php
  11. 21 7
      app/Http/Controllers/OrderFreezeController.php
  12. 19 1
      app/Http/Controllers/RegionController.php
  13. 10 0
      app/Http/Controllers/SendEmailsController.php
  14. 62 191
      app/Http/Controllers/TestController.php
  15. 19 6
      app/Http/Controllers/api/thirdPart/haiq/PickStationController.php
  16. 8 10
      app/Http/Controllers/api/thirdPart/haiq/StorageController.php
  17. 35 0
      app/Http/Requests/ForeignHaiRobotic_processedRequest.php
  18. 1 1
      app/Http/Requests/ForeignHaiRobotic_taskUpdateRequest.php
  19. 4 1
      app/Jobs/OrderFreeze.php
  20. 15 2
      app/Order.php
  21. 14 6
      app/OrderFreeze.php
  22. 4 3
      app/OrderIssue.php
  23. 18 0
      app/OrderPackageCountingRecord.php
  24. 2 1
      app/OrderTracking.php
  25. 18 0
      app/Providers/AppServiceProvider.php
  26. 49 8
      app/Services/BatchService.php
  27. 2 2
      app/Services/CacheService.php
  28. 167 67
      app/Services/ForeignHaiRoboticsService.php
  29. 39 33
      app/Services/LogisticSFService.php
  30. 5 3
      app/Services/MaterialBoxService.php
  31. 2 1
      app/Services/OracleDOCOrderHeaderService.php
  32. 44 13
      app/Services/OracleDocWaveDetailService.php
  33. 22 22
      app/Services/OrderFreezeService.php
  34. 8 7
      app/Services/OrderPackageReceivedSyncService.php
  35. 2 2
      app/Services/OrderService.php
  36. 9 3
      app/Services/OrderTrackingService.php
  37. 3 2
      app/Services/OwnerPriceOperationService.php
  38. 3 3
      app/Services/PackageStatisticsService.php
  39. 30 6
      app/Services/RegionService.php
  40. 12 8
      app/Services/StationRuleBatchService.php
  41. 22 0
      app/Services/StationService.php
  42. 75 39
      app/Services/StationTaskBatchService.php
  43. 1 2
      app/Services/StationTaskBatchTypeService.php
  44. 73 20
      app/Services/StationTaskCommodityService.php
  45. 107 15
      app/Services/StationTaskMaterialBoxService.php
  46. 17 16
      app/Services/StationTaskService.php
  47. 9 0
      app/Services/StationTaskTypeService.php
  48. 9 0
      app/Services/StationTypeBinMonitorService.php
  49. 6 5
      app/Services/StationTypeService.php
  50. 1 1
      app/Services/WaybillService.php
  51. 6 3
      app/Station.php
  52. 3 2
      app/StationRuleBatch.php
  53. 27 3
      app/StationTask.php
  54. 7 6
      app/StationTaskBatch.php
  55. 1 1
      app/StationTaskChild.php
  56. 9 7
      app/StationTaskCommodity.php
  57. 21 4
      app/StationTaskMaterialBox.php
  58. 44 4
      app/Traits/TestMockSubServices.php
  59. 2 2
      config/api.php
  60. 2 1
      config/api_logistic.php
  61. 1 1
      database/factories/MaterialBoxFactory.php
  62. 6 3
      database/factories/OwnerFactory.php
  63. 0 12
      database/factories/StationMissionBatchFactory.php
  64. 0 12
      database/factories/StationMissionCommodityFactory.php
  65. 1 1
      database/factories/StationRuleBatchFactory.php
  66. 0 0
      database/factories/StationTaskBatchTypeFactory.php
  67. 1 1
      database/factories/StationTaskFactory.php
  68. 1 1
      database/factories/StationTaskMaterialBoxFactory.php
  69. 1 1
      database/factories/StationTypeFactory.php
  70. 6 1
      database/migrations/2020_11_30_140958_create_stations_table.php
  71. 44 0
      database/migrations/2020_12_24_155647_add_column_material_task_type_drop_station_mission_tables.php
  72. 30 0
      database/migrations/2020_12_29_182249_change_station_rule_batch_column_default_batch_type.php
  73. 45 0
      database/migrations/2021_01_06_114158_create_station_task_children2.php
  74. 0 36
      database/migrations/2021_01_08_112003_add_default_mail_event_role.php
  75. 36 0
      database/migrations/2021_01_21_100909_add_created_at_index_order_packages.php
  76. 36 0
      database/migrations/2021_01_21_132441_add_authorrities_mail.php
  77. 45 0
      database/migrations/2021_01_21_153513_add_column_station_task_id_for_all_sub_tasks.php
  78. 32 0
      database/migrations/2021_01_22_104216_add_column_frozen_to_orders.php
  79. 36 0
      database/migrations/2021_01_22_112931_change_order_freeze_table.php
  80. 32 0
      database/migrations/2021_01_25_104626_create_order_package_counting_records_table.php
  81. 32 0
      database/migrations/2021_01_26_172812_add_column_order_client_code_wms_to_order_trackings.php
  82. 3 2
      public/t.php
  83. 5 5
      resources/js/queryForm/queryForm.js
  84. 1 1
      resources/lang/cn/validation.php
  85. 19 0
      resources/sass/text.scss
  86. 105 4
      resources/views/control/panel.blade.php
  87. 2 1
      resources/views/customer/menu.blade.php
  88. 4 4
      resources/views/customer/project/create.blade.php
  89. 35 23
      resources/views/customer/project/part/_operation.blade.php
  90. 2 1
      resources/views/maintenance/menu.blade.php
  91. 59 43
      resources/views/maintenance/region/index.blade.php
  92. 48 8
      resources/views/order/index/_freezeModal.blade.php
  93. 133 18
      resources/views/order/index/freeze.blade.php
  94. 15 7
      resources/views/order/tracking/index.blade.php
  95. 1 0
      resources/views/package/logistic/index.blade.php
  96. 0 1
      resources/views/package/menu.blade.php
  97. 3 2
      resources/views/personnel/menu.blade.php
  98. 26 10
      resources/views/waybill/index.blade.php
  99. 1 0
      routes/apiLocal.php
  100. 1 0
      routes/web.php

+ 2 - 2
.gitlab-ci.yml

@@ -8,8 +8,8 @@ cache:
     - vendor/
 
 before_script:
-  - sudo cp ci/.envCi .env
-  - sudo bash ci/installEnv.sh
+#  - sudo cp ci/.envCi .env
+#  - sudo bash ci/installEnv.sh
 
 
 build:

+ 51 - 0
app/Console/Commands/CreateWeightStatistic.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Order;
+use App\OrderBin;
+use App\OrderPackageCountingRecord;
+use App\Services\BatchService;
+use App\Services\common\BatchUpdateService;
+use App\Services\DocWaveHeaderService;
+use App\Services\LogService;
+use App\ValueStore;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
+
+class CreateWeightStatistic extends Command
+{
+    protected $signature = 'create:weightStatistic';
+
+    protected $description = 'every day create weight statistic data';
+
+    public function handle()
+    {
+        $yesterday = date("Y-m-d",strtotime("-1 day"));
+        $sql = <<<sql
+SELECT DATE_FORMAT(created_at,'%Y-%m-%d') date,
+SUM(CASE WHEN weighed_at IS NOT NULL THEN 1 ELSE 0 END) AS count,
+COUNT(1) total FROM order_packages WHERE created_at BETWEEN '{$yesterday} 00:00:00' AND '{$yesterday} 23:59:59' GROUP BY date
+sql;
+        $result = DB::selectOne(DB::raw($sql));
+        if (!$result)$obj = [
+            "targeted_at"    => $yesterday,
+            "un_weigh_count" => 0,
+            "total_count"    => 0
+        ]; else $obj = [
+            "targeted_at"    => $result->date,
+            "un_weigh_count" => $result->count,
+            "total_count"    => $result->total,
+        ];
+        /** @var \stdClass $model */
+        $model = OrderPackageCountingRecord::query()->create($obj);
+        Cache::put("weight.".$yesterday,[
+            "date"=>$yesterday,
+            "total"=>$model->total_count,
+            "count"=>$model->un_weigh_count,
+            "value"=>$model->total_count ? intval(($model->un_weigh_count/$model->total_count)*100) : 0
+        ]);
+    }
+}

+ 1 - 3
app/Console/Commands/MakeTestCommand.php

@@ -56,9 +56,7 @@ class MakeTestCommand extends \Illuminate\Foundation\Console\TestMakeCommand
     }
     protected function getModelNamePlural()
     {
-        $modelName=preg_replace('/s$/','ses',lcfirst($this->getModelName()));
-        $modelName=preg_replace('/ch$/','ches',$modelName);
-        $modelName=preg_replace('/sh$/','shes',$modelName);
+        $modelName=preg_replace('/(s|x|ch|sh)$/','ses',lcfirst($this->getModelName()));
         $modelName=preg_replace('/y$/','ies',$modelName);
         $modelName=preg_replace('/[cC]hild$/','children',$modelName);
         if(preg_match('/[cC]hildren$/',$modelName)==0){

+ 43 - 13
app/Console/Commands/SyncBatchTask.php

@@ -77,18 +77,22 @@ sql
         $map = [];
         $batches = $this->batchService->get(["code"=>$codes]);
         if ($batches){
-            foreach ($batches as $batch)$map[$batch->code] = $batch->id;
+            foreach ($batches as $index=>$batch)$map[$batch->code] = $index;
         }
         $update = [["id","wms_status","remark","updated_at"]];
         $insert = [];
         foreach ($waves as $wave){
             if (isset($map[$wave->waveno])){
-                $update[] = [
-                    "id" => $map[$wave->waveno],
-                    "wms_status" => $this->wms_status($wave),
-                    "remark"=>$wave->descr,
-                    "updated_at"=>$wave->edittime,
-                ];
+                $bat = $batches[$map[$wave->waveno]];
+                $wms_status = $this->wms_status($wave);
+                if ($bat->wms_status != $wms_status || $bat->remark != $wave->descr){
+                    $update[] = [
+                        "id" => $bat->id,
+                        "wms_status" => $this->wms_status($wave),
+                        "remark"=>$wave->descr,
+                        "updated_at"=>$wave->edittime,
+                    ];
+                }
                 continue;
             }
             $owner = app("OwnerService")->codeGetOwner($wave->customerid);
@@ -106,7 +110,7 @@ sql
         //存在则更新
         if (count($update)>1){
             $bool = app(BatchUpdateService::class)->batchUpdate("batches",$update);
-            if ($bool)LogService::log(__METHOD__,"SUCCESS-同步更新波次成功",json_encode($update));
+            if ($bool!==false)LogService::log(__METHOD__,"SUCCESS-同步更新波次成功",json_encode($update));
             else LogService::log(__METHOD__,"ERROR-同步更新波次失败",json_encode($update));
         }
 
@@ -150,6 +154,7 @@ sql;
         $nos = [];
         $orderCodes = [];
         $seqnos = [];
+        $batchMapping = [];
         foreach ($details as $detail){
             if (isset($map[$detail->waveno]))$map[$detail->waveno][] = $detail->orderno;
             else {
@@ -158,9 +163,9 @@ sql;
             }
             $orderCodes[] = $detail->orderno;
             $seqnos[$detail->orderno] = $detail->seqno;
+            $batchMapping[$detail->orderno] = $detail->waveno;
         }
-        $orders = Order::query()->select("id","code")->whereIn("code",$orderCodes)->get();
-        if (count($orderCodes) != count($orders))LogService::log(__METHOD__,"波次同步-本地订单缺失",json_encode($orderCodes)." | ".count($orderCodes)." | ".count($orders));
+        $orders = Order::query()->select("id","batch_id","code")->whereIn("code",$orderCodes)->get();
         if ($orders){
             $orderIds = [];
             $orderMap = [];
@@ -180,10 +185,12 @@ sql;
                 if ($orderBin->number != $orderMap[$orderBin->order_id])$updateBin[]=["id"=>$orderBin->id,"number"=>$orderMap[$orderBin->order_id]];
                 unset($orderMap[$orderBin->order_id]);
             }
+            $d = date('Y-m-d H:i:s');
             foreach ($orderMap as $orderId=>$binNumber){
                 $insertBin[]=[
                     "order_id"=>$orderId,
-                    "number"=>$binNumber
+                    "number"=>$binNumber,
+                    'created_at' => $d
                 ];
             }
             if (count($updateBin)>1){
@@ -200,10 +207,31 @@ sql;
             }
         }
         $batches = $this->batchService->get(["code"=>$nos]);
+        $batchDiff = array_keys(array_flip(array_diff($nos,array_column($batches->toArray(),"code"))));
+        if (count($batchDiff)>0){
+            $sql = <<<sql
+SELECT * FROM DOC_WAVE_HEADER WHERE WAVENO IN (''
+sql;
+            foreach ($batchDiff as $bd)$sql .= ",'".$bd."'";
+            $sql .= ')';
+            $wmsBatches = DB::connection("oracle")->select(DB::raw($sql));
+            $this->headerExe($wmsBatches);
+            $batches = $this->batchService->get(["code"=>$nos]);
+        }
+        $updateOrder = [["code","batch_id"]];
         foreach ($batches as $batch){
-            app("OrderService")->update(["code"=>$map[$batch->code]],["batch_id"=>$batch->id]);
+            foreach ($map[$batch->code] as $on){
+                $updateOrder[] = [
+                    "code"=>$on,
+                    "batch_id"=>$batch->id
+                ];
+            }
             unset($map[$batch->code]);
         }
+        if (count($updateOrder)>1){
+            app("OrderService")->batchUpdate($updateOrder);//反向修改订单
+            LogService::log(__METHOD__,"波次同步-修改订单波次号",json_encode($updateOrder));
+        }
         if ($map){
             $waveCodes = array_keys($map);
             $waves = $this->service->get(["waveno"=>$waveCodes],["waveno"=>"in"]);
@@ -229,7 +257,9 @@ sql;
                 }
             }
         }
-        //        $this->batchService->assignTasks($batches);
+
+         $this->batchService->assignTasks($batches);    //在这里为波次注册任务!
+
         ValueStore::query()->where("name","wave_detail_last_sync_date")->update(["value"=>$details[count($details)-1]->edittime]);
     }
 

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

@@ -38,7 +38,7 @@ class SyncOrderPackageLogisticRouteTask extends Command
      */
     public function handle()
     {
-        ini_set('memory_limit','1226M');
+        ini_set('memory_limit','2226M');
         (new OrderPackageReceivedSyncService)->syncLogisticRoute();
     }
 }

+ 3 - 0
app/Console/Kernel.php

@@ -3,6 +3,7 @@
 namespace App\Console;
 
 use App\Console\Commands\ClearCancelledOrderTask;
+use App\Console\Commands\CreateWeightStatistic;
 use App\Console\Commands\FluxOrderFix;
 use App\Console\Commands\InventoryDailyLoggingOwner;
 use App\Console\Commands\LogExpireDelete;
@@ -42,6 +43,7 @@ class Kernel extends ConsoleKernel
         SyncWmsCommoditiesInformation::class,
         ClearCancelledOrderTask::class,
         WasSyncWmsAsnInformation::class,
+        CreateWeightStatistic::class,
     ];
 
     /**
@@ -66,6 +68,7 @@ class Kernel extends ConsoleKernel
         $schedule->command('SyncWmsCommoditiesInformation')->everyMinute();
         $schedule->command('clear:cancelledOrder')->everyTenMinutes();
         $schedule->command('WasSyncWmsAsnInformation')->everyMinute();
+        $schedule->command('create:weightStatistic')->dailyAt("00:30");
     }
 
     /**

+ 33 - 6
app/Exceptions/Exception.php

@@ -4,14 +4,41 @@
 namespace App\Exceptions;
 
 
+use App\Services\LogService;
+use Illuminate\Support\Facades\Auth;
 use Throwable;
 
 class Exception extends \Exception
 {
-        public $type;
-        public function __construct($message = "",$type='error', $code = 0, Throwable $previous = null)
-        {
-            parent::__construct($message, $code, $previous);
-            $this->type=$type;
-        }
+    public $type;
+    public function __construct($message = "",$type='error', $code = 0, Throwable $previous = null)
+    {
+        parent::__construct($message, $code, $previous);
+        $this->type=$type;
+        $this->logging();
+    }
+    public function logging()
+    {
+        $exception=$this;
+        list(
+            $className,
+            $functionName,
+            $tracesAll
+            )           =(function()use($exception){
+            $traces=method_exists($exception,'getTraceAsString')
+                ?($exception->getTraceAsString()??'')
+                :'';
+            if(!$traces)return '';
+            preg_match('/\#0.*?\: (.*?)(-\>|\:\:)(.*?)\(/', $traces, $result);
+            return [$result[1]??'',$result[3]??'',$traces];
+        })();
+        LogService::log(
+            $className,
+            $functionName,
+            ($exception->getMessage()??'')
+            .'调用堆栈:'.$tracesAll,
+            Auth::id()??'',
+            $this->type
+        );
+    }
 }

+ 5 - 1
app/Filters/OrderIssueFilters.php

@@ -412,7 +412,11 @@ class OrderIssueFilters
 
     public function final_status($final_status)
     {
-        $this->queryBuilder->where('order_issues.final_status',$final_status);
+        if($final_status === 'null')
+            $this->queryBuilder->whereNull('order_issues.final_status');
+        else
+            $this->queryBuilder->where('order_issues.final_status',$final_status);
+
     }
 
     public function finance_confirm($finance_confirm)

+ 6 - 1
app/Filters/OrderPackageFilters.php

@@ -13,7 +13,7 @@ class OrderPackageFilters
     protected $request;
     protected $queryBuilder;
     protected $filters = ['logistic_number', 'status', 'received_at_start',
-        'received_at_end', 'is_weighed', 'logistic_id', 'owner_id', 'sent_at_start', 'sent_at_end', 'is_exception'];
+        'received_at_end', 'is_weighed', 'logistic_id', 'owner_id', 'sent_at_start', 'sent_at_end', 'is_exception','default_date'];
 
     public function __construct(Request $request)
     {
@@ -90,4 +90,9 @@ class OrderPackageFilters
     {
         $this->queryBuilder->where('exception', $is_exception);
     }
+
+    public function default_date()
+    {
+        $this->queryBuilder->where('created_at', '>=',now()->startOfDay() ->subDays(15))->where('created_at', '<',now()->startOfDay()->addDay());
+    }
 }

+ 74 - 2
app/Http/Controllers/ControlPanelController.php

@@ -2,7 +2,10 @@
 
 namespace App\Http\Controllers;
 
+use App\Components\AsyncResponse;
+use App\OrderPackageCountingRecord;
 use App\Owner;
+use App\Services\CacheService;
 use App\Services\CheckActiveMenuService;
 use App\Services\LaborReportsCountingRecordService;
 use App\Services\NewOrderCountingRecordService;
@@ -10,13 +13,14 @@ use App\Services\RealtimePendingOrdersService;
 use App\Services\UserService;
 use App\User;
 use Carbon\Carbon;
-use DebugBar\DataFormatter\DataFormatter;
+use Carbon\CarbonPeriod;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
 
 class ControlPanelController extends Controller
 {
-
+    use AsyncResponse;
 
     /**
      * ControlPanelController constructor.
@@ -131,4 +135,72 @@ class ControlPanelController extends Controller
             return array_intersect($ownerIds, $permittingOwnerIds);
         });
     }
+
+    /**
+     * 获取称重统计数据API
+     */
+    public function weightApi()
+    {
+        //转化为Carbon
+        $start = Carbon::parse(request("start"));
+        $end   = Carbon::parse(request("end"));
+
+        //定义三个数组 空间换时间 避免结果集二次转换
+        $title = []; //标题
+        $data = []; //核心数据,二维数组
+        foreach (CarbonPeriod::create($start,$end) as $date){
+            /** @var $date Carbon */
+            $str = $date->format("Y-m-d");
+            $data[] = $this->getTargetData($str);
+            $title[] = $str;
+        }
+
+        //大于31天转换为月份显示
+        if ($end->diffInDays($start) > 31){
+            $title = [];
+            $sign = []; //标记是否已被插入
+            $dataTemp = []; //临时存储
+
+            foreach ($data as $datum){
+                $month = substr($datum["date"],0,7);
+                if (!isset($sign[$month])){
+                    $dataTemp[] = ["date"=>$month,"total"=>$datum["total"],"count"=>$datum["count"],"value"=>$datum["value"]];
+                    $title[] = $month;
+                    $sign[$month] = count($dataTemp)-1;
+                }else{
+                    $dataTemp[$sign[$month]]["total"] += $datum["total"];
+                    $dataTemp[$sign[$month]]["count"] += $datum["count"];
+                    $dataTemp[$sign[$month]]["value"] = (string)($dataTemp[$sign[$month]]["total"] ? intval(($dataTemp[$sign[$month]]["count"]/$dataTemp[$sign[$month]]["total"])*100) : 0);
+                }
+            }
+            $data = $dataTemp;
+        }
+        $this->success(["title"=>$title,"data"=>$data]);
+    }
+
+    /**
+     * 根据指定日期获取目标统计数据
+     *
+     * @param string $date
+     * @return array|null
+     */
+    private function getTargetData(string $date)
+    {
+        if ($date == date("Y-m-d")){
+            $sql = <<<sql
+SELECT DATE_FORMAT(created_at,'%Y-%m-%d') date,
+SUM(CASE WHEN weighed_at IS NOT NULL THEN 1 ELSE 0 END) AS count,
+COUNT(1) total FROM order_packages WHERE created_at >= '{$date} 00:00:00' GROUP BY date
+sql;
+
+            $pack = DB::selectOne(DB::raw($sql));
+            if (!$pack)return ["date"=>$date,"total"=>0,"count"=>0,"value"=>0];
+            return ["date"=>$pack->date,"total"=>$pack->total,"count"=>$pack->count,"value"=>(string)($pack->total ? intval(($pack->count/$pack->total)*100) : 0)];
+        }
+        return app(CacheService::class)->getOrExecute("weight.".$date,function ()use($date){
+            $count = OrderPackageCountingRecord::query()->where("targeted_at",$date)->first();
+            if (!$count)return ["date"=>$date,"total"=>0,"count"=>0,"value"=>0];
+            return ["date"=>$count->targeted_at,"total"=>$count->total_count,"count"=>$count->un_weigh_count,"value"=>(string)($count->total_count ? intval(($count->un_weigh_count/$count->total_count)*100) : 0)];
+        },config("cache.expirations.forever"));
+    }
 }

+ 21 - 7
app/Http/Controllers/OrderFreezeController.php

@@ -11,7 +11,7 @@ class OrderFreezeController extends Controller
     public function index()
     {
         $this->gate("订单管理-自动冻结");
-        $freezes = OrderFreeze::query()->with(["logistic:id,name","province:id,name","city:id,name","location:id,name"])
+        $freezes = OrderFreeze::query()->with(["logistic:id,name","province:id,name","city:id,name","district:id,name","town:id,name","street:id,name"])
             ->orderByDesc("id")->where("status",0)
             ->paginate(request("paginate") ?? 50);
         return view("order.index.freeze",compact("freezes"));
@@ -20,24 +20,38 @@ class OrderFreezeController extends Controller
     public function store()
     {
         $this->gate("订单管理-自动冻结");
-        $freeze = OrderFreeze::query()->where("logistic_id",request("logistic_id"))
-            ->where("province_id",request("province_id"))
-            ->where("city_id",request("city_id"))->where("status",0)
-            ->where("location_id",request("location_id"))->first();
+        $freeze = OrderFreeze::query()->where("logistic_id",request("logistic_id"))->where("status",0);
+        if (request("province_id"))$freeze->where("province_id",request("province_id"));
+        else $freeze->whereNull("province_id");
 
+        if (request("city_id"))$freeze->where("city_id",request("city_id"));
+        else $freeze->whereNull("city_id");
+
+        if (request("district_id"))$freeze->where("district_id",request("district_id"));
+        else $freeze->whereNull("district_id");
+
+        if (request("town_id"))$freeze->where("town_id",request("town_id"));
+        else $freeze->whereNull("town_id");
+
+        if (request("street_id"))$freeze->where("street_id",request("street_id"));
+        else $freeze->whereNull("street_id");
+
+        $freeze = $freeze->first();
         if ($freeze && $freeze->id!=request("id"))$this->error("已存在冻结选项,无需重复录入");
         $obj = [
             "logistic_id"   => request("logistic_id"),
             "province_id"   => request("province_id"),
             "city_id"       => request("city_id"),
-            "location_id"   => request("location_id"),
+            "district_id"   => request("district_id"),
+            "town_id"       => request("town_id"),
+            "street_id"     => request("street_id"),
         ];
         if (request("id")){
             $freeze = OrderFreeze::query()->find(request("id"));
             $freeze->update($obj);
         }else $freeze = OrderFreeze::query()->create($obj);
         app("OrderFreezeService")->refreshFreezes();
-        $freeze->load(["logistic:id,name","province:id,name","city:id,name","location:id,name"]);
+        $freeze->load(["logistic:id,name","province:id,name","city:id,name","district:id,name","town:id,name","street:id,name"]);
         $this->success($freeze);
     }
 

+ 19 - 1
app/Http/Controllers/RegionController.php

@@ -13,7 +13,7 @@ class RegionController extends Controller
     {
         $type = request("type");
         $regions = Region::query();
-        if (!$type)$regions->where("type",$type);
+        if ($type)$regions->where("type",$type);
         $this->success($regions->get());
     }
 
@@ -23,4 +23,22 @@ class RegionController extends Controller
         $regions = Region::withTrashed()->get();
         return view("maintenance.region.index",compact("regions"));
     }
+
+    public function store()
+    {
+        $parent = request("parent_id");
+        $type = request("type");
+        if (!$type)$this->error("非法参数");
+
+        $name = app("RegionService")->formatName(request("name"),$type);
+        if (!$name)$this->error("非法参数");
+
+        $region = Region::withTrashed()->where("name",$name)->where("type",$type)->first();
+        if ($region)$this->error("已经存在,无需重复录入");
+        $this->success(Region::query()->create([
+            "name" => $name,
+            "type" => $type,
+            "parent_id" => $parent
+        ]));
+    }
 }

+ 10 - 0
app/Http/Controllers/SendEmailsController.php

@@ -8,7 +8,17 @@ use Illuminate\Http\Request;
 
 class SendEmailsController extends Controller
 {
+
+
     //
+    /**
+     * SendEmailsController constructor.
+     */
+    public function __construct()
+    {
+        $this->middleware('auth')->except([]);
+    }
+
     public function index()
     {
         $roles = Role::all();

+ 62 - 191
app/Http/Controllers/TestController.php

@@ -12,9 +12,11 @@ use App\CommodityBarcode;
 use App\Console\Commands\CreateOwnerAreaReport;
 use App\Console\Commands\CreateOwnerBillReport;
 use App\Console\Commands\CreateOwnerReport;
+use App\Console\Commands\SyncBatchTask;
 use App\Console\Commands\SyncWmsCommoditiesInformation;
 use App\Console\Commands\SyncWMSOrderTask;
 use App\Console\Commands\WasSyncWmsAsnInformation;
+use App\Exceptions\ErrorException;
 use App\Events\CancelOrder;
 use App\Events\SendEmailEvent;
 use App\Http\Requests\ForeignHaiRobotic_taskUpdateRequest;
@@ -43,6 +45,7 @@ use App\OrderCommodity;
 use App\OrderIssue;
 use App\OrderPackage;
 use App\OrderPackageCommodities;
+use App\OrderPackageCountingRecord;
 use App\OrderTracking;
 use App\Owner;
 use App\OwnerPriceOperation;
@@ -81,6 +84,7 @@ use App\Services\RejectedBillService;
 use App\Services\ShopService;
 use App\Services\StoreService;
 use App\Services\WarehouseService;
+use App\StationRuleBatch;
 use App\Store;
 use App\StationTaskBatch;
 use App\StoreCheckingReceiveItem;
@@ -92,6 +96,7 @@ use App\Warehouse;
 use App\Waybill;
 use App\WaybillPriceModel;
 use Carbon\Carbon;
+use Carbon\CarbonPeriod;
 use ChangeColumnOrderIdToOrderIssues;
 use Doctrine\DBAL\Query\QueryBuilder;
 use Illuminate\Database\Eloquent\Builder;
@@ -125,80 +130,46 @@ class TestController extends Controller
         return call_user_func([$this, $method], $request);
     }
 
-    public function updateInventory()
-    {
-        $inventoryAccounts = InventoryAccount::query()->get();
-        $updateParams = [[
-            'id', 'processed', 'ignored', 'updated_at'
-        ]];
-        $updated_at = Carbon::now()->toDateTimeString();
-        foreach ($inventoryAccounts as $inventoryAccount) {
-            if ($inventoryAccount->getIgnoredAmount() > 0) {
-                $updateParams[] = [
-                    'id' => $inventoryAccount->id,
-                    'processed' => $inventoryAccount->getProcessedAmount(),
-                    'ignored' => $inventoryAccount->getIgnoredAmount(),
-                    'updated_at' => $updated_at,
-                ];
-            }
-        }
-        if (count($updateParams) > 1) {
-            app(BatchUpdateService::class)->batchUpdate('inventory_accounts', $updateParams);
-        }
-    }
-    public function disposeDetail($date = null)
-    {
-        DB::transaction(function ()use($date){
-            if (!$date){
-                $valueStore = ValueStore::query()->where("name","wave_detail_last_sync_date")->lockForUpdate()->first();
-                $date = $valueStore->value ?? Carbon::now()->subSeconds(65)->toDateTimeString();
-            }
-            $count = DB::connection("oracle")->selectOne(DB::raw("SELECT count(*) count FROM DOC_WAVE_DETAILS WHERE EDITTIME >= TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')"),[$date]);
-            if ($count->count > 1000){
-                $sql = <<<sql
-    SELECT * FROM (SELECT ORDERNO,WAVENO,SEQNO,EDITTIME, ROWNUM AS rowno FROM (
-    SELECT * FROM DOC_WAVE_DETAILS WHERE EDITTIME >= TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')
- ORDER BY EDITTIME) WHERE ROWNUM <= 1000)wave WHERE wave.rowno >= 0
-sql;
-                $details = DB::connection("oracle")->select(DB::raw($sql),[$date]);
-                //$this->detailExe($details);
-                $this->disposeDetail($details[count($details)-1]->edittime);dump($details[count($details)-1]->edittime);
-            }else{
-                $sql = "SELECT ORDERNO,WAVENO,SEQNO FROM DOC_WAVE_DETAILS WHERE EDITTIME >= TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')";
-                $details = DB::connection("oracle")->select(DB::raw($sql),[$date]);dd($details ? $details[count($details)-1]->edittime : Carbon::now()->toDateTimeString());
-                //$this->detailExe($details);
-                //ValueStore::query()->where("name","wave_detail_last_sync_date")->update(["value"=>$details ? $details[count($details)-1]->edittime : Carbon::now()->toDateTimeString()]);
-            }
-        });
+    public function zzd(){
+        $update = [
+            ["id","wms_status","remark","updated_at"],
+            ["id"=>6,"wms_status"=>"完全收货",
+                "remark"=>"01.[ALLBLU]普通波次","updated_at"=>"2021-01-27 08:58:53"]
+        ];
+        dd(app(BatchUpdateService::class)->batchUpdate("batches",$update));
     }
 
-    public function zzd()
+    public function syncWeight()
     {
-         $province = [
-             "a"=>["安徽","澳门"],
-             "b"=>["北京"],
-             "c"=>["重庆"],
-             "f"=>["福建"],
-             "g"=>["广东","甘肃","广西","贵州"],
-             "h"=>["河北","湖北","黑龙江","湖南","河南","海南"],
-             "j"=>["吉林","江苏","江西"],
-             "l"=>["辽宁"],
-             "n"=>["内蒙古","宁夏"],
-             "q"=>["青海"],
-             "s"=>["四川","山东","上海","陕西","山西"],
-             "t"=>["天津","台湾"],
-             "x"=>["香港","新疆","西藏"],
-             "y"=>["云南"],
-             "z"=>["浙江"],
-         ];
-         foreach ($province as $arr){
-             foreach ($arr as $name){
-                 Region::query()->create([
-                     "name" => $name,
-                     "type" => 1,
-                 ]);
-             }
-         }
+        $pack = OrderPackageCountingRecord::query()->get();
+        foreach ($pack as $p){
+            $yesterday = $p->targeted_at;
+            Cache::pull("weight.".$yesterday);
+            OrderPackageCountingRecord::query()->where("targeted_at",$yesterday)->delete();
+            $sql = <<<sql
+SELECT DATE_FORMAT(created_at,'%Y-%m-%d') date,
+SUM(CASE WHEN weighed_at IS NOT NULL THEN 1 ELSE 0 END) AS count,
+COUNT(1) total FROM order_packages WHERE created_at BETWEEN '{$yesterday} 00:00:00' AND '{$yesterday} 23:59:59' GROUP BY date
+sql;
+            $result = DB::selectOne(DB::raw($sql));
+            if (!$result)$obj = [
+                "targeted_at"    => $yesterday,
+                "un_weigh_count" => 0,
+                "total_count"    => 0
+            ]; else $obj = [
+                "targeted_at"    => $result->date,
+                "un_weigh_count" => $result->count,
+                "total_count"    => $result->total,
+            ];
+            /** @var \stdClass $model */
+            $model = OrderPackageCountingRecord::query()->create($obj);
+            Cache::put("weight.".$yesterday,[
+                "date"=>$yesterday,
+                "total"=>$model->total_count,
+                "count"=>$model->un_weigh_count,
+                "value"=>$model->total_count ? intval(($model->un_weigh_count/$model->total_count)*100) : 0
+            ]);
+        }
     }
 
     public function sync()
@@ -341,40 +312,9 @@ sql;
 
     function t1(Request $request)
     {
-        $times=12345;
-        $start_at = microtime(true);
-        for($i=0;$i<$times;$i++){
-            Cache::put(md5('k_delme'.$i), 'a');
-        }
-        echo microtime(true)-$start_at, '<br>';
-
-        $start_at = microtime(true);
-        for($i=0;$i<$times;$i++){
-            Cache::get(md5('k_delme'.$i));
-        }
-        echo microtime(true)-$start_at, '<br>';
-
-        $start_at = microtime(true);
-        for($i=0;$i<$times;$i++){
-            Cache::pull(md5('k_delme'.$i));
-        }
-        echo microtime(true)-$start_at, '<br>';
-        for($i=0;$i<$times;$i++){
-            Redis::set(md5('k_delme'.$i), 'a');
-        }
-        echo microtime(true)-$start_at, '<br>';
-
-        $start_at = microtime(true);
-        for($i=0;$i<$times;$i++){
-            Redis::get(md5('k_delme'.$i));
-        }
-        echo microtime(true)-$start_at, '<br>';
-
-        $start_at = microtime(true);
-        for($i=0;$i<$times;$i++){
-            Redis::del(md5('k_delme'.$i));
-        }
-        echo microtime(true)-$start_at, '<br>';
+        throw new ErrorException('eeeff');
+        DB::connection('oracle')->update(DB::raw("update BAS_SKU set HAZARD_FLAG= 'N' where SKU= '13564151055'"));
+//        DB::connection('oracle')->update(DB::raw("UPDATE DOC_ORDER_HEADER SET notes = CASE WHEN notes IS NULL THEN '停运' ELSE  notes||',停运' END where ORDERNO in ('','SO190628000050','SO190628000001')"));
     }
 
     function packageT(Request $request)
@@ -596,59 +536,6 @@ sql;
         if (count($error) > 0) app('LogService')->log(__METHOD__, "同步时WMS中未找到这些订单_two", json_encode($error));
     }
 
-    function test1()
-    {
-        $statistics = ProcessStatistic::query()->whereNull('revenue')->get();
-        $id = array_column($statistics->toArray(), 'process_id');
-        $processes = Process::query()->where(function (Builder $query) {
-            $query->where('status', '待交接')->orWhere('status', '交接完成');
-        })->whereIn('id', $id)->get();
-        $sign_end = true;
-        foreach ($processes as $process) {
-            if (count($process->processDailies) > 0) {
-                $completed_amount = 0;
-                foreach ($process->processDailies as $processDaily) {
-                    $completed_amount = $completed_amount + ($processDaily->output);
-                }
-                $process->completed_amount = $completed_amount;
-            }
-            //统计:
-            $revenue = ($process->unit_price) * ($process->completed_amount);   //收入合计
-            $processDailies = ProcessDaily::with('processDailyParticipants')->where('process_id', $process->id)->where('output', '>', 0)->get();
-            $duration_days = count($processDailies);      //完成天数
-            $duration_man_hours = 0;      //总工时
-            $total_cost = 0;              //合计成本
-            foreach ($processDailies as $processDailyOne) {
-                foreach ($processDailyOne->processDailyParticipants as $processDailyParticipant) {
-                    if (!$processDailyParticipant->unit_price && !$processDailyParticipant->hour_price) continue;
-                    $duration_man_hours += $processDailyParticipant->hour_count;
-                    if ($processDailyParticipant->unit_count) {
-                        $total_cost += ($processDailyParticipant->unit_count) * ($processDailyParticipant->unit_price);
-                        continue;
-                    }
-                    $total_cost += ($processDailyParticipant->hour_count) * ($processDailyParticipant->hour_price);
-                }
-            };
-            $processStatistic = ProcessStatistic::query()->find($process->id);
-            $processStatistic->revenue = $revenue;
-            $processStatistic->duration_days = $duration_days;
-            $processStatistic->duration_man_hours = $duration_man_hours;
-            if ($sign_end) $processStatistic->ended_at = date('Y-m-d H:i:s');
-            if (!$revenue || !$total_cost) {
-                $processStatistic->update();
-                continue;
-            }
-            $gross_profit = $revenue - $total_cost; //毛利润
-            if ($gross_profit != 0) $gross_profit_rate = $gross_profit / $revenue;  //毛利率;
-            else $gross_profit_rate = 0;
-            $processStatistic->total_cost = $total_cost;
-            $processStatistic->gross_profit = $gross_profit;
-            $processStatistic->gross_profit_rate = $gross_profit_rate;
-            $processStatistic->update();
-            app('LogService')->log(__METHOD__, "修改二次加工单统计单_" . __FUNCTION__, json_encode($processStatistic), Auth::user()['id']);
-        }
-    }
-
     public function test5()
     {
         ini_set('max_execution_time', 2500);
@@ -1138,7 +1025,7 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
 
     public function reNewBatches3()
     {
-        $batches = Batch::query()->where('id', 6384)->get('code');
+        $batches = Batch::query()->where('id','>', 73620)->get('code');
         $batchCodes = $batches->map(function ($batch) {
             return $batch['code'];
         })->toArray();
@@ -1164,8 +1051,8 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
 //        dd($logs);
         foreach ($batchCodes as $code) {
 //            $request=Cache::get('temp'.$code)['description'];
-            $request = Log::query()->select('description')->where('CREATED_AT', '>', '2020-12-16')
-                ->where('type', "issued_newBatch")
+            $request = Log::query()->select('description')->where('CREATED_AT', '>', '2021-01-22')
+                ->where('method', "issued_newBatch")
                 ->where('description', 'like', "%{$code}%")
                 ->first();
             if ($request) {
@@ -1529,13 +1416,15 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
 
     public function orderTrackingUpdate()
     {
-        $start_at = '2021-01-01 00:00:00';
+        $start_at = '2021-01-08 00:00:00';
+        $end_at = '2021-01-12 00:00:00';
         // 修改【安桥,锐活】 订单号
         $orderHeaderService = new OracleDOCOrderHeaderService();
         $orderTrackingService = new OrderTrackingService();
         $query = $orderHeaderService->getQuery();
         $orderHeaders = $query->whereIn('Doc_Order_Header.customerid',['ONKYO','RUIHUO'])
             ->where('Doc_Order_Header.AddTime','>=',$start_at)
+            ->where('Doc_Order_Header.AddTime','<=',$end_at)
             ->get();
         $orderTrackingService->updateByWmsOrderHeaders($orderHeaders);
     }
@@ -1553,37 +1442,19 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
                  * @var DataHandlerService $dataService
                  */
                 $service = new OrderTrackingService();
-                $orderHeaderService = new OracleDOCOrderHeaderService();
-                $dataService = new DataHandlerService();
-                $order_nos = array_unique(data_get($orderTrackings,'*.commodities.package.order.code'));
-                $order_headers = $orderHeaderService->getQuery()->whereIn('orderno',$order_nos)->get();
-                $update[] = ['id','order_client_code','client',];
-                $order_header_map = $dataService->dataHeader(['orderno'],$order_headers);
+                $update = [];
+                $update[]  = ['id','order_client_code_wms'];
                 foreach ($orderTrackings as $orderTracking) {
-                    $params = ['id' => $orderTracking->id];
-                    $order_package_commodity = $orderTracking->commodities;
-                    if(!$order_package_commodity)continue;
-                    if(!$order_package_commodity->package)continue;
-                    if(!$order_package_commodity->package->order)continue;
-                    $order= $order_package_commodity->package->order;
-                    $order_header = $dataService->getKeyValue(['orderno'=>$order->code],$order_header_map);
-                    $order_remark = $order_header['notes'] ?? '';        // 订单备注
-                    $params['client'] = $order_header['issuepartyname'];
-                    if(mb_stristr($order_remark,'天猫') && mb_stristr($order_remark,'赠品')){ // client and order_remark 商铺 和 订单备注
-                        $params['client'] = '天猫(赠品)';
-                        $params['order_remark'] = $order_remark;
+                    if($orderTracking->commodities->order ?? false){
+                        $update = [
+                            'id' => $orderTracking->id,
+                            'order_client_code_wms' => $orderTracking->commodities->order->client_code
+                        ];
                     }
-                    if(mb_stristr($order_header['issuepartyname'],'天猫') && $params['client'] !== '天猫(赠品)') $params['client'] = '天猫';
-                    if($params['client'] == '天猫') // order_client_code 订单号  店铺包含天猫
-                        $params['order_client_code'] = $service->get_d_edit_03($order_header,$order_package_commodity);
-                    else
-                        $params['order_client_code'] = $order->client_code;
-                    if($params['client'] != '天猫' && $params['client'] != '天猫(赠品)')continue;
-                    if($params['client']!=$orderTracking->client ||  $params['order_client_code']!=$orderTracking->order_client_code) $update[] = $params;
-            }
-            if(count($update) > 1){
-                $service->batchUpdate($update);
-            }
+                }
+                if(count($update) > 1){
+                    $service->batchUpdate($update);
+                }
         });
     }
 

+ 19 - 6
app/Http/Controllers/api/thirdPart/haiq/PickStationController.php

@@ -18,12 +18,25 @@ class PickStationController
         $this->service=app('ForeignHaiRoboticsService');
     }
 
-    public function processed(Request $request){
-        $success = $request->input('success');
-        $code = $success?200:0;
-        $this->service->markBinProcessed();
-        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->all()));
-        return ['code'=>$code,'errMsg'=>'','data'=>$request->all()];
+    public function processed(Request $request): array
+    {
+        $failed=
+            ($processedResult=
+                $this->service->markBinProcessed(
+                    $request->input('workStation'),
+                    $request->input('binCode'),
+                    $request->input('success'),
+                    $request->input('created_at'),
+                    $request->input('exception'),
+                    $request->input('is_in_plan')
+                ))!==true;
+
+        $result = ["code" => 200, "data" => json_encode($request->all())];
+        if($failed){
+            $result["code"] = 500;
+            $result["errMsg"] = $processedResult;
+        }
+        return $result;
     }
 
 }

+ 8 - 10
app/Http/Controllers/api/thirdPart/haiq/StorageController.php

@@ -243,16 +243,15 @@ class StorageController
         return $this->light($request,$this->lightOff);
     }
     public function taskUpdate(ForeignHaiRobotic_taskUpdateRequest $request){
-        return $request->method();
         try{
             $this->service->taskUpdate(
-                $request['groupCode'],
-                $request['taskCode'],
-                $request['updateEventType'],
-                $request['status'],
-                $request['binCode'],
-                $request['kubotId'],
-                $request['description']
+//                $request['groupCode']
+                $request['taskCode']
+                ,$request['updateEventType']
+                ,$request['status']
+                ,$request['binCode']
+//                ,$request['kubotId']
+//                ,$request['description']
             );
             return ['code'=>200,'errMsg'=>'','data'=>$request->all()];
         }catch (\Exception $e){
@@ -260,8 +259,7 @@ class StorageController
         }
     }
     public function exception(Request $request){
-        $this->service->excepted();
-        app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->all()));
+        $this->service->excepted('海柔异常','',json_encode($request));
         return ['code'=>200,'errMsg'=>'','data'=>$request->all()];
     }
 }

+ 35 - 0
app/Http/Requests/ForeignHaiRobotic_processedRequest.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class ForeignHaiRobotic_processedRequest extends FormRequest
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     *
+     * @return bool
+     */
+    public function authorize()
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        return [
+            'workStation'=>'nullable',
+            'binCode'=>'required',
+            'success'=>'required|bool',
+            'created_at'=>'nullable',
+            'exception'=>'nullable',
+            'is_in_plan'=>'required|bool',
+        ];
+    }
+}

+ 1 - 1
app/Http/Requests/ForeignHaiRobotic_taskUpdateRequest.php

@@ -28,7 +28,7 @@ class ForeignHaiRobotic_taskUpdateRequest extends FormRequest
         return [
            'groupCode'=>'required',
            'taskCode'=>'required',
-           'updateEventType'=>'required',
+           'updateEventType'=>'required|in:0,1',
            'status'=>'required|in:0,1',
            'binCode'=>'required',
            'kubotId'=>'required',

+ 4 - 1
app/Jobs/OrderFreeze.php

@@ -51,6 +51,7 @@ class OrderFreeze implements ShouldQueue
     {
         $freezeOrders = [];
         foreach ($this->params as $param){
+            if (!$param["frozen"]=='是')continue;
             if (!$param["logistic_id"])continue;
             if ($this->isFreeze($param))$freezeOrders[] = $param["code"];
         }
@@ -66,7 +67,9 @@ class OrderFreeze implements ShouldQueue
             if ($pool["logistic_id"]!=$param["logistic_id"])continue;
             if ($pool["province_name"] && (mb_strpos($param["province"],$pool["province_name"]) === false))continue;
             if ($pool["city_name"] && (mb_strpos($param["city"],$pool["city_name"]) === false))continue;
-            if ($pool["location_name"] && (mb_strpos($param["district"],$pool["location_name"]) === false))continue;
+            if ($pool["district_name"] && (mb_strpos($param["district"],$pool["district_name"]) === false))continue;
+            if ($pool["town_name"] && (mb_strpos($param["address"],$pool["town_name"]) === false))continue;
+            if ($pool["street_name"] && (mb_strpos($param["address"],$pool["street_name"]) === false))continue;
             return true;
         }
         return false;

+ 15 - 2
app/Order.php

@@ -19,7 +19,8 @@ class Order extends Model
         'created_at', 'code', 'shop_id',  'client_code',
         'logistic_id', 'consignee_name', 'consignee_phone', 'province',
         'city', 'district', 'address','warehouse_id',
-        'wms_edittime', 'wms_status','order_type'];
+        'wms_edittime', 'wms_status','order_type','frozen'
+    ];
 
     /*
      * wms订单号             code=>DOC_ORDER_HEADER[orderno]
@@ -139,7 +140,8 @@ class Order extends Model
 
     public function isEquals($order)
     {
-        return $this['wms_edittime'] == $order['wms_edittime'];
+        return $this['wms_edittime'] == $order['wms_edittime']
+            && $this['frozen'] == $order['frozen'];
     }
 
     public function assignValueByOrder($order)
@@ -159,7 +161,18 @@ class Order extends Model
         $this['client_code'] = $order['client_code'] ;
         $this['wms_status'] = $order['wms_status'] ;
         $this['wms_edittime'] = $order['wms_edittime'];
+        $this['frozen'] = $order['frozen'];
         $this['order_type'] = $order['order_type'];
         $this['created_at'] =$order['created_at'];
     }
+
+    public static function getFrozen($string): string
+    {
+        $arr = [
+            'H' => '是',
+            'Y' => '否',
+            'N' => '否'
+        ];
+        return $arr[$string] ?? '否';
+    }
 }

+ 14 - 6
app/OrderFreeze.php

@@ -13,7 +13,7 @@ class OrderFreeze extends Model
     use ModelTimeFormat;
 
     protected $fillable = [
-        "status","logistic_id","province_id","city_id","location_id"
+        "status","logistic_id","province_id","city_id","district_id","town_id","street_id"
     ];
 
     const status=[
@@ -27,14 +27,22 @@ class OrderFreeze extends Model
     }
     public function province()
     {   //省
-        return $this->belongsTo(Province::class);
+        return $this->belongsTo(Region::class)->where("type",1);
     }
     public function city()
     {   //市
-        return $this->belongsTo(City::class);
+        return $this->belongsTo(Region::class)->where("type",2);
     }
-    public function location()
-    {   //区
-        return $this->belongsTo(City::class)->where("type","3");
+    public function district()
+    {   //区县
+        return $this->belongsTo(Region::class)->where("type",3);
+    }
+    public function town()
+    {   //乡镇
+        return $this->belongsTo(Region::class)->where("type",4);
+    }
+    public function street()
+    {   //村街
+        return $this->belongsTo(Region::class)->where("type",5);
     }
 }

+ 4 - 3
app/OrderIssue.php

@@ -307,7 +307,8 @@ class OrderIssue extends Model
             ->selectRaw('order_issues.* ,order_issue_on_tops.id top_id ,order_issue_on_tops.remark,order_issue_on_tops.updated_at top_update')
             ->leftJoin('order_issue_on_tops', 'order_issue_on_tops.order_issue_id', '=', 'order_issues.id')
             ->whereNull('order_issue_on_tops.deleted_at')
-            ->orderBy('order_issue_on_tops.updated_at', 'desc');
+            ->orderBy('order_issue_on_tops.updated_at', 'desc')
+            ->orderBy('order_issues.id', 'desc');
     }
 
     public function scopeJsonWith($query)
@@ -320,8 +321,8 @@ class OrderIssue extends Model
             $query->with(['shop', 'logistic', 'owner', 'packages.commodities.commodity.barcodes']);
         },'orderIssueRejectedBills.rejectedBill'=>function($query){
             $query->with(['owner','logistic','user','items.quality']);
-        },'userWorkgroups'])
-            ->orderBy('order_issues.id', 'desc');
+        },'userWorkgroups']);
+
     }
 
     public function userWorkgroups(): BelongsToMany

+ 18 - 0
app/OrderPackageCountingRecord.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\LogModelChanging;
+
+class OrderPackageCountingRecord extends Model
+{
+    use LogModelChanging;
+
+    protected $fillable=[
+        "targeted_at","un_weigh_count","total_count"
+    ];
+    public $timestamps=false;
+
+}

+ 2 - 1
app/OrderTracking.php

@@ -16,7 +16,7 @@ class OrderTracking extends Model
     protected $fillable = [
         'order_package_commodity_id','owner_id','logistic_id',
         'web_order_number',
-        'pick_up_at','sale','client','order_client_code',
+        'pick_up_at','sale','client','order_client_code','order_client_code_wms',
         'order_remark','pallet_total','planning_sent_at',
         'is_on_duty_shift','is_arrival','signed_at',
         'receive_bill_status','remark','gross_weight','bulk'];
@@ -39,6 +39,7 @@ class OrderTracking extends Model
      * remark 签收单情况
      * gross_weight 重量
      * bulk 体积
+     * customer_order_number 客户订单号
      */
 
     protected $appends =[

+ 18 - 0
app/Providers/AppServiceProvider.php

@@ -20,6 +20,7 @@ use App\Services\InventoryAccountMissionService;
 use App\Services\InventoryCompareService;
 use App\Services\LaborReportsCountingRecordService;
 use App\Services\LogService;
+use App\Services\MaterialBoxService;
 use App\Services\OracleBasCustomerService;
 use App\Services\OracleBasSkuService;
 use App\Services\OracleDocAsnDetailService;
@@ -63,9 +64,17 @@ use App\Services\RejectedBillItemService;
 use App\Services\RejectedBillService;
 use App\Services\ShopService;
 use App\Services\RejectedService;
+use App\Services\StationRuleBatchService;
 use App\Services\StationTaskBatchService;
 use App\Services\StationTaskBatchTypeService;
 use App\Services\StationService;
+use App\Services\StationTaskChildService;
+use App\Services\StationTaskCommodityService;
+use App\Services\StationTaskMaterialBoxService;
+use App\Services\StationTaskService;
+use App\Services\StationTaskTypeService;
+use App\Services\StationTypeBinMonitorService;
+use App\Services\StationTypeService;
 use App\Services\StoreCheckingReceiveItemService;
 use App\Services\StoreCheckingReceiveService;
 use App\Services\StoreItemService;
@@ -150,6 +159,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('LaborReportsCountingRecordService',LaborReportsCountingRecordService::class);
         app()->singleton('LogService',LogService::class);
         app()->singleton('LogisticService',LogisticService::class);
+        app()->singleton('MaterialBoxService',MaterialBoxService::class);
         app()->singleton('OracleActAllocationDetailService',OracleActAllocationDetailService::class);
         app()->singleton('OracleBasCustomerService',OracleBasCustomerService::class);
         app()->singleton('OracleBasSkuService',OracleBasSkuService::class);
@@ -191,11 +201,19 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('RejectedBillService',RejectedBillService::class);
         app()->singleton('RejectedService',RejectedService::class);
         app()->singleton('ShopService',ShopService::class);
+        app()->singleton('StationRuleBatchService',StationRuleBatchService::class);
         app()->singleton('StationService',StationService::class);
         app()->singleton('StationTaskBatchService',StationTaskBatchService::class);
         app()->singleton('StationTaskBatchTypeService',StationTaskBatchTypeService::class);
         app()->singleton('StoreCheckingReceiveItemService',StoreCheckingReceiveItemService::class);
         app()->singleton('StoreCheckingReceiveService',StoreCheckingReceiveService::class);
+        app()->singleton('StationTaskCommodityService',StationTaskCommodityService::class);
+        app()->singleton('StationTaskMaterialBoxService',StationTaskMaterialBoxService::class);
+        app()->singleton('StationTaskChildService',StationTaskChildService::class);
+        app()->singleton('StationTaskService',StationTaskService::class);
+        app()->singleton('StationTaskTypeService',StationTaskTypeService::class);
+        app()->singleton('StationTypeBinMonitorService',StationTypeBinMonitorService::class);
+        app()->singleton('StationTypeService',StationTypeService::class);
         app()->singleton('StoreItemService',StoreItemService::class);
         app()->singleton('StoreService',StoreService::class);
         app()->singleton('UnitService',UnitService::class);

+ 49 - 8
app/Services/BatchService.php

@@ -3,7 +3,13 @@
 namespace App\Services;
 
 use App\Batch;
+use App\OracleActAllocationDetails;
+use App\Order;
+use App\OrderCommodity;
+use App\Owner;
 use Exception;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Http;
 use App\Traits\ServiceAppAop;
 
 
@@ -51,28 +57,63 @@ Class BatchService
 
     /**
      * 为波次附加任务,已附加的重复任务不影响
-     * @param Batch[] $batches
+     * @param Collection $batches
      * @throws Exception
      */
-    public function assignTasks(array $batches)
+    public function assignTasks(Collection $batches)
     {
+//        $this->directTemp($batches);
         $this->instant($this->stationTaskBatchService,'StationTaskBatchService');
         $this->instant($this->stationRuleBatchService,'StationRuleBatchService');
         $this->instant($this->stationTaskService,'StationTaskService');
         $this->instant($this->stationTaskCommodityService,'StationTaskCommodityService');
         $this->instant($this->stationTaskMaterialBoxService,'StationTaskMaterialBoxService');
 
-        $batches_canProcess = $this->stationRuleBatchService->getBatches_canProcess($batches); //按规则过滤需要的波次
-        if($batches_canProcess->isEmpty()) return;
+        $batches_shouldProcess = $this->stationRuleBatchService->getBatches_shouldProcess($batches); //按规则过滤需要的波次
+        if($batches_shouldProcess->isEmpty()) return;
 
-        $stationTasks =  $this->stationTaskService->create($batches_canProcess->count()); //生成总任务
-        $stationTaskBatches=$this->stationTaskBatchService->createByBatches($batches_canProcess,$stationTasks); //注册波次任务
-        $this->stationTaskCommodityService->createByBatches($batches_canProcess,$stationTasks); //注册商品任务
-        $this->stationTaskMaterialBoxService->createByBatches($batches_canProcess,$stationTasks); //注册料箱任务
+        $stationTasks =  $this->stationTaskService->create($batches_shouldProcess->count()); //生成总任务
+        $stationTaskBatches=$this->stationTaskBatchService->createByBatches($batches_shouldProcess,$stationTasks); //注册波次任务
+        $this->stationTaskCommodityService->createByBatches($batches_shouldProcess,$stationTasks); //注册商品任务
+        $this->stationTaskMaterialBoxService->createByBatches($batches_shouldProcess,$stationTasks); //注册料箱任务
 
         $this->stationTaskBatchService->runMany($stationTaskBatches);//执行波次任务
     }
 
+//    public function directTemp($batches){
+//        $ownerName='';
+//        $batches=$batches->map(function(Batch $batch)use($ownerName){
+//            $owner=Owner::query()->where('name',$ownerName)->get();
+//            if(!$owner) return false;
+//            if($batch['owner_id']==$owner['id'])return $batch;
+//            return false;
+//        });
+//        $bins=$batches->map(function (Batch $batch){
+//            $batch->loadMissing('orders.orderCommodities');
+//
+//            foreach ($batch['orders'] as $order){
+//                foreach ($order['orderCommodities'] as $orderCommodity){
+//                    return [
+//                        "taskCode"  =>'testTask'.microtime(),
+//                        "binCode"   => $orderCommodity['location'],
+//                        "toLocCode" => 'BIN-OUT1',
+//                    ];
+//                }
+//            }
+//            return null;
+//        });
+//
+//        $json= [
+//            "taskMode"  =>2,
+//            "bins"=>$bins,
+//            "groupCode"=>'testGroup'.microtime(),
+//            "priority"=>10,
+//            "sequenceFlag"=>1,
+//        ];
+//        $response = Http::post(config('api.haiq.storage.moveBin'),$json);
+//        LogService::log(__CLASS__,__METHOD__,$response->json());
+//    }
+
     public function getBatchByCodes($codes)
     {
         if(empty($codes))return collect();

+ 2 - 2
app/Services/CacheService.php

@@ -11,8 +11,8 @@ use App\Traits\ServiceAppAop;
 class CacheService
 {
     use ServiceAppAop;
-    function getOrExecute(String $key, $func, $expiration=null){
-        if(!$expiration) $expiration=config('cache.expirations.default');
+    function getOrExecute(String $key, $func, $expiration=-1){
+        if($expiration === -1) $expiration=config('cache.expirations.default');
         return Cache::remember($key, $expiration, $func);
 //        $results = Cache::get($key);
 //        if(!$results){

+ 167 - 67
app/Services/ForeignHaiRoboticsService.php

@@ -10,14 +10,28 @@ use App\MaterialBox;
 use App\StationTaskMaterialBox;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
+use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Http;
-use Ramsey\Collection\Collection;
 use App\Traits\ServiceAppAop;
 
 
 class ForeignHaiRoboticsService
 {
     use ServiceAppAop;
+
+    /** @var  $stationTaskMaterialBoxService StationTaskMaterialBoxService */
+    private $stationTaskMaterialBoxService;
+    /** @var  $materialBoxService MaterialBoxService */
+    private $materialBoxService;
+    /** @var  $stationService StationService */
+    private $stationService;
+    public function __construct()
+    {
+        $this->stationTaskMaterialBoxService=null;
+        $this->materialBoxService=null;
+        $this->stationService=null;
+    }
+
     /**
      * @param string $modeName '输送线入立架'|'立架出至输送线'|'移动立架内位置'|'缓存架入立架'|'立架出至缓存架'
      * @param string $fromLocation
@@ -26,6 +40,7 @@ class ForeignHaiRoboticsService
      * @param string $groupId
      * @param int $priority
      * @param int $isSequenced
+     * @return array
      */
     private function makeJson_move(
         Collection $taskMaterialBoxes,
@@ -35,7 +50,8 @@ class ForeignHaiRoboticsService
         $groupId=''
         , $priority=10
         , $isSequenced=1
-    ){
+    ): array
+    {
         $timestampSuffix = microtime(true);
         $taskMode=(function()use($modeName){
             switch ($modeName){
@@ -47,113 +63,197 @@ class ForeignHaiRoboticsService
                 default: throw new \Exception('发至海柔的移料箱请求,模式不存在');
             }
         })();
-        $bins=$taskMaterialBoxes->map(function (StationTaskMaterialBox $taskMaterialBox)use($timestampSuffix){
+        $bins=$taskMaterialBoxes->map(function (StationTaskMaterialBox $taskMaterialBox)use($timestampSuffix,$fromLocation,$toLocation){
             return [
-                "taskCode"  =>"{$taskMaterialBox['id']}_{$taskMaterialBox['material_box_id']}_{$timestampSuffix}",
+                "taskCode"  =>$taskMaterialBox['id'],
                 "binCode"   => $taskMaterialBox['materialBox']['code'],
                 "fromLocCode" => $fromLocation??'',
                 "toLocCode" => $toLocation??'',
             ];
         });
-        $groupId .= $timestampSuffix;
         return [
             "taskMode"  =>$taskMode,
             "bins"=>$bins,
-            "groupCode"=>$groupId,
+            "groupCode"=>$groupId.$timestampSuffix,
             "priority"=>$priority,
             "sequenceFlag"=>$isSequenced,
         ];
     }
 
-    public function fetchGroupToProcessor($toLocation, Collection $taskMaterialBoxes, $groupIdPrefix=''): bool
+    public function fetchGroup($toLocation, Collection $taskMaterialBoxes, $groupIdPrefix=''): bool
     {
         $dataToPost=$this->makeJson_move(
             $taskMaterialBoxes,
             '立架出至输送线',
             '',
-            $toLocation,
+            $toLocation??'',
             $groupIdPrefix
         );
-        $response = Http::post(config('api.haiq.storage.moveBin'),$dataToPost);
-        $errMsg=(function()use($response){
-            if($response->ok())return '';
-            $errMsg = '错误: ';
-            if (!$response){
-                return $errMsg.'没有返回内容,检查连接或目标服务器';
-            }
-            switch (((string)$response["code"])[0]){
-                case 5: $errMsg.='目标服务器代码错误,请联系对方';break;
-                case 4: $errMsg.='权限不足以请求资源,请检查对方服务器规范';break;
-                default: $errMsg.='出现未知请求错误';break;
-            }
-            $responseDetails=' code:'.$response["code"]
-                .' header:'.$response->body()
-                .' response:'.json_encode($response->headers());
-            return $errMsg.$responseDetails;
-        })();
-
-        LogService::log(__METHOD__,__FUNCTION__,
-            $errMsg??''
-            .'请求:'.json_encode($dataToPost)
-            .'调用堆栈:'.json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),0,3))
-        );
-        return $isSuccess=!$errMsg;
+        return $this->controlHaiRobot($dataToPost);
     }
 
     public function moveBin(){
 
     }
 
-    public function markBinProcessed(){
+    public function markBinProcessed(
+        $workStation,
+        $binCode,
+        $success,
+        $created_at,
+        $exception,
+        $is_in_plan
+    ): bool
+    {
+        try{
+            if($failed
+                =!$success)
+                throw new ErrorException('海柔任务失败:'.$exception);
+            if($NotInPlan
+                =!$is_in_plan)
+                throw new ErrorException('海柔认为是计划外的料箱:'.$exception);
 
+            $materialBox=
+                $this->materialBoxService->get(['code'=>$binCode]);
+            if($stationTaskMaterialBox
+                =(function()use($materialBox){
+                return $stationTaskMaterialBox=
+                    $this->stationTaskMaterialBoxService
+                        ->get([
+                            'material_box_id'=>$materialBox['id'],
+                            'status'=>'处理中',
+                        ])->first();
+            })()){
+                throw new ErrorException('该料箱没有安排在处理队列中');
+            }
+            $this->putBinToStore($stationTaskMaterialBox)
+                ?true
+                :(function(){throw new ErrorException('呼叫机器人回收U型线料箱失败');})();
+            $this->stationTaskMaterialBoxService
+                ->markProcessed($stationTaskMaterialBox);
+            return true;
+        }catch (\Exception $e){
+            $this->stationTaskMaterialBoxService
+                ->excepted($stationTaskMaterialBox??$materialBox??null);
+            return $e->getMessage();
+        }
+    }
+
+    public function putBinToStore(StationTaskMaterialBox $stationTaskMaterialBox): bool
+    {
+        $this->instant($this->stationService,'StationService');
+        $dataToPost=$this->makeJson_move(
+            collect($stationTaskMaterialBox),
+            '缓存架入立架',
+            $this->stationService->getULineExit($stationTaskMaterialBox['station'])['name']??'',
+            '',
+            $stationTaskMaterialBox['stationTaskBatch']['id']
+        );
+        return $this->controlHaiRobot($dataToPost);
     }
+
     public function taskUpdate(
-        $groupCode,
+//        $groupCode,
         $taskCode,
         $updateEventType,   //0:task_begin(取货)1:task_end(放货)
         $status,            //0:任务成功1:任务失败
-        $binCode,
-        $robotId,
-        $description
+        $binCode
     ):bool{
-        if($status==1){
-            return $this->excepted();
-        }
-        switch ($updateEventType){
-            case 0:
-            case 1:
+        try{
+            if(($failed
+                    =$status)==1){
+                throw new ErrorException('海柔任务失败');
+            }
+            if($boxNotMatch=
+                !$stationTaskMaterialBox
+                =(function()use($taskCode,$binCode){
+                $stationTaskMaterialBox=StationTaskMaterialBox::query()->find($id=$taskCode);
+                if($stationTaskMaterialBox['code']==$binCode)return $stationTaskMaterialBox;
+                return null;
+            })()){
+                throw new ErrorException('发回的料箱和任务号(ID)不匹配');
+            }
+            ($标记已放置在库外=
+                function()use($updateEventType,$stationTaskMaterialBox){
+                if(($isPut
+                        =$updateEventType)==1){
+                    $this->stationTaskMaterialBoxService->markHasPut($stationTaskMaterialBox);
+                }
+            })();
+            ($标记已入立架=
+                function()use($updateEventType,$stationTaskMaterialBox){
+                    if(($isGet
+                            =$updateEventType)==0){
+                        $this->stationTaskMaterialBoxService->markTaken($stationTaskMaterialBox);
+                    }
+            })();
+        }catch (\Exception $e){
+            $this->excepted($taskCode, $binCode, $e->getMessage());
+            return false;
         }
-        $this->markHasGet();
-
+        return true;
     }
-    public function markHasPut(
-        $groupCode,
-        $taskCode,
-        $updateEventType,   //0:task_begin(取货)1:task_end(放货)
-        $status,            //0:任务成功1:任务失败
-        $binCode,
-        $robotId,
-        $description
-    ):bool{
-
 
-    }
-    public function markHasGet(
-        $groupCode,
-        $taskCode,
-        $updateEventType,   //0:task_begin(取货)1:task_end(放货)
-        $status,            //0:任务成功1:任务失败
-        $binCode,
-        $robotId,
-        $description
-    ):bool{
+//    public function markHasPut($taskCode,$binCode):bool{
+//        try{
+//            //标记料箱进入位置
+////            $taskMaterialBoxesService->markDone();//
+//        }catch (\Exception $e){
+//            switch ($e->getCode()){
+//                case 'taskBinNotMatch';
+//                case 'taskGetFailed';
+//            }
+//        }
+//
+//    }
 
 
+    public function excepted($taskCode='',$binCode='', $msg=''):bool{
+        try{
+            throw new ErrorException(
+                "taskCode任务号:$taskCode , binCode箱号:$binCode 海柔运行报错: $msg"
+            );
+        }catch (\Exception $e){
+            return true;
+        }
     }
 
+    /**
+     * @param array $dataToPost
+     * @return bool
+     */
+    public function controlHaiRobot(array $dataToPost): bool
+    {
+        $response = Http::post(config('api.haiq.storage.moveBin'), $dataToPost);
+        $errMsg = (function () use ($response) {
+            if ($response->ok()) return '';
+            $errMsg = '错误: ';
+            if (!$response) {
+                return $errMsg . '没有返回内容,检查连接或目标服务器';
+            }
+            switch (((string)$response["code"])[0]) {
+                case 5:
+                    $errMsg .= '目标服务器代码错误,请联系对方';
+                    break;
+                case 4:
+                    $errMsg .= '权限不足以请求资源,请检查对方服务器规范';
+                    break;
+                default:
+                    $errMsg .= '出现未知请求错误';
+                    break;
+            }
+            $responseDetails = ' code:' . $response["code"]
+                . ' header:' . $response->body()
+                . ' response:' . json_encode($response->headers());
+            return $errMsg . $responseDetails;
+        })();
 
-    public function excepted():bool{
-
+        LogService::log(__METHOD__, __FUNCTION__,
+            $errMsg ?? ''
+            . '请求:' . json_encode($dataToPost)
+            . '调用堆栈:' . json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 0, 3))
+        );
+        return $isSuccess = !$errMsg;
     }
 
 }

+ 39 - 33
app/Services/LogisticSFService.php

@@ -132,40 +132,46 @@ xml;
      */
     public function switchOpCodeToStatus(array $lastRoute, array $data): array
     {
-        switch ($lastRoute['opcode']) {
-            case 123:
-            case 130:
-            case 3036:
-            case 31:
-            case 30:
-                $data['status'] = '在途';
-                break;
-            case 70:
-            case 33:
-                $data['status'] = '派送异常';
-                $data['exception'] = '是';
-                break;
-            case 204:
-            case 44:
-                $data['status'] = '派送中';
-                break;
-            case 50:
-                $data['status'] = '已揽收';
-                break;
-            case 607:
-            case 8000:
-            case 80:
-                $data['status'] = '已收件';
-                $data['received_at'] = $lastRoute[$this->protected_switch['received_at']];
-                break;
-            case 648:
-            case 99:
-                $data['status'] = '返回中';
-                break;
-            default:
-                throw new WarningException("未知的丰桥状态码: {$lastRoute['opcode']}->{json_encode($lastRoute)}");
+        try {
+            switch ($lastRoute['opcode']) {
+                case 123:
+                case 130:
+                case 3036:
+                case 31:
+                case 30:
+                case 36:
+                    $data['status'] = '在途';
+                    break;
+                case 70:
+                case 33:
+                    $data['status'] = '派送异常';
+                    $data['exception'] = '是';
+                    break;
+                case 204:
+                case 44:
+                    $data['status'] = '派送中';
+                    break;
+                case 50:
+                    $data['status'] = '已揽收';
+                    break;
+                case 607:
+                case 8000:
+                case 80:
+                    $data['status'] = '已收件';
+                    $data['received_at'] = $lastRoute[$this->protected_switch['received_at']];
+                    break;
+                case 648:
+                case 99:
+                    $data['status'] = '返回中';
+                    break;
+                default:
+                    throw new WarningException("未知的丰桥状态码: {$lastRoute['opcode']}->{json_encode($lastRoute)}");
+            }
+        } catch (WarningException $e) {
+            $data['status'] = '其他异常';
+        }finally {
+            return $data;
         }
-        return $data;
     }
 
     /**

+ 5 - 3
app/Services/MaterialBoxService.php

@@ -5,6 +5,7 @@ namespace App\Services;
 
 
 use App\MaterialBox;
+use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
 use App\Traits\ServiceAppAop;
 
@@ -13,7 +14,7 @@ class MaterialBoxService
 {
     use ServiceAppAop;
 
-    function get(array $kvPairs){
+    function get(array $kvPairs):?Collection{
         ksort($kvPairs);
         return Cache::remember('MaterialBox_'.md5(json_encode($kvPairs)), config('cache.expirations.rarelyChange'), function ()use($kvPairs) {
             $query = MaterialBox::query();
@@ -27,7 +28,8 @@ class MaterialBoxService
 
     function firstOrCreate(array $kvPairs){
         $materialBox=$this->get($kvPairs);
-        if(!$materialBox)
-            return MaterialBox::query()->create($kvPairs);
+        if($materialBox->isNotEmpty())
+            return $materialBox->first();
+        return MaterialBox::query()->create($kvPairs);
     }
 }

+ 2 - 1
app/Services/OracleDOCOrderHeaderService.php

@@ -24,7 +24,8 @@ Class OracleDOCOrderHeaderService
         'DOC_Order_Header.CarrierName', 'DOC_Order_Header.LastShipmentTime','DOC_Order_Header.EDISendFlag',
         'DOC_Order_Header.SOReference5', 'DOC_Order_Header.C_Tel2','DOC_Order_Header.Transportation',
         'DOC_Order_Header.WareHouseId','DOC_Order_Header.SOStatus','DOC_Order_Header.C_Tel1','DOC_Order_Header.C_District',
-        'DOC_Order_Header.IssuePartyName','DOC_Order_Header.OrderType','DOC_Order_Header.WaveNo'
+        'DOC_Order_Header.IssuePartyName','DOC_Order_Header.OrderType','DOC_Order_Header.WaveNo',
+        'DOC_Order_Header.ReleaseStatus'
     ];
 
     public function getQuery(){

+ 44 - 13
app/Services/OracleDocWaveDetailService.php

@@ -4,6 +4,7 @@ namespace App\Services;
 
 use App\OracleDOCOrderHeader;
 use App\OracleDOCWaveDetails;
+use App\Order;
 use App\ValueStore;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\Cache;
@@ -16,11 +17,20 @@ class OracleDocWaveDetailService
     public function clearCancelledOrder($orderHeaders)
     {
         if (!$orderHeaders) return;
-        $clearOrderNos = data_get($orderHeaders, '*.orderno');
-        OracleDOCWaveDetails::query()->whereIn('OrderNo', $clearOrderNos)->delete();
-        app('LogService')->log(__CLASS__, __METHOD__, 'Delete OracleDOCWaveDetails' . '  ' . json_encode($clearOrderNos) );
+        $orderHeader_arr = $orderHeaders->chunk(300);
+        $orderHeader_arr->each(function ($items){
+            $clearOrderNos = data_get($items, '*.orderno');
+            $ownerNos = array_diff(data_get($items, '*.waveno'),['*']) ;
+            try {
+                OracleDOCWaveDetails::query()->whereIn('OrderNo', $clearOrderNos)->whereIn('OwnerNo', $ownerNos)->delete();
+                app('LogService')->log(__CLASS__, __METHOD__, 'Delete OracleDOCWaveDetails' . '  ' . json_encode($clearOrderNos) );
+            } catch (\Exception $e) {
+                app('LogService')->log(__CLASS__, __METHOD__,'Error clearCancelledOrder'.json_encode($clearOrderNos).json_encode($ownerNos));
+            }
+        });
     }
 
+
     private function getSyncAt()
     {
         return Cache::remember('clear_cancel_order_sync_at', config('sync.clear_wave_order.cache_prefix.sync_at'), function () {
@@ -79,7 +89,7 @@ class OracleDocWaveDetailService
         $restart = config('clear_wave_order.cache_prefix.restart');
         $start_time = Carbon::now();
 
-        if (isset($last_start_at) && empty($last_end_at) && $start_time->diffInMinutes(Carbon::parse($last_start_at)) < $this->restart) return;
+        if (isset($last_start_at) && empty($last_end_at) && $start_time->diffInMinutes(Carbon::parse($last_start_at)) < $restart) return;
         if (isset($last_start_at) && isset($last_end_at)
             && Carbon::parse($last_end_at)->lt(Carbon::parse($last_start_at))
             && $start_time->diffInMinutes(Carbon::parse($last_start_at)) < $restart)
@@ -87,18 +97,25 @@ class OracleDocWaveDetailService
 
         $orderHeaders = OracleDOCOrderHeader::query()
             ->selectRaw('orderno,waveno')
-            ->where('editTime', '>=', Carbon::parse($sync_at)->subSeconds(1))
+            ->where('EDITTIME', '>=', Carbon::parse($sync_at)->subSeconds(1))
             ->where('ERPCANCELFLAG', 'Y')
             ->orderByDesc('editTime')->get();
         $orderHeaderList = $orderHeaders->chunk(3000);
-        foreach ($orderHeaderList as $items) {
-            $this->clearCancelledOrder($items);
-            if ($orderHeaders->count() > 0) {
-                OracleDOCOrderHeader::query()->whereIn('orderNo', data_get($items, '*.orderno'))->update(['waveno' => '*']);
-                $json = json_encode($items->map(function ($orderHeader) {
-                    return ['orderno' => $orderHeader->orderno, 'waveno' => $orderHeader->waveno];
-                }));
-                app('LogService')->log(__CLASS__, __METHOD__, 'update OrderHeader' . '  ' . $json);
+        $update_at = Carbon::now();
+        if(count($orderHeaders)>0){
+            foreach ($orderHeaderList as $items) {
+                $this->clearCancelledOrder($items);
+                if ($items->count() > 0) {
+                    OracleDOCOrderHeader::query()
+                        ->whereIn('orderNo', data_get($items, '*.orderno'))
+                        ->whereIn('waveno', data_get($items, '*.waveno'))
+                        ->update(['waveno' => '*','editTime' =>$update_at]);
+                    $json = json_encode($items->map(function ($orderHeader) {
+                        return ['orderno' => $orderHeader->orderno, 'waveno' => $orderHeader->waveno];
+                    }));
+                    app('LogService')->log(__CLASS__, __METHOD__, 'update OrderHeader' . '  ' . $json);
+                    $this->disposeOrderBatchId(data_get($items, '*.orderno'));
+                }
             }
         }
         $end_time = (string)Carbon::now();
@@ -107,4 +124,18 @@ class OracleDocWaveDetailService
         $this->setSyncStartAt((string)$start_time);
         $this->setSyncEndAt($end_time);
     }
+
+
+    public function disposeOrderBatchId(array $orderNos)
+    {
+        if(!$orderNos) return;
+        try {
+            $bool = Order::query()->whereIn('code', $orderNos)->update(['batch_id' => null]);
+            if($bool>0) app('LogService')->log(__CLASS__, __FUNCTION__ , 'success update Order batch_id' . '  ' . json_encode($orderNos));
+            else app('LogService')->log(__CLASS__, __FUNCTION__ , 'error update Order batch_id' . '  ' . json_encode($orderNos));
+        } catch (\Exception $e) {
+            app('LogService')->log(__CLASS__, __FUNCTION__ , 'failed update Order batch_id' . '  ' . json_encode($orderNos));
+        }
+    }
+
 }

+ 22 - 22
app/Services/OrderFreezeService.php

@@ -16,16 +16,7 @@ class OrderFreezeService
     public function getFreezes()
     {
         return app(CacheService::class)->getOrExecute("order_freeze_condition_pool",function (){
-            return \App\OrderFreeze::query()
-                ->with(["logistic:id,name","province:id,name","city:id,name","location:id,name"])
-                ->where("status",0)
-                ->get(["logistic_id","province_id","city_id","location_id"])->each(function (&$freeze){
-                    $freeze["logistic_name"] = $freeze->logistic ? $freeze->logistic->name : '';
-                    $freeze["province_name"] = $freeze->province ? $freeze->province->name : '';
-                    $freeze["city_name"]     = $freeze->city ? $freeze->city->name : '';
-                    $freeze["location_name"] = $freeze->location ? $freeze->location->name : '';
-                    unset($freeze->logistic,$freeze->province,$freeze->city,$freeze->location);
-                })->toArray();
+            return $this->get();
         },config("cache.expirations.rarelyChange"));
     }
 
@@ -34,17 +25,26 @@ class OrderFreezeService
      */
     public function refreshFreezes()
     {
-        if (Cache::has("order_freeze_condition_pool")){
-            $val = \App\OrderFreeze::query()
-                ->with(["logistic:id,name", "province:id,name", "city:id,name", "location:id,name"])
-                ->where("status", 0)
-                ->get()->each(function (&$freeze) {
-                    $freeze["logistic_name"] = $freeze->logistic ? $freeze->logistic->name : '';
-                    $freeze["province_name"] = $freeze->province ? $freeze->province->name : '';
-                    $freeze["city_name"] = $freeze->city ? $freeze->city->name : '';
-                    $freeze["location_name"] = $freeze->location ? $freeze->location->name : '';
-                });
-            Cache::put("order_freeze_condition_pool",$val);
-        }
+        if (Cache::has("order_freeze_condition_pool")) Cache::put("order_freeze_condition_pool",$this->get());
+    }
+
+    /**
+     * 获取所有冻结条件
+     *
+     */
+    public function get()
+    {
+        return \App\OrderFreeze::query()
+            ->with(["logistic:id,name","province:id,name","city:id,name","district:id,name","town:id,name","street:id,name"])
+            ->where("status",0)
+            ->get(["logistic_id","province_id","city_id","district_id","town_id","street_id"])->each(function (&$freeze){
+                $freeze["logistic_name"] = $freeze->logistic ? $freeze->logistic->name : '';
+                $freeze["province_name"] = $freeze->province ? $freeze->province->name : '';
+                $freeze["city_name"]     = $freeze->city ? $freeze->city->name : '';
+                $freeze["district_name"] = $freeze->district ? $freeze->district->name : '';
+                $freeze["town_name"] = $freeze->town ? $freeze->town->name : '';
+                $freeze["street_name"] = $freeze->street ? $freeze->street->name : '';
+                unset($freeze->logistic,$freeze->province,$freeze->city,$freeze->district,$freeze->town,$freeze->street);
+            })->toArray();
     }
 }

+ 8 - 7
app/Services/OrderPackageReceivedSyncService.php

@@ -84,7 +84,7 @@ class OrderPackageReceivedSyncService
             if (isset($data['status'])) $orderPackage->status = $data['status'];
             if (isset($data['received_at'])) $orderPackage->received_at = $data['received_at'];
             if (isset($data['exception'])) $orderPackage->exception = $data['exception'];
-            if (isset($data['transfer_status'])) $orderPackage->transfer_status = json_encode($data['transfer_status'],JSON_UNESCAPED_UNICODE);
+            if (isset($data['transfer_status'])) $orderPackage->transfer_status = $data['transfer_status'];
             $orderPackage->save();
         }
     }
@@ -102,13 +102,14 @@ class OrderPackageReceivedSyncService
                 return $query->with('logistic');
             }]);
         if (Carbon::now()->lte($initDate)) {//当前时间小于等于初始化时间
-            $query = $query->where('created_at', '>=', $initDate->subMonths(1)->toDateTimeString()); //初始化查询一个月的数据
-        } else {//当前时间大于初始化时间
-            $query = $query->where('created_at', '>=', $initDate->toDateTimeString()); //大于等于初始化时间的全部快递单号
+            //初始化查询一个月的数据,exception为否
+            $query = $query->where('created_at', '>=', $initDate->subDays((int)config('api_logistic.days'))->toDateTimeString())
+                ->where('exception', '否');
+        } else {//当前时间大于初始化时间,exception为否且未收货
+            $query = $query->where('created_at', '>=', $initDate->toDateTimeString())
+                ->where('exception', '否')
+                ->whereNull('received_at');
         }
-        $query = $query
-            ->where('exception', '否')
-            ->whereNull('received_at');
         return $this->buildData($query->get(), $data);
     }
 

+ 2 - 2
app/Services/OrderService.php

@@ -665,9 +665,8 @@ class OrderService
         }
         unset($created_params);
         $update_params = [
-            ['id','code','warehouse_id','owner_id','batch_id','shop_id','logistic_id','consignee_name','consignee_phone','province','city','district','address','client_code','wms_status','created_at','updated_at','wms_edittime','order_type']
+            ['id','code','warehouse_id','owner_id','batch_id','shop_id','logistic_id','consignee_name','consignee_phone','province','city','district','address','client_code','wms_status','created_at','updated_at','wms_edittime','order_type','frozen']
         ];
-
         $update_order->each(function($item)use(&$update_params){
             $update_params[] = $item->toArray();
         });
@@ -757,6 +756,7 @@ class OrderService
             'wms_edittime' => $orderHeader['edittime'],
             'wms_status' => $orderHeader->oracleBASCode->codename_c??'',
             'order_type' => $orderHeader->orderType->codename_c??'',
+            'frozen' => Order::getFrozen($orderHeader->releasestatus),
             'updated_at' => $date,
             'created_at' => $orderHeader['addtime']
         ];

+ 9 - 3
app/Services/OrderTrackingService.php

@@ -74,6 +74,10 @@ class OrderTrackingService
 //            });
         }
 
+        if(isset($params['order_client_code_wms'])){
+            $query->where('order_client_code_wms','like',$params['order_client_code_wms']);
+        }
+
         if(isset($params['logistic_id']))$query->where('logistic_id',$params['logistic_id']);   // 快递
 
         if ($params['client'] ?? false) $query->where('client', 'like', $params['client']);  // 客户
@@ -311,7 +315,7 @@ class OrderTrackingService
         $BasSKUs_code_sku_map = $dataService->dataHeader(['customerid','sku'],$BasSKUs);
 
         $update_params = [];
-        $update_params[0] =['id','client','pick_up_at','order_remark','gross_weight','bulk','planning_sent_at','web_order_number','order_client_code'];
+        $update_params[0] =['id','client','pick_up_at','order_remark','gross_weight','bulk','planning_sent_at','web_order_number','order_client_code','order_client_code_wms'];
         foreach ($orderHeaders as $orderHeader) {
             if($orderHeader->sostatus == '90'){continue;}
             $order_package_commodity_list = $order_package_commodity_order_code_map[$orderHeader->orderno] ?? false;
@@ -330,8 +334,9 @@ class OrderTrackingService
                     $order_tracking->pick_up_at != $params['pick_up_at'] ||
                     $order_tracking->gross_weight != $params['gross_weight'] ||
                     $order_tracking->bulk != $params['bulk'] ||
-                    $order_tracking->client != $params['client']
-                    || $order_tracking->order_client_code != $params['order_client_code']
+                    $order_tracking->client != $params['client'] ||
+                    $order_tracking->order_client_code_wms != $params['order_client_code_wms'] ||
+                    $order_tracking->order_client_code != $params['order_client_code']
                 ){
                     $params['updated_at'] = Carbon::now();
                     $update_params[] = $params;
@@ -509,6 +514,7 @@ class OrderTrackingService
         $params['gross_weight'] = round($basSkU->grossweight * $orderPackageCommodity->amount, 2) ?? null;  // 重量
         $params['bulk'] = round($basSkU->cube * $orderPackageCommodity->amount, 2) ?? null; // 体积
         $params['created_at'] = Carbon::now();  // 创建时间
+        $params['order_client_code_wms'] = $order->client_code;
         return $params;
     }
 }

+ 3 - 2
app/Services/OwnerPriceOperationService.php

@@ -253,10 +253,11 @@ Class OwnerPriceOperationService
                     }
                     break;
                 default:
-                    if ($isIn)break;
-                    if ($unitName && $unitName != $units[$rule->unit_id])return -3; //校验单位是否一致
+                    if ($isIn)break;    //入库不计算起步
 
                     if ($rule->amount){ //起步数+起步费
+                        if ($unitName && $unitName != $units[$rule->unit_id])return -3; //校验单位是否一致
+
                         $money = $rule->unit_price;
                         $startNumber = $rule->amount;
                         $packages = $this->settingCount($packages,$amountColumn,$startNumber);

+ 3 - 3
app/Services/PackageStatisticsService.php

@@ -20,10 +20,10 @@ Class PackageStatisticsService
     private function conditionQuery(array $params){
         $ownerIds = app('UserService')->getPermittingOwnerIds(auth()->user());
         $query = DB::table('order_packages')->select(DB::raw('COUNT(*) AS count'))
-            ->whereIn('owner_id',$ownerIds)
+            ->whereIn('order_packages.owner_id',$ownerIds)
             ->whereNotNull('logistic_id')
             ->leftJoin('orders','order_packages.order_id','orders.id')
-                ->selectRaw('owner_id,logistic_id');
+                ->selectRaw('orders.owner_id,logistic_id');
 
         $columnQueryRules=[
             'created_at_start' => ['alias' => 'created_at','startDate' => ":00"],
@@ -31,7 +31,7 @@ Class PackageStatisticsService
             'logistic_id' => ['multi' => ','],
             'owner_id' => ['multi' => ','],
         ];
-        $query = $query->groupBy('owner_id','logistic_id');
+        $query = $query->groupBy('order_packages.owner_id','logistic_id');
         return app(QueryService::class)->query($params,$query,$columnQueryRules);
     }
 

+ 30 - 6
app/Services/RegionService.php

@@ -9,6 +9,33 @@ class RegionService
 {
     use ServiceAppAop;
 
+
+    /**
+     * 根据行政级别格式化地域名,提取关键字
+     *
+     * @param string $name
+     * @param int $type
+     *
+     * @return string
+     */
+    public function formatName($name, $type)
+    {
+        switch ($type){
+            case 1:
+                $pool = ["省","自治区","市","特别行政"];
+                break;
+            case 2:
+                $pool = ["市","区","自治州"/*,"州"*/,"盟"];
+                break;
+            case 3:
+                $pool = ["市","区","自治县","县","自治旗","旗","特区","林区"];
+                break;
+            default:
+                $pool = [];
+        }
+        return $this->extractKeyword($name,$pool);
+    }
+
     /**
      * 根据省份获取ID
      *
@@ -18,8 +45,7 @@ class RegionService
      */
     public function getProvince(string $province):int
     {
-        $pool = ["省","自治区","市","特别行政"];
-        $province = $this->extractKeyword($province,$pool);
+        $province = $this->formatName($province,1);
         $region = Region::withTrashed()->where("name","like",$province."%")
             ->where("type",1)->first();
         if (!$region)$region = Region::query()->create([
@@ -39,8 +65,7 @@ class RegionService
      */
     public function getCity(string $city, $parent = null):int
     {
-        $pool = ["市","区","自治州","州","盟"];
-        $city = $this->extractKeyword($city,$pool);
+        $city = $this->formatName($city,2);
         $region = Region::withTrashed()->where("name","like",$city."%")
             ->where("type",2)->first();
         if (!$region){
@@ -67,8 +92,7 @@ class RegionService
      */
     public function getDistrict(string $district, $parent = null):int
     {
-        $pool = ["市","区","自治县","县","自治旗","旗","特区","林区"];
-        $district = $this->extractKeyword($district,$pool);
+        $district = $this->formatName($district,3);
         $region = Region::withTrashed()->where("name","like",$district."%")
             ->where("type",3)->first();
         if (!$region){

+ 12 - 8
app/Services/StationRuleBatchService.php

@@ -15,14 +15,18 @@ use App\Traits\ServiceAppAop;
 class StationRuleBatchService
 {
     use ServiceAppAop;
-    function getByBatch(Batch $batch): StationRuleBatch
+    function getByBatch(Batch $batch): ?StationRuleBatch
     {
         $batchType = $batch['type'] ?? 'null';
         $ownerId = $batch['owner_id'] ?? 'null';
-        return Cache::remember('stationType_type_'.$batchType.'_ownerId_'.$ownerId, config('cache.expirations.rarelyChange'),function($batch){
-            return StationRuleBatch::query()->with('stationType')->where('batch_type',$batch['type'])
-                ->where('owner_id',$batch['owner_id'])
-                ->first();
+        return Cache::remember('stationRuleBatch_batchType_'.$batchType.'_ownerId_'.$ownerId, config('cache.expirations.rarelyChange'),function()use($batch){
+            $builder= StationRuleBatch::query()->with('stationType')
+                ->where('owner_id',$batch['owner_id']);
+            if($batch['type']
+                && $batch['type']!='无'){
+                $builder=$builder->where('batch_type',$batch['type']);
+            }
+            return $builder->first();
         });
     }
 
@@ -33,10 +37,10 @@ class StationRuleBatchService
     }
 
     /**
-     * @param Batch[] $batches
-     * @return Collection
+     * @param Collection $batches
+     * @return Collection Batches
      */
-    function getBatches_canProcess(array $batches): Collection
+    function getBatches_shouldProcess(Collection $batches): Collection
     {
         $batches_toProcess=collect();
         foreach ($batches as $batch){

+ 22 - 0
app/Services/StationService.php

@@ -33,6 +33,28 @@ class StationService
         return $station;
     }
 
+    function getULineEntrance(Station $station):?Station{
+        $station->loadMissing(['stationType','child']);
+        if ($station['stationType']['name']??''=='料箱出货口'){
+            return $station;
+        }
+        if ($station['child']['stationType']['name']??''=='料箱出货口'){
+            return $station['child'];
+        }
+        return null;
+    }
+
+    function getULineExit(Station $station):?Station{
+        $station->loadMissing(['stationType','child']);
+        if ($station['stationType']['name']??''=='料箱入货口'){
+            return $station;
+        }
+        if ($station['child']['stationType']['name']??''=='料箱入货口'){
+            return $station['child'];
+        }
+        return null;
+    }
+
     function broadcast($station_id, $json_data){
         broadcast(new BroadcastToStation($station_id,$json_data));
     }

+ 75 - 39
app/Services/StationTaskBatchService.php

@@ -4,12 +4,8 @@
 namespace App\Services;
 
 
-use App\Batch;
-use App\Log;
-use App\Station;
-use App\StationTask;
+use App\Exceptions\ErrorException;
 use App\StationTaskBatch;
-use App\StationTaskBatchType;
 use Exception;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
@@ -43,59 +39,77 @@ class StationTaskBatchService
     }
 
     /**
-     * @param $batches Batch[]
+     * @param Collection $batches Batch[]
      * @param Collection $stationTasks_toAttach
      * @return Collection
      * @throws Exception
      */
-    function createByBatches(array $batches, Collection $stationTasks_toAttach): Collection
+    function createByBatches(Collection $batches, Collection $stationTasks_toAttach): Collection
     {
         $this->stationService = app('StationService');
+        $this->stationTaskService = app('StationTaskService');
         $this->stationTypeService = app('StationTypeService');
         $this->stationTaskBatchTypeService = app('StationTaskBatchTypeService');
         $this->batchService = app('BatchService');
 
         $stationTaskBatches_toCreate = new Collection();
-        $id_stationTaskBatchType = $this->stationTaskBatchTypeService->firstByWhere('name', 'U型线分捡');
+        $stationTaskBatchType = $this->stationTaskBatchTypeService->firstByWhere('name', 'U型线分捡');
+        $id_stationTaskBatchType=$stationTaskBatchType['id']??'';
 
         $batches_handled = collect();
         foreach ($batches as $batch) {
             if ($batch['status'] == '未处理') {
                 $stationType = $this->stationTypeService->getByBatch($batch);
                 $station = $this->stationService->getStation_byType($stationType['name']);
-                $stationTaskBatches_toCreate->push([
-                    'batch_id' => $batch['id'],
-                    'station_id' => $station['id'],
-                    'station_task_batch_type_id' => $id_stationTaskBatchType,
-                    'status' => '待处理'
-                ]);
+                $stationTaskBatches_toCreate->push(
+                    new StationTaskBatch([
+                        'batch_id' => $batch['id'],
+                        'station_id' => $station['id'],
+                        'station_task_batch_type_id' => $id_stationTaskBatchType,
+                        'status' => '待处理'
+                    ])
+                );
                 $batches_handled->push($batch);
             }
         }
         $this->batchService->updateWhereIn('id', data_get($batches_handled, '*.id'), ['status' => '处理中']);
         $this->insert($stationTaskBatches_toCreate->toArray());
-        $this->stationTaskService->registerSubTasks($stationTasks_toAttach,
-            $stationTaskBatches_toCreate->map(function ($stationMissionBatch) {
-                return [$stationMissionBatch];
+        $stationTaskBatches_toCreate=$this->getAndAttachIds($stationTaskBatches_toCreate);
+        $this->stationTaskService->registerSubTasks(
+            $stationTasks_toAttach,
+            $stationTaskBatches_toCreate->map(function($taskBatch){
+                return [$taskBatch];
             })
         );
 
         return $stationTaskBatches_toCreate;
     }
 
+    function getAndAttachIds($stationTaskBatches): Collection
+    {
+        $md5=is_array($stationTaskBatches)
+            ?$md5=md5(json_encode($stationTaskBatches)):null;
+
+        return Cache::remember(
+            'StationTaskBatch_'.$md5??md5(json_encode($stationTaskBatches->toArray()))
+            ,config('cache.expirations.rarelyChange')
+            ,function()use($stationTaskBatches){
+            return StationTaskBatch::query()
+                ->whereIn('status',data_get($stationTaskBatches,'*.status'))
+                ->whereIn('batch_id',data_get($stationTaskBatches,'*.batch_id'))
+                ->get();
+        });
+    }
     function insert(array $stationMissionBatches): bool
     {
-        $inserted = StationTaskBatch::query()->insert($stationMissionBatches);
-        LogService::log(__METHOD__, __FUNCTION__, json_encode($stationMissionBatches) .
-            '||' . json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 0, 3)));
-        return $inserted;
+        return StationTaskBatch::query()->insert($stationMissionBatches);
     }
 
     function markManyExcepted(Collection $stationTaskBatches_failed)
     {
         foreach (
             $stationTaskBatches_failed
-                 as $stationTaskBatch) {
+            as $stationTaskBatch) {
             if($stationTaskBatch['status']!='异常')
                 $this->markExcepted($stationTaskBatch);
         }
@@ -103,10 +117,7 @@ class StationTaskBatchService
         ($logAtFailings_andWait =
             function ($stationTaskBatches_failed) {
                 if ($stationTaskBatches_failed->isEmpty()) return;
-                LogService::log(__METHOD__, __FUNCTION__,
-                    '任务波次异常失败的:' . $stationTaskBatches_failed->toJson()
-                    . '调用堆栈:' . json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 0, 3))
-                );
+                throw new ErrorException('任务波次异常失败的');
             })($stationTaskBatches_failed);
     }
 
@@ -114,7 +125,7 @@ class StationTaskBatchService
      * @param Collection $stationTaskBatches
      * @return Collection|\Tightenco\Collect\Support\Collection|null 返回执行失败的记录
      */
-    function runMany(Collection $stationTaskBatches)
+    function runMany(Collection $stationTaskBatches):?Collection
     {
         $stationTaskBatches_failed = null;
         ($execute =
@@ -146,14 +157,18 @@ class StationTaskBatchService
 
     function run(StationTaskBatch $stationTaskBatch): bool
     {
-        $toLocation         = $stationTaskBatch['station']['code'];
+        $this->instant($this->foreignHaiRoboticsService,'ForeignHaiRoboticsService');
+        $this->instant($this->stationService,'StationService');
+        $stationTaskBatch->loadMissing(['station','stationTask.stationTaskMaterialBoxes']);
+        $toLocation         = $this->stationService->getULineEntrance($stationTaskBatch['station'])['code'];
         $groupPrefix        = $stationTaskBatch['id'];
-        $taskMaterialBoxes  = $stationTaskBatch['stationTask']['taskMaterialBoxes'] ??
-            function () use ($stationTaskBatch) {
+        $taskMaterialBoxes  = $stationTaskBatch['stationTask']['stationTaskMaterialBoxes'] ??
+            (function () use ($stationTaskBatch) {
                 throw new Exception('找不到料箱:' . json_encode($stationTaskBatch));
-            };
-        $isFetchedFromRobotics          = $this->foreignHaiRoboticsService->
-                                    fetchGroupToProcessor($toLocation, $taskMaterialBoxes, $groupPrefix);
+            })();
+        $isFetchedFromRobotics
+            = $this->foreignHaiRoboticsService->
+        fetchGroup($toLocation, $taskMaterialBoxes, $groupPrefix);
         ($markNewStatus
             =function()use($isFetchedFromRobotics,$stationTaskBatch){
             $isFetchedFromRobotics?
@@ -163,15 +178,36 @@ class StationTaskBatchService
         return $isFetchedFromRobotics;
     }
 
-    function markProcessing(StationTaskBatch $stationTaskBatch)
+    function markProcessing($stationTaskBatches)
     {
-        $stationTaskBatch   ['status']                  = '处理中';
-        $stationTaskBatch   ->update();
-        $stationTaskBatch   ->loadMissing               ('stationTask');
-        $stationTaskBatch   ['stationTask']['status']   = '异常';
-        $stationTaskBatch   ['stationTask']             ->update();
+        if (get_class($stationTaskBatches)==StationTaskBatch::class){
+            $stationTaskBatches = collect($stationTaskBatches);
+        }
+        StationTaskBatch::query()
+            ->whereIn('id', data_get($stationTaskBatches, '*.id'))
+            ->update(['status'=>'处理中']);
+
+        $this->stationTaskService
+            ->markProcessing_byId(
+                data_get($stationTaskBatches, '*.station_id')
+            );
     }
 
+//    function markFinished($stationTaskBatches)
+//    {
+//        if (get_class($stationTaskBatches)==StationTaskBatch::class){
+//            $stationTaskBatches = collect($stationTaskBatches);
+//        }
+//        StationTaskBatch::query()
+//            ->whereIn('id', data_get($stationTaskBatches, '*.id'))
+//            ->update(['status'=>'完成']);
+//
+//        $this->stationTaskService
+//            ->markProcessing_byId(
+//                data_get($stationTaskBatches, '*.station_id')
+//            );
+//    }
+
     function markExcepted(StationTaskBatch $stationTaskBatch)
     {
         $stationTaskBatch['status'] = '异常';

+ 1 - 2
app/Services/StationTaskBatchTypeService.php

@@ -6,7 +6,6 @@ namespace App\Services;
 
 use App\Station;
 use App\StationTaskBatchType;
-use App\StationType;
 use Illuminate\Support\Facades\Cache;
 use App\Traits\ServiceAppAop;
 
@@ -19,7 +18,7 @@ class StationTaskBatchTypeService
      * @param string $value
      * @return Station
      */
-    public function firstByWhere(string $key,string $value):Station{
+    public function firstByWhere(string $key,string $value):StationTaskBatchType{
         return Cache::remember('station_mission_batch_type_id_by_'.$key.$value, config('cache.expirations.rarelyChange'), function ()use($key,$value) {
             $stationMissionBatchType =StationTaskBatchType::query()->where($key, $value)->first();
             if(!$stationMissionBatchType)throw new \Exception("找不到 StationMissionBatchType,where $key = $value");

+ 73 - 20
app/Services/StationTaskCommodityService.php

@@ -6,6 +6,8 @@ namespace App\Services;
 
 use App\Batch;
 use App\OrderCommodity;
+use App\StationTask;
+use App\StationTaskBatch;
 use App\StationTaskCommodity;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
@@ -42,18 +44,50 @@ class StationTaskCommodityService
         });
     }
 
-    function createByBatches(array $batches,Collection $stationTasks_toAttach): Collection
+    function createByBatches(Collection $batches,Collection $stationTasks_toAttach): Collection
     {
         $this->instant($this->stationTaskService,'StationTaskService');
         $stationTaskCommodities_listByBatch=new Collection();
+        $stationTaskCommodities=new Collection();
         foreach ($batches as $batch){
-            $stationTaskCommodities_listByBatch->push(
-                $this->createByBatch($batch)
-            );
+            $taskCommodities = $this->createByBatch($batch);
+            $stationTaskCommodities= $stationTaskCommodities->merge($taskCommodities);
+            $stationTaskCommodities_listByBatch->push($taskCommodities);
         }
-        $this->stationTaskService->registerSubTasks($stationTasks_toAttach,$stationTaskCommodities_listByBatch);
+//        $stationTaskCommodities=$this->getAndAttachIds($stationTaskCommodities);
+        $this->stationTaskService->registerSubTasks(
+            $stationTasks_toAttach,
+            $stationTaskCommodities_listByBatch);
+        return $stationTaskCommodities;
+
     }
 
+//    function getAndAttachIds($taskCommodities): Collection
+//    {
+//        $md5=is_array($taskCommodities)
+//            ?$md5=md5(json_encode($taskCommodities)):null;
+//
+//        return Cache::remember(
+//            'StationTaskCommodity_'.$md5??md5(json_encode($taskCommodities->toArray()))
+//            ,config('cache.expirations.rarelyChange')
+//            ,function()use($taskCommodities){
+//                $a=data_get($taskCommodities,'*.status');
+//                $a2=data_get($taskCommodities,'*.station_task_batch_id');
+//                $a3=data_get($taskCommodities,'*.commodity_id');
+//                $a4=StationTaskCommodity::query()
+//                    ->whereIn('status',data_get($taskCommodities,'*.status'))
+//                    ->whereIn('station_task_batch_id',data_get($taskCommodities,'*.station_task_batch_id'))
+//                    ->whereIn('commodity_id',data_get($taskCommodities,'*.commodity_id'))
+//                    ->get();
+//                $a5=1;
+//            return StationTaskCommodity::query()
+//                ->whereIn('status',data_get($taskCommodities,'*.status'))
+//                ->whereIn('station_task_batch_id',data_get($taskCommodities,'*.station_task_batch_id'))
+//                ->whereIn('commodity_id',data_get($taskCommodities,'*.commodity_id'))
+//                ->get();
+//        });
+//    }
+
     function createByBatch(Batch $batch): Collection
     {
         $this->instant($this->stationTypeService,'StationTypeService');
@@ -66,24 +100,43 @@ class StationTaskCommodityService
             $stationType=$this->stationTypeService->getForCommodity();
             $station=$this->stationService->getStation_byType($stationType['name']);
             $materialBox=$this->materialBoxService->firstOrCreate(['code' => $orderCommodity['location']]);
-            $stationTaskCommodities_toCreate->push([
-                'station_id'=>$station['id'],
-                'material_box_id'=>$materialBox['id'],
-                'commodity_id'=>$orderCommodity['commodity_id'],
-                'amount'=>$orderCommodity['amount'],
-                'bin_number'=>$orderCommodity['orderBin']['number']??'',
-                'order_id'=>$orderCommodity['order_id'],
-                'status'=>'待处理'
-            ]);
+            $stationTaskCommodities_toCreate->push(
+                new StationTaskCommodity([
+                    'station_id'=>$station['id'],
+                    'material_box_id'=>$materialBox['id'],
+                    'commodity_id'=>$orderCommodity['commodity_id'],
+                    'amount'=>$orderCommodity['amount'],
+                    'bin_number'=>$orderCommodity['orderBin']['number']??'',
+                    'order_id'=>$orderCommodity['order_id'],
+                    'station_task_batch_id'=>$batch['id'],
+                    'status'=>'待处理'
+                ])
+            );
         }
-        $this->insert($stationTaskCommodities_toCreate->toArray());
+        return $this->insert($stationTaskCommodities_toCreate->toArray());
     }
 
-    public function insert(array $stationTaskCommodities): bool
+    public function insert(array $taskCommodities): ?Collection
     {
-        $inserted = StationTaskCommodity::query()->insert($stationTaskCommodities);
-        LogService::log(__METHOD__,__FUNCTION__,json_encode($stationTaskCommodities).
-            '||'.json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),0,3)));
-        return $inserted;
+        StationTaskCommodity::query()->insert($taskCommodities);
+        return StationTaskCommodity::query()
+            ->whereIn('status', data_get($taskCommodities, '*.status'))
+            ->whereIn('station_task_batch_id', data_get($taskCommodities, '*.station_task_batch_id'))
+            ->whereIn('commodity_id', data_get($taskCommodities, '*.commodity_id'))
+            ->get();
+    }
+    function markProcessing($stationTaskCommodities)
+    {
+        if (get_class($stationTaskCommodities)==StationTaskCommodity::class){
+            $stationTaskCommodities = collect($stationTaskCommodities);
+        }
+        StationTaskCommodity::query()
+            ->whereIn('id',data_get($stationTaskCommodities,'*.id'))
+            ->update(['status'=>'处理中']);
+
+        $this->stationTaskService
+            ->markProcessing_byId(
+                data_get($stationTaskCommodities, '*.station_id')
+            );
     }
 }

+ 107 - 15
app/Services/StationTaskMaterialBoxService.php

@@ -5,7 +5,10 @@ namespace App\Services;
 
 
 use App\Batch;
+use App\Exceptions\ErrorException;
+use App\MaterialBox;
 use App\OrderCommodity;
+use App\StationTask;
 use App\StationTaskMaterialBox;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
@@ -21,6 +24,10 @@ class StationTaskMaterialBoxService
     private $stationTypeService;
     /** @var StationTaskService $stationTaskService */
     private $stationTaskService;
+    /** @var StationTaskBatchService $stationTaskBatchService */
+    private $stationTaskBatchService;
+    /** @var StationTaskCommodityService $stationTaskCommodityService */
+    private $stationTaskCommodityService;
     /** @var MaterialBoxService $materialBoxService */
     private $materialBoxService;
     public function __construct(){
@@ -28,20 +35,32 @@ class StationTaskMaterialBoxService
         $this->stationTypeService=null;
         $this->stationTaskService=null;
         $this->materialBoxService=null;
+        $this->stationTaskBatchService=null;
+        $this->stationTaskCommodityService=null;
     }
-    function createByBatches(array $batches,Collection $stationTasks_toAttach): Collection
+
+    function createByBatches(Collection $batches,Collection $stationTasks_toAttach): Collection
     {
-        $stationTaskMaterialBoxes_listByBatch=new Collection();
-        foreach ($batches as $batch){
-            $stationTaskMaterialBoxes_listByBatch->push(
-                $this->createByBatch($batch)
-            );
-        }
-        $this->stationTaskService->registerSubTasks($stationTasks_toAttach,$stationTaskMaterialBoxes_listByBatch);
+        $this->instant($this->stationTaskService,'StationTaskService');
+        $stationTaskMaterialBoxes = (function () use ($batches) {
+            $stationTaskMaterialBoxes_listByBatch = new Collection();
+            foreach ($batches as $batch) {
+                $stationTaskMaterialBoxes_listByBatch=
+                    $stationTaskMaterialBoxes_listByBatch->merge(
+                    $this->createByBatch($batch)
+                );
+            }
+            return $stationTaskMaterialBoxes_listByBatch;
+        })();
+         $this->stationTaskService
+            ->registerSubTasks(
+                $stationTasks_toAttach,
+                [$stationTaskMaterialBoxes]);
+        return $stationTaskMaterialBoxes;
 
     }
 
-    function createByBatch(Batch $batch): Collection
+    function createByBatch(Batch $batch): ?Collection
     {
         $this->instant($this->materialBoxService,'MaterialBoxService');
         $this->instant($this->stationTypeService,'StationTypeService');
@@ -49,8 +68,9 @@ class StationTaskMaterialBoxService
         $stationMaterialBoxes_toCreate=new Collection();
         $order_ids=data_get($batch['orders'],'*.id');
         $orderCommodities=OrderCommodity::query()->with('orderBin')->whereIn('order_id',$order_ids)->get();
+        if($orderCommodities->isEmpty())return $stationMaterialBoxes_toCreate;
+        $stationType=$this->stationTypeService->getForMaterialBox_onBatchProcess();
         foreach ($orderCommodities as $orderCommodity){
-            $stationType=$this->stationTypeService->getForMaterialBox();
             $station=$this->stationService->getStation_byType($stationType['name']);
             $materialBox=$this->materialBoxService->firstOrCreate(['code' => $orderCommodity['location']]);
             $stationMaterialBoxes_toCreate->push([
@@ -59,7 +79,7 @@ class StationTaskMaterialBoxService
                 'status'=>'待处理'
             ]);
         }
-        $this->insert($stationMaterialBoxes_toCreate->toArray());
+        return $this->insert($stationMaterialBoxes_toCreate->toArray());
     }
 
     function get(array $kvPairs){
@@ -74,11 +94,83 @@ class StationTaskMaterialBoxService
         });
     }
 
-    public function insert(array $stationTaskMaterialBoxes): bool
+    public function insert(array $stationTaskMaterialBoxes): Collection
     {
-        $inserted = StationTaskMaterialBox::query()->insert($stationTaskMaterialBoxes);
-        LogService::log(__METHOD__,__FUNCTION__,json_encode($stationTaskMaterialBoxes).
-            '||'.json_encode(array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),0,3)));
+        $inserted=collect();
+        foreach ($stationTaskMaterialBoxes as $stationTaskMaterialBox){
+            $inserted->push(StationTaskMaterialBox::query()->create($stationTaskMaterialBox));
+        }
         return $inserted;
     }
+
+    function markHasPut(StationTaskMaterialBox $stationTaskMaterialBox){
+        try{
+            $taskType=$this->getServingTaskType($stationTaskMaterialBox);
+            switch ($taskType){
+                case '分波次':
+                    $this->markProcessing($stationTaskMaterialBox);
+                    $this->stationTaskBatchService->markProcessing($stationTaskMaterialBox['stationTaskBatch']);
+                    $this->stationTaskCommodityService->markProcessing($stationTaskMaterialBox['stationTaskCommodities']);
+                    break;
+                case '入立库':
+
+                    break;
+                case '入库':break;
+            }
+        }catch (\Exception $e){
+            throw new ErrorException('放置料箱出错');
+        }
+    }
+
+    function markTaken($stationTaskMaterialBox){
+        //TODO: 标记 料箱位置(需要其字段存在)$stationTaskMaterialBox['materialBox']['position']
+    }
+    function markProcessed(StationTaskMaterialBox $stationTaskMaterialBox){
+        $stationTaskMaterialBox['status'] = '完成';
+        $stationTaskMaterialBox->save();
+        $this->stationService->broadcastBinMonitor($stationTaskMaterialBox['station_id'],$stationTaskMaterialBox['stationTask']);
+    }
+
+    function markProcessing($stationTaskMaterialBox)
+    {
+        if (get_class($stationTaskMaterialBox)==StationTaskMaterialBox::class){
+            $stationTaskMaterialBox = collect($stationTaskMaterialBox);
+        }
+        StationTaskMaterialBox::query()
+            ->whereIn('id', data_get($stationTaskMaterialBox, '*.id'))
+            ->update(['status'=>'处理中']);
+        $this->stationTaskService
+            ->markProcessing_byId(
+                data_get($stationTaskMaterialBox, '*.station_id')
+            );
+    }
+
+    function excepted($stationTaskMaterialBox_orBox){
+        switch (get_class($stationTaskMaterialBox_orBox)){
+            case MaterialBox::class:
+            case StationTaskMaterialBox::class:
+            throw new ErrorException('料箱异常'.json_encode($stationTaskMaterialBox_orBox->toJson()));
+        }
+    }
+
+    function getServingTaskType(StationTaskMaterialBox $stationTaskMaterialBox): string
+    {
+        $stationTaskMaterialBox->loadMissing('station.stationType');
+        if($isBatching=(
+            $stationTaskMaterialBox['station_task_batch_id'] &&
+            $stationTaskMaterialBox['station']['stationType'] == '料箱监视器')
+        ){
+            return '分波次';
+        }
+        if($isPuttingBack=(
+            !$stationTaskMaterialBox &&
+            $stationTaskMaterialBox['station']['stationType'] == '立库')
+        ){
+            return '入立库';
+        }
+        if($isStoring=false){
+            return '入库';
+        }
+        throw new ErrorException('当前类型找不到');
+    }
 }

+ 17 - 16
app/Services/StationTaskService.php

@@ -34,37 +34,38 @@ class StationTaskService
     }
 
     /**
-     * 个列表一一对应,每个task注册一组子任务: [task,task...],[[subTask,subTask],[subTask,subTask]....]
+     * 个列表一一对应,每个task注册一组子任务: [task,task...],[[subTask,subTask],[subTask,subTask]....]
      * @param Collection $tasks
      * @param Collection $subTaskLists 二维数组,第一维是对应注册的任务
-     * @return array
      */
-    function registerSubTasks(Collection $tasks, Collection $subTaskLists): array
+    function registerSubTasks(Collection $tasks, iterable $subTaskLists)
     {
         $this->instant($this->stationTaskChildService,'StationTaskChildService');
         $taskChildren_toInsert=collect();
         foreach ($subTaskLists as $i=>$subTaskList){
             foreach ($subTaskList as $subTask){
-                $tableName=(function()use($subTask){
-                    switch (get_class($subTask)){
-                        case StationTaskBatch::class: return 'station_task_batches';
-                        case StationTaskCommodity::class: return 'station_task_commodities';
-                        case StationTaskMaterialBox::class: return 'station_task_material_boxes';
-                        default:
-                            throw new \Exception('任务类型没有定义相应的模型类');
-                    }
-                })();
                 $paramToInsert = [
                     'station_task_id' => $tasks[$i]['id'],
-                    'station_task_table_type' => $tableName,
-                    'station_task_table_id' => $subTask['id'],
+                    'station_taskable_type' => get_class($subTask),
+                    'station_taskable_id' => $subTask['id'],
                 ];
-                $taskChild=$this->stationTaskChildService->get($paramToInsert)->frist();
-                if(!$taskChild)
+                $taskChild_existed=$this->stationTaskChildService->get($paramToInsert)->first();
+                if(!$taskChild_existed){
                     $taskChildren_toInsert->push($paramToInsert);
+                    $subTask['station_task_id']=$tasks[$i]['id'];
+                    $subTask->save();
+                }
             }
         }
         $this->stationTaskChildService->insert($taskChildren_toInsert->toArray());
     }
 
+    function markProcessing_byId($stationTaskIds)
+    {
+        StationTask::query()
+            ->whereIn('id',$stationTaskIds)
+            ->update(['status'=>'处理中']);
+    }
+
+
 }

+ 9 - 0
app/Services/StationTaskTypeService.php

@@ -0,0 +1,9 @@
+<?php 
+
+namespace App\Services; 
+
+Class StationTaskTypeService
+{ 
+
+
+}

+ 9 - 0
app/Services/StationTypeBinMonitorService.php

@@ -0,0 +1,9 @@
+<?php 
+
+namespace App\Services; 
+
+Class StationTypeBinMonitorService
+{ 
+
+
+}

+ 6 - 5
app/Services/StationTypeService.php

@@ -19,20 +19,21 @@ class StationTypeService
     {
         $this->stationRuleBatchService=null;
     }
-
-    function getByBatch(Batch $batch): StationType
+    function getByBatch(Batch $batch)
     {
         $this->instant($this->stationRuleBatchService,'StationRuleBatchService');
-        $stationRuleBatch=$this->stationRuleBatchService->getByBatch($batch);
-        return $stationRuleBatch['stationType'];
+//        return $stationRuleBatch['stationType'];
+        return StationType::query()->where('name','料箱监视器')->first();
     }
+
     function getForCommodity(): StationType
     {
         /** @var StationType $stationType */
         $stationType= StationType::query()->firstOrCreate(['name'=>'料箱监视器']);
         return $stationType;
     }
-    function getForMaterialBox(): StationType
+
+    function getForMaterialBox_onBatchProcess(): StationType
     {
         /** @var StationType $stationType */
         $stationType= StationType::query()->firstOrCreate(['name'=>'料箱监视器']);

+ 1 - 1
app/Services/WaybillService.php

@@ -21,7 +21,7 @@ Class WaybillService
      */
     private function conditionQuery(array $param){
         $waybills = Waybill::filterAuthorities()->with(['owner','logistic','originationCity','destinationCity.province',
-            'uploadFile','amountUnit','warehouseWeightUnit','carrierWeightUnit',
+            'uploadFile','amountUnit','warehouseWeightUnit','carrierWeightUnit','district',
             'warehouseWeightUnitOther','carrierWeightUnitOther','carType','uploadFile','waybillAuditLogs.user'])
             ->selectRaw('waybills.* ,waybill_on_tops.id top_id ,waybill_on_tops.remark,waybill_on_tops.updated_at top_update')
             ->leftJoin('waybill_on_tops','waybill_on_tops.waybill_id','=','waybills.id')

+ 6 - 3
app/Station.php

@@ -12,10 +12,13 @@ class Station extends Model
 
     protected $fillable=['name', 'code', 'station_type_id','sequence','parent_id'];
 
-    public function type(){
-        return $this->belongsTo(StationType::class,'station_type_id');
+    public function stationType(){
+        return $this->belongsTo(StationType::class);
     }
     public function parent(){
-        return $this->belongsTo(Station::class,'parent_id','id');
+        return $this->belongsTo(Station::class);
+    }
+    public function child(){
+        return $this->hasOne(Station::class,'parent_id');
     }
 }

+ 3 - 2
app/StationRuleBatch.php

@@ -3,6 +3,7 @@
 namespace App;
 
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasOne;
 
 use App\Traits\LogModelChanging;
@@ -13,8 +14,8 @@ class StationRuleBatch extends Model
 
     protected $fillable=['name','station_type_id','batch_type','owner_id'];
 
-    public function stationType(): HasOne
+    public function stationType(): BelongsTo
     {
-        return $this->hasOne(StationType::class);
+        return $this->belongsTo(StationType::class);
     }
 }

+ 27 - 3
app/StationTask.php

@@ -19,14 +19,38 @@ class StationTask extends Model
 
     public function stationTaskCommodities()
     {   //任务商品列表
-        return $this->morphTo()->where("station_task_table_type","station_task_commodities");
+        return $this->morphToMany(
+            StationTaskCommodity::class,
+            'station_taskable',
+            'station_task_children',
+            'station_task_id',
+            'station_taskable_id',
+            'id',
+            'id',
+            true);
     }
     public function stationTaskBatches()
     {   //任务波次 目前为单个,取值时应取第一个即可
-        return $this->morphTo()->where("station_task_table_type","station_task_batches");
+        return $this->morphToMany(
+            StationTaskBatch::class,
+            'station_taskable',
+            'station_task_children',
+            'station_task_id',
+            'station_taskable_id',
+            'id',
+            'id',
+            true);
     }
     public function stationTaskMaterialBoxes()
     {   //任务料箱
-        return $this->morphTo()->where("station_task_table_type","station_task_material_boxes");
+        return $this->morphToMany(
+            StationTaskMaterialBox::class,
+            'station_taskable',
+            'station_task_children',
+            'station_task_id',
+            'station_taskable_id',
+            'id',
+            'id',
+        true);
     }
 }

+ 7 - 6
app/StationTaskBatch.php

@@ -3,6 +3,7 @@
 namespace App;
 
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Database\Eloquent\Relations\MorphOne;
 
@@ -14,17 +15,17 @@ class StationTaskBatch extends Model
 
     protected $fillable=['batch_id','station_id','station_task_batch_type_id','status'];
 
-    function station(): HasOne
+    function station(): BelongsTo
     {
-        return $this->hasOne(Station::class);
+        return $this->belongsTo(Station::class);
     }
-    function stationTask(): MorphOne
+    function stationTask(): BelongsTo
     {
-        return $this->morphOne(StationTask::class,'station_taskable');
+        return $this->belongsTo(StationTask::class);
     }
 
-    public function batch(): HasOne
+    public function batch(): BelongsTo
     {   //波次
-        return $this->hasOne(Batch::class,"id","batch_id");
+        return $this->belongsTo(Batch::class);
     }
 }

+ 1 - 1
app/StationTaskChild.php

@@ -10,5 +10,5 @@ class StationTaskChild extends Model
 {
     use LogModelChanging;
 
-    protected $fillable= ['station_task_id','station_task_table_type','station_task_table_id'];
+    protected $fillable= ['station_task_id','station_taskable_type','station_taskable_id'];
 }

+ 9 - 7
app/StationTaskCommodity.php

@@ -5,22 +5,24 @@ namespace App;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\LogModelChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
 class StationTaskCommodity extends Model
 {
     use LogModelChanging;
 
-    protected $fillable= ['station_id','material_box_id','commodity_id','amount','order_id','status',"bin_number"];
+    protected $fillable= ['station_id','material_box_id','commodity_id','amount','order_id','status',"bin_number","station_task_batch_id"];
 
-    public function commodity()
+    public function commodity(): BelongsTo
     {   //商品
-        return $this->hasOne(Commodity::class,"id","commodity_id");
+        return $this->belongsTo(Commodity::class);
     }
-    public function materialBox()
+    public function materialBox(): BelongsTo
     {   //料箱
-        return $this->hasOne(MaterialBox::class,"id","material_box_id");
+        return $this->belongsTo(MaterialBox::class);
     }
-    function parentTask(){
-        return $this->morphOne(StationTask::class,'station_taskable');
+    function stationTask(): BelongsTo
+    {
+        return $this->belongsTo(StationTask::class);
     }
 }

+ 21 - 4
app/StationTaskMaterialBox.php

@@ -3,6 +3,9 @@
 namespace App;
 
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+use Illuminate\Database\Eloquent\Relations\MorphOne;
 
 use App\Traits\LogModelChanging;
 
@@ -12,11 +15,25 @@ class StationTaskMaterialBox extends Model
 
     protected $fillable=['station_id','material_box_id','status'];
 
-    public function materialBox()
-    {   //料箱
+    function materialBox(): HasOne
+    {
         return $this->hasOne(MaterialBox::class,"id","material_box_id");
     }
-    function parentTask(){
-        return $this->morphOne(StationTask::class,'station_taskable');
+    function station(): BelongsTo
+    {
+        return $this->belongsTo(Station::class,"id","station_id");
+    }
+    function stationTaskBatch(): BelongsTo
+    {
+        return $this->belongsTo(StationTaskBatch::class,"id","station_id");
+    }
+    function stationTask(): BelongsTo
+    {
+        return $this->belongsTo(StationTask::class);
+    }
+    function stationTaskCommodities(): HasOne
+    {
+        return $this->hasOne(StationTaskCommodity::class,"station_task_batch_id","station_task_batch_id")
+        ->where('material_box_id',$this['material_box_id']);
     }
 }

+ 44 - 4
app/Traits/TestMockSubServices.php

@@ -5,11 +5,13 @@ trait TestMockSubServices{
     function subMock(array $serviceDefinition){
         $mockingService=$this->createPartialMock(
             $serviceDefinition['class'],
-            array_keys($serviceDefinition['methods'])
+            isset($serviceDefinition['methods'])
+                ?array_keys($serviceDefinition['methods']):[]
         );
-        foreach ($serviceDefinition['methods'] as $mName=>$mVal){
-            $mockingService->method($mName)->willReturn($mVal);
-        }
+        if(isset($serviceDefinition['methods']))
+            foreach ($serviceDefinition['methods'] as $mName=>$mVal){
+                $mockingService->method($mName)->willReturn($mVal);
+            }
 
         if(isset($serviceDefinition['subServices']))
             foreach ($serviceDefinition['subServices'] as $subService){
@@ -31,4 +33,42 @@ trait TestMockSubServices{
         return $mockingService;
     }
 
+    function getTargetIdCirculately($targetArr, $additionMark='', $idName='id'){
+        $amount = count($targetArr);
+
+        $json_encode = json_encode($targetArr);
+        $iName = 'i_' . md5($json_encode . $additionMark);
+        if(!isset($this->data[$iName])){
+            $this->data[$iName]=$amount;
+        }
+        $this->data[$iName]++;
+        if($this->data[$iName]>=$this->batchAmount)
+            $this->data[$iName]=0;
+        return $targetArr[$this->data[$iName]][$idName];
+    }
+    function getIntegerIncreasely($markStr): int
+    {
+        $iName = 'i_' . $markStr;
+        if(!isset($this->data[$iName])){
+            $this->data[$iName]=-1;
+        }
+        $this->data[$iName]++;
+        return $this->data[$iName];
+    }
+    function makeArray($amount,$array)
+    {
+        $resultArrays=[];
+        for($i=0;$i<$amount;$i++){
+            $newArr=[];
+            foreach ($array as $key=>$item){
+                if(gettype($item)=='object'){
+                    $newArr[$key]=$item();
+                }else{
+                    $newArr[$key]=$item;
+                }
+            }
+            $resultArrays[]= $newArr;
+        }
+        return $resultArrays;
+    }
 }

+ 2 - 2
config/api.php

@@ -46,8 +46,8 @@ return [
     'haiq'=>[
         'storage'=>[
 //            'relocate' => "http://59.37.126.227:65448/api/haiqEss/gr/relocate",
-            'moveBin' => "http://192.168.1.201:2011/api/haiqEss/gr/relocate",  //移动料箱
-            'light' => "http://192.168.1.201:40000/api/haiqEss/ctlPTL",  //控灯
+            'moveBin' => "http://58.33.243.164:10022/api/haiqEss/gr/relocate",  //移动料箱
+            'light' => "http://58.33.243.164:10022/api/haiqEss/ctlPTL",  //控灯
         ],
     ],
 

+ 2 - 1
config/api_logistic.php

@@ -106,5 +106,6 @@ return [
         'x-appKey' => 'c51c718eb899e9f706979',
         'x-dataDigest' => '9f664e3ab08049874aa417720840161a',
     ],
-    'init_date' => '2021-01-17 23:59:59',
+    'init_date' => '2021-01-25 23:59:59',
+    'days' => 7,
 ];

+ 1 - 1
database/factories/MaterialBoxFactory.php

@@ -7,6 +7,6 @@ use Faker\Generator as Faker;
 
 $factory->define(MaterialBox::class, function (Faker $faker) {
     return [
-        'code'=>md5(\Illuminate\Support\Str::random(5)).date('Ymd')
+        'code'=>md5(\Illuminate\Support\Str::random(5).microtime(true))
     ];
 });

+ 6 - 3
database/factories/OwnerFactory.php

@@ -1,19 +1,22 @@
 <?php
 
-/** @var \Illuminate\Database\Eloquent\Factory $factory */
+/** @var Factory $factory */
 
 use App\Owner;
+use App\UserOwnerGroup;
 use Faker\Generator as Faker;
+use Illuminate\Database\Eloquent\Factory;
+use Illuminate\Support\Str;
 
 $factory->define(Owner::class, function (Faker $faker) {
     return [
         'name' => $faker->name,                 //名称
-        'code' => \Illuminate\Support\Str::random(5).date('yymmdd'),                 //代码
+        'code' => Str::random(5).date('yymmdd'),                 //代码
         'checking_count' => mt_rand(0,5),       //审核数量
         "tax_rate" => mt_rand(0,100) / 10,             //税率
         "linkman" => $faker->name,              //联系人
         "phone_number" => $faker->phoneNumber,         //联系电话
-        "user_owner_group_id" => factory(\App\UserOwnerGroup::class),  //项目组ID
+        "user_owner_group_id" => factory(UserOwnerGroup::class),  //项目组ID
         "waring_line_on" => mt_rand(0,1000),       //月单量预警
         "description" => $faker->text           //描述
     ];

+ 0 - 12
database/factories/StationMissionBatchFactory.php

@@ -1,12 +0,0 @@
-<?php
-
-/** @var \Illuminate\Database\Eloquent\Factory $factory */
-
-use App\StationTaskBatch;
-use Faker\Generator as Faker;
-
-$factory->define(StationTaskBatch::class, function (Faker $faker) {
-    return [
-        //
-    ];
-});

+ 0 - 12
database/factories/StationMissionCommodityFactory.php

@@ -1,12 +0,0 @@
-<?php
-
-/** @var \Illuminate\Database\Eloquent\Factory $factory */
-
-use App\StationTaskCommodity;
-use Faker\Generator as Faker;
-
-$factory->define(StationTaskCommodity::class, function (Faker $faker) {
-    return [
-        //
-    ];
-});

+ 1 - 1
database/factories/StationRuleBatchFactory.php

@@ -7,6 +7,6 @@ use Faker\Generator as Faker;
 
 $factory->define(StationRuleBatch::class, function (Faker $faker) {
     return [
-        //
+        'name' => $faker->uuid,
     ];
 });

+ 0 - 0
database/factories/StationMissionBatchTypeFactory.php → database/factories/StationTaskBatchTypeFactory.php


+ 1 - 1
database/factories/StationTaskFactory.php

@@ -8,6 +8,6 @@ use Faker\Generator as Faker;
 $factory->define(StationTask::class, function (Faker $faker) {
     $status = ['待处理','挂起','处理中','完成','异常','取消'];
     return [
-        "status"=>$status[array_rand($status)],
+        "status"=>'待处理',
     ];
 });

+ 1 - 1
database/factories/StationMissionMaterialBoxFactory.php → database/factories/StationTaskMaterialBoxFactory.php

@@ -7,6 +7,6 @@ use Faker\Generator as Faker;
 
 $factory->define(StationTaskMaterialBox::class, function (Faker $faker) {
     return [
-        //
+        'status'=>'待处理'
     ];
 });

+ 1 - 1
database/factories/StationTypeFactory.php

@@ -7,6 +7,6 @@ use Faker\Generator as Faker;
 
 $factory->define(StationType::class, function (Faker $faker) {
     return [
-        //
+        'name'=>$faker->name
     ];
 });

+ 6 - 1
database/migrations/2020_11_30_140958_create_stations_table.php

@@ -25,7 +25,12 @@ class CreateStationsTable extends Migration
             $table->timestamps();
         });
         $stationType= StationType::query()->firstOrCreate(['name'=>'料箱出货口']);
-        $station= Station::query()->firstOrCreate(['code'=>'BIN-OUT01','station_type_id'=>$stationType['id']]);
+        $station料箱监视器01= StationType::query()->firstOrCreate(['name'=>'料箱监视器01']);
+        $station= Station::query()->firstOrCreate(['name'=>'U型线入货口01'
+            ,'code'=>'BIN-OUT01'
+            ,'station_type_id'=>$stationType['id']
+            ,'parent_id'=>$station料箱监视器01['id']
+        ]);
         $station['sequence']=1;
         $station['station_type_id']=$stationType['id'];
         $station->save();

+ 44 - 0
database/migrations/2020_12_24_155647_add_column_material_task_type_drop_station_mission_tables.php

@@ -0,0 +1,44 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddColumnMaterialTaskTypeDropStationMissionTables extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::dropIfExists('station_mission_batch_types');
+        Schema::dropIfExists('station_mission_batches');
+        Schema::dropIfExists('station_mission_commodities');
+        Schema::dropIfExists('station_mission_material_boxes');
+        Schema::table('station_task_material_boxes',function(Blueprint $table){
+            $table->enum('type',['取','放','移动']);
+            $table->bigInteger('station_task_batch_id')->index()->nullable();
+        });
+        Schema::table('station_task_commodities',function(Blueprint $table){
+            $table->bigInteger('station_task_batch_id')->index()->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('station_task_material_boxes',function(Blueprint $table){
+            $table->dropColumn('type');
+            $table->dropColumn('station_task_batch_id');
+        });
+        Schema::table('station_task_commodities',function(Blueprint $table){
+            $table->dropColumn('station_task_batch_id');
+        });
+    }
+}

+ 30 - 0
database/migrations/2020_12_29_182249_change_station_rule_batch_column_default_batch_type.php

@@ -0,0 +1,30 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangeStationRuleBatchColumnDefaultBatchType extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('station_rule_batches',function(Blueprint $table){
+            $table->string('batch_type')->default('无')->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 45 - 0
database/migrations/2021_01_06_114158_create_station_task_children2.php

@@ -0,0 +1,45 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateStationTaskChildren2 extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('station_task_children', function (Blueprint $table) {
+            $table->id();
+            $table->bigInteger('station_task_id')->index();
+            $table->string('station_taskable_type');
+            $table->bigInteger('station_taskable_id');
+            $table->index(['station_taskable_type','station_taskable_id'],'station_taskable_t_i');
+            $table->timestamps();
+        });
+        Schema::table('station_tasks', function (Blueprint $table) {
+            $table->dropColumn('station_taskable_type');
+            $table->dropColumn('station_taskable_id');
+            $table->dropIndex('station_taskable_type');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('station_task_children');
+        Schema::table('station_tasks', function (Blueprint $table) {
+            $table->string('station_taskable_type');
+            $table->integer('station_taskable_id');
+            $table->index(['station_taskable_id','station_taskable_id'],'station_taskable_type');
+        });
+    }
+}

+ 0 - 36
database/migrations/2021_01_08_112003_add_default_mail_event_role.php

@@ -1,36 +0,0 @@
-<?php
-
-use App\Events\SendEmailEvent;
-use App\MailEvent;
-use App\Role;
-use Illuminate\Database\Migrations\Migration;
-use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Facades\Schema;
-
-class AddDefaultMailEventRole extends Migration
-{
-    protected $role;
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        $this->role =  Role::query()->firstOrCreate(['name'=>'发送邮件测试']);
-        $emailEvent = MailEvent::query()->where('name', '发送默认邮件')->first();
-        $emailEvent->roles()->attach($this->role->id);
-        $this->role->users()->attach(\App\User::query()->where('name','yang')->first()->id);
-    }
-
-    /**
-     * Reverse the migrations.
-     *
-     * @return void
-     */
-    public function down()
-    {
-        $this->role->delete();
-    }
-}

+ 36 - 0
database/migrations/2021_01_21_100909_add_created_at_index_order_packages.php

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddCreatedAtIndexOrderPackages extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            //
+            $table->index('created_at');
+            $table->index(['status','created_at']);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            //
+            $table->dropIndex('order_packages_created_at_index');
+            $table->dropIndex('order_packages_status_created_at_index');
+        });
+    }
+}

+ 36 - 0
database/migrations/2021_01_21_132441_add_authorrities_mail.php

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddAuthorritiesMail extends Migration
+{
+    protected $authNames=[
+        "基础设置-邮件",
+    ];
+
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        foreach ($this->authNames as $name){
+            \App\Authority::create(['name'=>$name,'alias_name'=>$name,'permission'=>'允许']);
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        foreach ($this->authNames as $name){
+            \App\Authority::where(['name'=>$name,'alias_name'=>$name])->delete();
+        }
+    }
+}

+ 45 - 0
database/migrations/2021_01_21_153513_add_column_station_task_id_for_all_sub_tasks.php

@@ -0,0 +1,45 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddColumnStationTaskIdForAllSubTasks extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('station_task_batches', function (Blueprint $table) {
+            $table->integer('station_task_id')->index()->nullable();
+        });
+        Schema::table('station_task_commodities', function (Blueprint $table) {
+            $table->integer('station_task_id')->index()->nullable();
+        });
+        Schema::table('station_task_material_boxes', function (Blueprint $table) {
+            $table->integer('station_task_id')->index()->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('station_task_batches', function (Blueprint $table) {
+            $table->dropColumn('station_task_id');
+        });
+        Schema::table('station_task_commodities', function (Blueprint $table) {
+            $table->dropColumn('station_task_id');
+        });
+        Schema::table('station_task_material_boxes', function (Blueprint $table) {
+            $table->dropColumn('station_task_id');
+        });
+
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddColumnFrozenToOrders extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->enum('frozen',['是','否'])->index()->default('否');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->dropColumn('frozen');
+        });
+    }
+}

+ 36 - 0
database/migrations/2021_01_22_112931_change_order_freeze_table.php

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ChangeOrderFreezeTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_freezes', function (Blueprint $table) {
+            $table->renameColumn("location_id","district_id");
+            $table->bigInteger("town_id")->nullable()->comment("外键乡镇");
+            $table->bigInteger("street_id")->nullable()->comment("外键村街");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_freezes', function (Blueprint $table) {
+            $table->renameColumn("district_id","location_id");
+            $table->dropColumn("town_id");
+            $table->dropColumn("street_id");
+        });
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateOrderPackageCountingRecordsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('order_package_counting_records', function (Blueprint $table) {
+            $table->date("targeted_at")->index()->comment("统计日期");
+            $table->integer("un_weigh_count")->default(0)->comment("未称重数量");
+            $table->integer("total_count")->default(0)->comment("总数");
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('order_package_counting_records');
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddColumnOrderClientCodeWmsToOrderTrackings extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_trackings', function (Blueprint $table) {
+            $table->string('order_client_code_wms')->index()->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_trackings', function (Blueprint $table) {
+            $table->dropColumn('order_client_code_wms');
+        });
+    }
+}

+ 3 - 2
public/t.php

@@ -1,4 +1,5 @@
 <?php
 
-$s = '434211kjk';
-var_dump(preg_match('/434/',$s));
+$failed=!$success=true;
+
+var_dump($failed,$success);

+ 5 - 5
resources/js/queryForm/queryForm.js

@@ -474,7 +474,7 @@ const query = function getQueryForm(data) {
         let min = $("<input id='" + condition.name + "_min' class='form-control form-control-sm ml-2' style='max-width: 100px;' placeholder='00:00' data-toggle='tooltip' data-placement='top' >");
         min.attr('title', controlJsType(condition.tip[1], 'undefined') ? '' : condition.tip[1]);
         dateTime.bind('input propertychange', function () {
-            let value = this.value !== '' ? this.value + ' ' +(!!min.val() ?  min.val() :'00:00' ) : '';
+            let value = this.value !== '' ? this.value + ' ' +(!!min.val() ?  min.val() :'23:59' ) : '';
             modifyData( {name: condition.name, type: 'time', value: value, mold: 'time'});
             // modifyData({name: condition.name, type: 'dateTime', value: this.value, mold: 'dateTime'});
         });
@@ -826,10 +826,10 @@ const query = function getQueryForm(data) {
                     if (relevance.value){
                         let today = getToday();
                         let tarDate = getSubDate(getToday(),relevance.value);
-                        _data[end.name].value = today;
-                        _data[start.name].value = tarDate;
-                        redenerSearchFormOnData(end.name, tarDate, end.mold);
-                        redenerSearchFormOnData(start.name, tarDate, start.mold);
+                        _data[end.name].value = today+" 23:59";
+                        _data[start.name].value = tarDate+" 00:00";
+                        /*redenerSearchFormOnData(end.name, tarDate+" 23:59", end.mold);
+                        redenerSearchFormOnData(start.name, tarDate+" 00:00", start.mold);*/
                     }
                     return;
                 }

+ 1 - 1
resources/lang/cn/validation.php

@@ -57,7 +57,7 @@ return [
         'array' => ':attribute must have :value items or more.',
     ],
     'image' => ':attribute must be an image.',
-    'in' => 'selected :attribute is invalid.',
+    'in' => ' :attribute 不在合法值内.',
     'in_array' => ':attribute field does not exist in :other.',
     'integer' => ':attribute must be an integer.',
     'ip' => ':attribute must be a valid IP address.',

+ 19 - 0
resources/sass/text.scss

@@ -132,4 +132,23 @@
 //文本强调阴影
 .text-shadow-stress{
     text-shadow: 3px 3px 3px yellow
+}
+
+//滚动条美化
+.scrollbar::-webkit-scrollbar {
+    /*滚动条整体样式*/
+    width : 10px;  /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+}
+.scrollbar::-webkit-scrollbar-thumb {
+    /*滚动条里面小方块*/
+    border-radius: 10px;
+    box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.2);
+    background   : #535353;
+}
+.scrollbar::-webkit-scrollbar-track {
+    /*滚动条里面轨道*/
+    box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.2);
+    border-radius: 10px;
+    background   : #ededed;
 }

+ 105 - 4
resources/views/control/panel.blade.php

@@ -346,6 +346,27 @@
                     </div>
                 @endcan
             </div>
+            <div class="row my-3">
+                <div class="col-6">
+                    <div class="card">
+                        <div class="card-header">
+                            <div class="row">
+                                <el-date-picker size="small" class="col-6 date" @blur="loadWeightInfo()" type="daterange" align="right"
+                                                v-model="searchOption.weightDate" unlink-panels range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd">
+                                </el-date-picker>
+                                <label class="col-3 offset-3">
+                                    <select class="form-control rounded" v-model="searchOption.weightSelect" @change="switchWeightDate()">
+                                        <option v-for="(date,i) in dateOptions" :value="i">@{{ date.text }}</option>
+                                    </select>
+                                </label>
+                            </div>
+                        </div>
+                        <div class="card-body row">
+                            <div id="weight" class="col-12" style="min-height: 500px"></div>
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
 @endsection
@@ -409,6 +430,16 @@
                         }
                     }]
                 },
+                dateOptions:[{text:'当天',start:moment().format('yyyy-MM-DD'),end:moment().format('yyyy-MM-DD')},
+                    {text:"昨天",start:moment().subtract("1","day").format('yyyy-MM-DD'),end:moment().subtract("1","day").format('yyyy-MM-DD')},
+                    {text:"本周",start:moment().weekday(1).format('yyyy-MM-DD'),end:moment().weekday(7).format('yyyy-MM-DD')},
+                    {text:"上周",start:moment().weekday(-6).format('yyyy-MM-DD'),end:moment().weekday(0).format('yyyy-MM-DD')},
+                    {text:"本月",start:moment().startOf("month").format('yyyy-MM-DD'),end:moment().endOf("month").format('yyyy-MM-DD')},
+                    {text:"上月",start:moment().month(moment().month() - 1).startOf('month').format('yyyy-MM-DD'),end:moment().month(moment().month() - 1).endOf('month').format('yyyy-MM-DD')},
+                    {text:"本季度",start:moment(moment().quarter(moment().quarter()).startOf('quarter').valueOf()).format('yyyy-MM-DD'),end:moment(moment().quarter(moment().quarter()).endOf('quarter').valueOf()).format('yyyy-MM-DD')},
+                    {text:"上季度",start:moment(moment().quarter(moment().quarter() - 1).startOf('quarter').valueOf()).format('yyyy-MM-DD'),end:moment(moment().quarter(moment().quarter() - 1).endOf('quarter').valueOf()).format('yyyy-MM-DD')},
+                    {text:"本年",start:moment(moment().year(moment().year()).startOf('year').valueOf()).format('yyyy-MM-DD'),end:moment(moment().year(moment().year()).endOf('year').valueOf()).format('yyyy-MM-DD')},
+                    {text:"去年",start:moment(moment().year(moment().year() - 1).startOf('year').valueOf()).format('yyyy-MM-DD'),end:moment(moment().year(moment().year() - 1).endOf('year').valueOf()).format('yyyy-MM-DD')}],
                 logisticsCountingRecordsData: [moment().subtract('1', 'month').format('yyyy-MM-DD'),
                     moment(new Date()).format('yyyy-MM-DD')],
                 warehouseCountingRecordsData: [moment().subtract('1', 'month').format('yyyy-MM-DD'),
@@ -454,6 +485,11 @@
                 laborReportsCountingRecordsYearShow: false,
                 laborReportsCountingRecordsStart: moment().subtract('1', 'month').format('yyyy-MM-DD'),
                 laborReportsCountingRecordsEnd: moment(new Date()).format('yyyy-MM-DD'),
+                cardPool:{},
+                searchOption:{
+                    weightDate:[],
+                    weightSelect:"",
+                },
             },
             watch:{
                 selectOrderOwners:function(val,oldval){
@@ -474,6 +510,9 @@
                 }
             },
             mounted: function () {
+                let index = 4;
+                this.searchOption.weightSelect = index;
+                this.searchOption.weightDate = [this.dateOptions[index].start,this.dateOptions[index].end];
                 $('#list').removeClass('d-none');
                 let _this = this;
                 this.warehouses = {
@@ -489,16 +528,18 @@
                     _this.totalOrders.partPacking += item.partPacking;
                     _this.totalOrders.sowComplete += item.sowComplete;
                 });
-                this.initOrderCountingRecords();
-                this.orderCountingRecordsChart = echarts.init(document.getElementById('orderCountingRecords'));
-                this.initOrderCountingRecordsChart();
+                if (this.orderCountingRecords[0]!=null) {
+                    this.initOrderCountingRecords();
+                    this.orderCountingRecordsChart = echarts.init(document.getElementById('orderCountingRecords'));
+                    this.initOrderCountingRecordsChart();
+                }
 
                 this.logisticsCountingRecordsChart = echarts.init(document.getElementById('logisticsCountingRecords'));
                 this.initLogisticsCountingRecordsChart();
 
                 this.warehouseCountingRecordsChart = echarts.init(document.getElementById('warehouseCountingRecords'));
                 this.initWarehouseCountingRecordsChart();
-
+                @can('人事管理-临时工报表-可见全部组')
                 this.initLaborReportsCountingRecords();
                 this.laborReportsCountingRecordsChart = echarts.init(document.getElementById('laborReportsCountingRecords'));
                 this.initLaborReportsCountingRecordsChart();
@@ -506,6 +547,9 @@
                 this.laborReportsUserGroupsCountChart = echarts.init(document.getElementById('laborReportsUserGroupsCount'));
                 this.initLaborReportsUserGroupsCountChart();
 
+                this.cardPool.weight = echarts.init(document.getElementById("weight"));
+                this.loadWeightInfo();
+                @endcan
             },
             methods: {
                 switchDataPanel_forOrderCountingRecords(fromUnit, toUnit) {
@@ -843,6 +887,63 @@
                         }
                     });
                 },
+                loadWeightInfo(){
+                    window.tempTip.setDuration(3000);
+                    if (!this.searchOption.weightDate[0]){
+                        window.tempTip.show("开始时间未选择");
+                        return;
+                    }
+                    if (!this.searchOption.weightDate[1]){
+                        window.tempTip.show("结束时间未选择");
+                        return;
+                    }
+                    this.cardPool.weight.showLoading('default',{text:"加 载 中",color:'#C0C0C0'});
+                    let url = "{{url('apiLocal/control/panel/menu/weightApi')}}";
+                    let params = {start:this.searchOption.weightDate[0],end:this.searchOption.weightDate[1]};
+                    window.tempTip.postBasicRequest(url,params,res=>{
+                        this.cardPool.weight.hideLoading();
+                        this.cardPool.weight.setOption(this._setWeightData(res.title,res.data));
+                    });
+                },
+                switchWeightDate(){
+                    let obj = this.dateOptions[this.searchOption.weightSelect];
+                    this.searchOption.weightDate = [obj.start,obj.end];
+                    this.loadWeightInfo();
+                },
+                _setWeightData(title, data){
+                    return {
+                        title: {
+                            text: '已称重包裹占比',
+                            left: 'left'
+                        },
+                        tooltip: {
+                            trigger: 'item',
+                            formatter: function (params) {
+                                return params.data.date+"<br>"+"总量:<span class='text-success font-weight-bold'>"+params.data.total+"</span><br>"+"已称:<span class='text-info font-weight-bold'>"+params.data.count+"</span>";
+                            }
+                        }, xAxis: {
+                            data: title
+                        }, yAxis: {
+                            axisLabel: {
+                                show: true,
+                                interval: 'auto',
+                                formatter: '{value} %'
+                            },
+                            max:100
+                        }, label:{
+                            show:true,
+                            position: 'top',
+                            formatter: '{c}%',
+                            color:"red"
+                        }, series: [{
+                            type: "bar",
+                            data: data,
+                            itemStyle:{
+                                color:"RGB(62,157,231)",
+                            }
+                        }]
+                    };
+                },
             }
         });
     </script>

+ 2 - 1
resources/views/customer/menu.blade.php

@@ -17,7 +17,8 @@
             @can('客户管理-相关设置')
             <li class="nav-item">
                 <a class="nav-link" href="{{url('customer/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
-            </li>@endcan
+            </li>
+                @endcan
         </ul>
     </div>
 </div>

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

@@ -142,7 +142,7 @@
                         name:"",
                         feature:"",
                         items : [
-                            {strategy:"起步"},
+                            {strategy:"起步",type:"0"},
                             {strategy:"默认"},
                             {strategy:"特征"},
                         ],
@@ -625,7 +625,7 @@
                             name:"",
                             feature:"",
                             items : [
-                                {strategy:"起步"},
+                                {strategy:"起步",type:"0"},
                                 {strategy:"默认"},
                                 {strategy:"特征"},
                             ],
@@ -640,10 +640,10 @@
                         this.errors['items.'+itemIndex+'.amount'] = ["数量不得为空"];
                         sign = true;
                     }else if (!obj.amount) obj.amount = 0;
-                    if (!obj.unit_id){
+                    if (obj.strategy!=='起步' && !obj.unit_id){
                         this.errors['items.'+itemIndex+'.unit_id'] = ["必须选择单位"];
                         sign = true;
-                    }
+                    }else if (!obj.unit_id) obj.unit_id = 0;
                     if (!obj.unit_price){
                         this.errors['items.'+itemIndex+'.unit_price'] = ["单价不得为空"];
                     }

+ 35 - 23
resources/views/customer/project/part/_operation.blade.php

@@ -42,29 +42,41 @@
         </div>
         <div class="card-body">
             <div class="row mt-2">
-                <label class="col-3">起步数</label>
-                <label class="col-5 mb-0"><input id="amount" type="number" :class="errors['items.0.amount'] ? 'is-invalid' : ''"
-                       v-model="model.operation.items[0].amount" class="form-control" step="1"></label>
-            </div>
-            <div class="row mt-0" v-if="errors['items.0.amount']">
-                <div class="offset-3"><small class="text-danger font-weight-bold ml-3">起步数为必填项</small></div>
-            </div>
-            <div class="row mt-2">
-                <label class="col-3">单位</label>
-                <label class="col-5 mb-0"><select v-model="model.operation.items[0].unit_id" class="form-control" :class="errors['items.0.unit_id'] ? 'is-invalid' : ''">
-                        <option v-for="unit in pool.units" :value="unit.id">@{{ unit.name }}</option>
-                </select></label>
-            </div>
-            <div class="row mt-0" v-if="errors['items.0.unit_id']">
-                <div class="offset-3"><small class="text-danger font-weight-bold ml-3">单位为必选项</small></div>
-            </div>
-            <div class="row mt-2">
-                <label class="col-3">起步费</label>
-                <label class="col-5 mb-0"><input type="number" min="0" step="0.001" class="form-control" v-model="model.operation.items[0].unit_price"
-                           :class="errors['items.0.unit_price'] ? 'is-invalid' : ''"></label>
-            </div>
-            <div class="row mt-0" v-if="errors['items.0.unit_price']">
-                <div class="offset-3"><small class="text-danger font-weight-bold ml-3">单价为必填项</small></div>
+                <div class="col-3">
+                    <label>
+                        <select class="form-control form-control-sm mt-1" v-model="model.operation.items[0].type">
+                            <option value="0">起步数</option>
+                            <option value="1">起步费</option>
+                        </select>
+                    </label>
+                </div>
+                <div class="col-9">
+                    <div class="row" v-if="model.operation.items[0].type == 0">
+                        <label class="col-3">起步数</label>
+                        <label class="col-5 mb-0"><input id="amount" type="number" :class="errors['items.0.amount'] ? 'is-invalid' : ''"
+                                                         v-model="model.operation.items[0].amount" class="form-control" step="1"></label>
+                    </div>
+                    <div class="row mt-0" v-if="errors['items.0.amount']">
+                        <div class="offset-3"><small class="text-danger font-weight-bold ml-3">起步数为必填项</small></div>
+                    </div>
+                    <div class="row mt-2" v-if="model.operation.items[0].type == 0">
+                        <label class="col-3">单位</label>
+                        <label class="col-5 mb-0"><select v-model="model.operation.items[0].unit_id" class="form-control" :class="errors['items.0.unit_id'] ? 'is-invalid' : ''">
+                                <option v-for="unit in pool.units" :value="unit.id">@{{ unit.name }}</option>
+                            </select></label>
+                    </div>
+                    <div class="row mt-0" v-if="errors['items.0.unit_id']">
+                        <div class="offset-3"><small class="text-danger font-weight-bold ml-3">单位为必选项</small></div>
+                    </div>
+                    <div class="row mt-2">
+                        <label class="col-3">起步费</label>
+                        <label class="col-5 mb-0"><input type="number" min="0" step="0.001" class="form-control" v-model="model.operation.items[0].unit_price"
+                                                         :class="errors['items.0.unit_price'] ? 'is-invalid' : ''"></label>
+                    </div>
+                    <div class="row mt-0" v-if="errors['items.0.unit_price']">
+                        <div class="offset-3"><small class="text-danger font-weight-bold ml-3">起步费为必填项</small></div>
+                    </div>
+                </div>
             </div>
         </div>
     </div>

+ 2 - 1
resources/views/maintenance/menu.blade.php

@@ -98,10 +98,11 @@
                 <li class="nav-item">
                     <a class="nav-link text-muted" href="{{url('maintenance/laborCompany')}}" :class="{active:isActive('laborCompany',2)}">劳务所</a>
                 </li> @endcan
-            {{--TODO 权限--}}
+            @can('基础设置-邮件')
                 <li class="nav-item">
                     <a class="nav-link text-muted" href="{{url('maintenance/mail')}}" :class="{active:isActive('mail',2)}">邮件</a>
                 </li>
+                @endcan
             @can('日志')
                 <li class="nav-item">
                     <a class="nav-link text-muted" href="{{url('maintenance/log')}}" :class="{active:isActive('log',2)}">日志</a>

+ 59 - 43
resources/views/maintenance/region/index.blade.php

@@ -3,52 +3,51 @@
 
 @section('content')
     @component('maintenance.menu')@endcomponent
-    <div class="container-fluid" id="container">
+    <div class="container-fluid d-none" id="container">
         <div class="card">
             <div class="card-body mt-2">
-                <div class="row">
-                    <div class="col-5 offset-4">
-                        <div class="row m-0 font-weight-bold">
-                            <label class="offset-1 col-4">省份</label>
-                            <label class="col-4">邮编</label>
-                            <label class="col-3">状态</label>
+                <div class="ml-2">
+                    <div v-for="region in parentMapping[0]" :style="{'margin-left':(2+region.type)+'%'}">
+                        <div>
+                            <span class="fa fa-hand-o-right cursor-pointer" @click="showItem('tree-'+region.id,$event)" v-if="parentMapping[region.id]"></span>
+                            <span v-else>&nbsp;&nbsp;&nbsp;</span>
+                            &nbsp;&nbsp;<span class="fa fa-circle" :class="region.deleted_at ? 'text-danger' : 'text-success'"></span>&nbsp;
+                            @{{ region.name }}<label class="text-secondary" v-if="region.code">(@{{ region.code }})</label>
                         </div>
-                    </div>
-                </div>
-                <div class="row" v-for="region in parentMapping[0]">
-                    <div class="col-5 offset-4">
-                        <div class="row m-0">
-                            <span class="fa fa-angle-double-right col-1 cursor-pointer" @click="showItem()"></span>
-                            <label class="col-4">@{{ region.name }}</label>
-                            <label class="col-4">@{{ region.code }}</label>
-                            <label class="col-3">
-                                <span class="fa fa-circle" :class="region.deleted_at ? 'text-danger' : 'text-success'"></span>
-                                <span v-if="region.deleted_at">冻结</span><span v-else>正常</span>
-                            </label>
-                        </div>
-                    </div>
-                    <div class="col-5 offset-5 border rounded border-2">
-                        <div class="row" v-for="city in parentMapping[region.id]">
-                            <div class="col-12">
-                                <div class="row m-0">
-                                    <span class="fa fa-angle-double-right col-1 cursor-pointer"></span>
-                                    <label class="col-3">@{{ city.name }}</label>
-                                    <label class="col-4">@{{ city.code }}</label>
-                                    <label class="col-3">
-                                        <span class="fa fa-circle" :class="city.deleted_at ? 'text-danger' : 'text-success'"></span>
-                                        <span v-if="city.deleted_at">冻结</span><span v-else>正常</span>
-                                    </label>
+                        <div :id="'tree-'+region.id" class="up">
+                            <div v-for="city in parentMapping[region.id]" :style="{'margin-left':(2+city.type)+'%'}">
+                                <div>
+                                    <span class="fa fa-hand-o-right cursor-pointer" @click="showItem('tree-'+city.id,$event)" v-if="parentMapping[city.id]"></span>
+                                    <span v-else>&nbsp;&nbsp;&nbsp;</span>
+                                    &nbsp;&nbsp;<span class="fa fa-circle" :class="city.deleted_at ? 'text-danger' : 'text-success'"></span>&nbsp;
+                                    @{{ city.name }}<label class="text-secondary" v-if="city.code">(@{{ city.code }})</label>
                                 </div>
-                                <div class="row m-0">
-                                    <div class="col-10 offset-2">
-                                        <div class="row" v-for="district in parentMapping[city.id]">
-                                            <span class="fa fa-angle-double-right col-1 cursor-pointer"></span>
-                                            <label class="col-3">@{{ city.name }}</label>
-                                            <label class="col-4">@{{ city.code }}</label>
-                                            <label class="col-3">
-                                                <span class="fa fa-circle" :class="city.deleted_at ? 'text-danger' : 'text-success'"></span>
-                                                <span v-if="city.deleted_at">冻结</span><span v-else>正常</span>
-                                            </label>
+                                <div :id="'tree-'+city.id" class="up">
+                                    <div v-for="district in parentMapping[city.id]" :style="{'margin-left':(2+district.type)+'%'}">
+                                        <div>
+                                            <span class="fa fa-hand-o-right cursor-pointer" @click="showItem('tree-'+district.id,$event)" v-if="parentMapping[district.id]"></span>
+                                            <span v-else>&nbsp;&nbsp;&nbsp;</span>
+                                            &nbsp;&nbsp;<span class="fa fa-circle" :class="district.deleted_at ? 'text-danger' : 'text-success'"></span>&nbsp;
+                                            @{{ district.name }}<label class="text-secondary" v-if="district.code">(@{{ district.code }})</label>
+                                        </div>
+                                        <div :id="'tree-'+district.id" class="up">
+                                            <div v-for="town in parentMapping[district.id]" :style="{'margin-left':(2+town.type)+'%'}">
+                                                <div>
+                                                    <span class="fa fa-hand-o-right cursor-pointer" @click="showItem('tree-'+town.id,$event)" v-if="parentMapping[town.id]"></span>
+                                                    <span v-else>&nbsp;&nbsp;&nbsp;</span>
+                                                    &nbsp;&nbsp;<span class="fa fa-circle" :class="town.deleted_at ? 'text-danger' : 'text-success'"></span>&nbsp;
+                                                    @{{ town.name }}<label class="text-secondary" v-if="town.code">(@{{ town.code }})</label>
+                                                </div>
+                                                <div :id="'tree-'+town.id" class="up">
+                                                    <div v-for="street in parentMapping[town.id]" :style="{'margin-left':(2+street.type)+'%'}">
+                                                        <div>
+                                                            {{--<span class="fa fa-hand-o-right cursor-pointer" @click="showItem('tree-'+street.id,$event)"></span>&nbsp;&nbsp;--}}
+                                                            <span class="fa fa-circle" :class="street.deleted_at ? 'text-danger' : 'text-success'"></span>&nbsp;
+                                                            @{{ street.name }}<label class="text-secondary" v-if="street.code">(@{{ street.code }})</label>
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            </div>
                                         </div>
                                     </div>
                                 </div>
@@ -72,6 +71,7 @@
                     @endforeach
                 ],
                 parentMapping:{},
+                showList:{},
             },
             mounted(){
                 let parent = {};
@@ -81,7 +81,23 @@
                     else parent[p] = [region];
                 });
                 this.parentMapping = parent;
-                console.log(parent);
+                setTimeout(()=>{
+                    $(".up").slideUp();
+                    $("#container").removeClass("d-none");
+                },0);
+            },
+            methods:{
+                showItem(id,event){
+                    if (this.showList[id]){
+                        this.showList[id] = false;
+                        event.target.className = "fa fa-hand-o-right cursor-pointer";
+                        $("#"+id).slideUp();
+                    }else{
+                        this.showList[id] = true;
+                        event.target.className = "fa fa-hand-o-down cursor-pointer";
+                        $("#"+id).slideDown();
+                    }
+                },
             },
         });
     </script>

+ 48 - 8
resources/views/order/index/_freezeModal.blade.php

@@ -2,6 +2,12 @@
     <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
         <div class="modal-content">
             <div class="modal-header">
+                <label class="ml-5">
+                    <input class="form-control rounded-pill" @keydown.13="search($event)" placeholder="回车快捷检索地区">
+                </label>
+                <div class="scrollbar ml-2 border border-2 rounded pl-2 pr-5" style="overflow-y:auto;max-height:80px;overflow-x:hidden;">
+                    <p class="mb-1 cursor-pointer" v-for="obj in result" v-html="obj.text" @click="selectedSearch(obj)"></p>
+                </div>
                 <button type="button" class="close" data-dismiss="modal">&times;</button>
             </div>
             <div class="modal-body">
@@ -12,6 +18,9 @@
                             v-model="freeze.logistic_id">
                             <option v-for="logistic in data.logistics" :value="logistic.id">@{{ logistic.name }}</option>
                     </select>
+                    <label class="col-2">
+                        <input class="ml-1 form-control form-control-sm rounded-pill" @input="searchLogistic($event)" placeholder="搜索承运商">
+                    </label>
                     <span class="invalid-feedback mt-0 offset-3" role="alert" v-if="errors.logistic_id">
                         <strong>@{{ errors.logistic_id[0] }}</strong>
                     </span>
@@ -21,7 +30,7 @@
                     <select class="col-5 form-control form-control-sm"
                             :class="errors.province_id ? 'is-invalid' : ''" id="province_id" type="text"
                             v-model="freeze.province_id">
-                        <option v-for="province in data.provinces" :value="province.id">@{{ province.name }}</option>
+                        <option v-for="province in mapping['0']" :value="province.id">@{{ province.name }}</option>
                     </select>
                     <span class="invalid-feedback mt-0 offset-3" role="alert" v-if="errors.province_id">
                         <strong>@{{ errors.province_id[0] }}</strong>
@@ -32,21 +41,52 @@
                     <select class="col-5 form-control form-control-sm"
                             :class="errors.city_id ? 'is-invalid' : ''" id="city_id" type="text"
                             v-model="freeze.city_id">
-                        <option v-for="city in data.cities" :value="city.id" v-if="city.province_id == freeze.province_id">@{{ city.name }}</option>
+                        <option v-for="city in mapping[freeze.province_id]" :value="city.id">@{{ city.name }}</option>
                     </select>
                     <span class="invalid-feedback mt-0 offset-3" role="alert" v-if="errors.city_id">
                         <strong>@{{ errors.city_id[0] }}</strong>
                     </span>
                 </div>
                 <div class="row mt-2">
-                    <label class="col-2 offset-1" for="location_id">区</label>
+                    <label class="col-2 offset-1" for="district_id">区/县</label>
+                    <select class="col-5 form-control form-control-sm"
+                            :class="errors.district_id ? 'is-invalid' : ''" id="district_id" type="text"
+                            v-model="freeze.district_id">
+                        <option v-for="district in mapping[freeze.city_id]" :value="district.id">@{{ district.name }}</option>
+                    </select>
+                    <label class="col-4">
+                        <input class="ml-1 form-control form-control-sm rounded-pill" @keydown.13="addRegion($event,3)" placeholder="此处输入回车添加新区/县">
+                    </label>
+                    <span class="invalid-feedback mt-0 offset-3" role="alert" v-if="errors.district_id">
+                        <strong>@{{ errors.district_id[0] }}</strong>
+                    </span>
+                </div>
+                <div class="row mt-2">
+                    <label class="col-2 offset-1" for="town_id">乡/镇</label>
+                    <select class="col-5 form-control form-control-sm"
+                            :class="errors.town_id ? 'is-invalid' : ''" id="town_id" type="text"
+                            v-model="freeze.town_id">
+                        <option v-for="town in mapping[freeze.district_id]" :value="town.id">@{{ town.name }}</option>
+                    </select>
+                    <label class="col-4">
+                        <input class="ml-1 form-control form-control-sm rounded-pill" @keydown.13="addRegion($event,4)" placeholder="此处输入回车添加新乡/镇">
+                    </label>
+                    <span class="invalid-feedback mt-0 offset-3" role="alert" v-if="errors.town_id">
+                        <strong>@{{ errors.town_id[0] }}</strong>
+                    </span>
+                </div>
+                <div class="row mt-2">
+                    <label class="col-2 offset-1" for="street_id">村/街</label>
                     <select class="col-5 form-control form-control-sm"
-                            :class="errors.location_id ? 'is-invalid' : ''" id="location_id" type="text"
-                            v-model="freeze.location_id">
-                        <option v-for="district in data.districts" :value="district.id" v-if="city.parent_id == freeze.city_id">@{{ district.name }}</option>
+                            :class="errors.street_id ? 'is-invalid' : ''" id="street_id" type="text"
+                            v-model="freeze.street_id">
+                        <option v-for="street in mapping[freeze.town_id]" :value="street.id">@{{ street.name }}</option>
                     </select>
-                    <span class="invalid-feedback mt-0 offset-3" role="alert" v-if="errors.location_id">
-                        <strong>@{{ errors.location_id[0] }}</strong>
+                    <label class="col-4">
+                        <input class="ml-1 form-control form-control-sm rounded-pill" @keydown.13="addRegion($event,5)" placeholder="此处输入回车添加新村/街">
+                    </label>
+                    <span class="invalid-feedback mt-0 offset-3" role="alert" v-if="errors.street_id">
+                        <strong>@{{ errors.street_id[0] }}</strong>
                     </span>
                 </div>
             </div>

+ 133 - 18
resources/views/order/index/freeze.blade.php

@@ -3,7 +3,7 @@
 
 @section('content')
     @component('order.index.menu')@endcomponent
-    <div class="card" id="container">
+    <div class="card d-none" id="container">
         <div class="card-body">
             <div class="container-fluid">
 
@@ -18,7 +18,10 @@
                         <th>承运商</th>
                         <th>省</th>
                         <th>市</th>
-                        <th>区</th>
+                        <th>区/县</th>
+                        <th>乡/镇</th>
+                        <th>村/街</th>
+                        <th>创建时间</th>
                         <th></th>
                     </tr>
                     <tr v-for="(freeze,i) in freezes">
@@ -26,7 +29,10 @@
                         <td>@{{ freeze.logistic ? freeze.logistic.name : '' }}</td>
                         <td>@{{ freeze.province ? freeze.province.name : '' }}</td>
                         <td>@{{ freeze.city ? freeze.city.name : '' }}</td>
-                        <td>@{{ freeze.location ? freeze.location.name : '' }}</td>
+                        <td>@{{ freeze.district ? freeze.district.name : '' }}</td>
+                        <td>@{{ freeze.town ? freeze.town.name : '' }}</td>
+                        <td>@{{ freeze.street ? freeze.street.name : '' }}</td>
+                        <td>@{{ freeze.created_at }}</td>
                         <td>
                             <button class="btn btn-sm btn-outline-danger" @click="deleteFreeze(freeze,i)">删除</button>
                             <button class="btn btn-sm btn-outline-info" @click="openModal(freeze,i)">编辑</button>
@@ -52,6 +58,13 @@
                 data:{},
                 freeze:{},
                 errors : {},
+                mapping:{},
+                mappingPool:{},
+                result : [],
+                stop:false,
+            },
+            mounted(){
+                $("#container").removeClass("d-none");
             },
             methods:{
                 openModal(model = null,index = null){
@@ -70,22 +83,20 @@
                             this.$set(this.data,'logistics',res);
                         });
                     }
-                    if (!this.data.provinces){
-                        let url = "{{url('maintenance/province/get')}}";
-                        window.tempTip.postBasicRequest(url,{},res=>{
-                            this.$set(this.data,'provinces',res);
-                        });
-                    }
-                    if (!this.data.cities){
-                        let url = "{{url('maintenance/city/get')}}";
-                        window.tempTip.postBasicRequest(url,{},res=>{
-                            this.$set(this.data,'cities',res);
-                        });
-                    }
-                    if (!this.data.districts){
+                    if (!this.data.regions){
                         let url = "{{url('maintenance/region/get')}}";
-                        window.tempTip.postBasicRequest(url,{type:3},res=>{
-                            this.$set(this.data,'districts',res);
+                        window.tempTip.postBasicRequest(url,{},res=>{
+                            this.$set(this.data,'regions',res);
+                            let mapping = {};
+                            let mappingPool = {};
+                            res.forEach((region,i)=>{
+                                if (!region["parent_id"])region["parent_id"] = 0;
+                                if (mapping[region["parent_id"]]) mapping[region["parent_id"]].push(region);
+                                else mapping[region["parent_id"]] = [region];
+                                mappingPool[region.id] = i;
+                            });
+                            this.mapping = mapping;
+                            this.mappingPool = mappingPool;
                         });
                     }
                 },
@@ -116,6 +127,110 @@
                         })
                     });
                 },
+                addRegion(e,type){
+                   let val = e.target.value;
+                   if (!val)return;
+                    window.tempTip.setDuration(3000);
+                    window.tempTip.setIndex(1099);
+                    let prent = "";
+                    let msg = "";
+                    let map = {2:"城市",3:"区/县",4:"乡/镇",5:"村/街"};
+                    switch (type) {
+                        case 3:
+                            prent = this.freeze.city_id;
+                            msg = map[2];
+                            break;
+                        case 4:
+                            prent = this.freeze.district_id;
+                            msg = map[3];
+                            break;
+                        case 5:
+                            prent = this.freeze.town_id;
+                            msg = map[4];
+                            break;
+                    }
+                   if (!prent){
+                       window.tempTip.show("尚未选择所属"+msg);
+                       return;
+                   }
+                   let params = {
+                       parent_id:prent,
+                       name:val,
+                       type:type,
+                   };
+                   window.tempTip.postBasicRequest("{{url('maintenance/region/store')}}",params,res=>{
+                       let arr = [];
+                       if (this.mapping[prent])arr=this.mapping[prent];
+                       arr.push(res);
+                       this.$set(this.mapping,prent,arr);
+                       switch (type) {
+                           case 3:
+                               this.freeze.district_id = res.id;
+                               break;
+                           case 4:
+                               this.freeze.town_id = res.id;
+                               break;
+                           case 5:
+                               this.freeze.street_id = res.id;
+                               break;
+                       }
+                       return "新增"+map[type]+"成功";
+                   })
+                },
+                search(e){
+                    this.stop = false;
+                    this.result = [];
+                    let val = e.target.value;
+                    if (!val)return;
+                    this.data.regions.some(region=>{
+                        if (this.stop)return true;
+                        if (region.name.indexOf(val) !== -1)this.result.push(this._traceParent(region));
+                    });
+                },
+                _traceParent(region){
+                    let text = "<b class='text-warning font-weight-bold'>"+region.name+"</b>";
+                    let sign = false;
+                    let obj = {};
+                    let isGo = true;
+                    while (isGo){
+                        if (sign) text = region.name+"&nbsp;<span class='text-dark'>-></span>&nbsp;"+text;
+                        else sign = true;
+                        switch (region.type) {
+                            case 1:
+                                obj.province_id = region.id;
+                                break;
+                            case 2:
+                                obj.city_id = region.id;
+                                break;
+                            case 3:
+                                obj.district_id = region.id;
+                                break;
+                            case 4:
+                                obj.town_id = region.id;
+                                break;
+                            case 5:
+                                obj.street_id = region.id;
+                                break;
+                        }
+                        if (!region.parent_id)isGo = false;
+                        region = this.data.regions[this.mappingPool[region.parent_id]];
+                    }
+                    obj.text = text;
+                    return obj;
+                },
+                selectedSearch(obj){
+                    this.freeze = obj;
+                    this.stop = true;
+                },
+                searchLogistic(e){
+                    let val = e.target.value;
+                    this.data.logistics.some(logistic=>{
+                        if (logistic.name.indexOf(val)!==-1){
+                            this.$set(this.freeze,"logistic_id",logistic.id);
+                            return true;
+                        }
+                    });
+                },
             },
         });
     </script>

+ 15 - 7
resources/views/order/tracking/index.blade.php

@@ -55,6 +55,7 @@
                         <th style="min-width: 50px">序号</th>
                         <th class="td-warm" style="min-width: 75px">公司</th>
                         <th class="td-warm" style="min-width: 120px">订单号</th>
+                        <th class="td-warm" style="min-width: 120px">客户订单号</th>
                         <th class="td-warm" style="min-width: 120px">WEB+订单号</th>
                         <th class="td-warm" style="min-width: 120px"> 提货日期</th>
                         <th class="td-warm" style="min-width: 120px">销售</th>
@@ -87,14 +88,19 @@
                             <span v-if="trackOrder.web_order_number">
                                 <input class="form-control form-control-sm" :value="trackOrder.order_client_code === trackOrder.web_order_number ? '' : trackOrder.order_client_code " @change="warehouseUpdate($event,'order_client_code',trackOrder)" >
                             </span>
-                            <span v-else>
-                            @can('订单管理-跟踪-仓库编辑')
-                                <input class="form-control form-control-sm" :value="trackOrder.order_client_code" @change="warehouseUpdate($event,'order_client_code',trackOrder)" >
-                            @else
-                                <span> @{{ trackOrder.order_client_code }}</span>
-                            @endcan
-                            </span>
+                            <span v-else>@{{ trackOrder.order_client_code }}</span>
+{{--                            <span v-else>--}}
+{{--                            @can('订单管理-跟踪-仓库编辑')--}}
+{{--                                <input class="form-control form-control-sm" :value="trackOrder.order_client_code" @change="warehouseUpdate($event,'order_client_code',trackOrder)" >--}}
+{{--                            @else--}}
+{{--                                <span> @{{ trackOrder.order_client_code }}</span>--}}
+{{--                            @endcan--}}
+{{--                            </span>--}}
                         </td>
+                        <td class="td-warm">
+                            @{{ trackOrder.order_client_code_wms }}
+                        </td>
+
                         <td class="td-warm">
                             @can('订单管理-跟踪-仓库编辑')
                                 <input class="form-control form-control-sm" :value="trackOrder.web_order_number" @change="warehouseUpdate($event,'web_order_number',trackOrder)" >
@@ -110,6 +116,8 @@
                             @endcan
                         </td>
                         <td class="td-warm">
+                        </td>
+{{--                        <td class="td-warm">--}}
 {{--                            @can('订单管理-跟踪-仓库编辑')--}}
 {{--                                <input class="form-control form-control-sm" :value="trackOrder.sale" @change="warehouseUpdate($event,'sale',trackOrder)" >--}}
 {{--                            @else--}}

+ 1 - 0
resources/views/package/logistic/index.blade.php

@@ -132,6 +132,7 @@
                             placeholder: '是否称重',
                             data: [{name: false, value: '无'}, {name: true, value: '已称重'}]
                         },
+                        {name: 'default_date', type: 'checkbox', tip: '默认15天', data: [{name: 'ture', value: '默认15天'}]},
 
                     ], [
                         {

+ 0 - 1
resources/views/package/menu.blade.php

@@ -6,7 +6,6 @@
                 <li class="nav-item">
                     <a class="nav-link" href="{{url('package/weigh/index')}}" :class="{active:isActive('weigh',2)}">称重管理</a>
                 </li>@endcan
-                {{--TODO 权限修改--}}
             @can('称重管理-快递')
                 <li class="nav-item">
                     <a class="nav-link" href="{{url('package/logistic')}}" :class="{active:isActive('logistic',2)}">快递</a>

+ 3 - 2
resources/views/personnel/menu.blade.php

@@ -10,10 +10,11 @@
                 <li class="nav-item">
                     <a class="nav-link" href="{{url('personnel/checking-in/createReplenishClock')}}" :class="{active:isActive('checking-in',2)}">打卡相关</a>
                 </li> @endcan
-            @can('人事管理-相关设置')
+{{--            @can('人事管理-相关设置')--}}
             <li class="nav-item">
                 <a class="nav-link text-dark" href="{{url('personnel/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
-            </li>@endcan
+            </li>
+{{--                @endcan--}}
         </ul>
     </div>
 </div>

+ 26 - 10
resources/views/waybill/index.blade.php

@@ -123,7 +123,8 @@
                     <td class="td-warm">@{{waybill.other_charge_remark}}</td>
                     <td class="td-warm">
                         <div align="center" @mouseleave="removeCommonImg('common_img_'+waybill.id)" @mouseenter="commonImg('img_'+waybill.id,waybill.url,waybill.suffix)">
-                            <img v-if="waybill.url" :id="'img_'+waybill.id"  :data-src="waybill.url+'-thumbnail.'+waybill.suffix" src="{{url('icon/img404-thumbnail.jpg')}}">
+                            <img v-if="waybill.url" :id="'img_'+waybill.id"  :src="waybill.url+'-thumbnail.'+waybill.suffix"
+                                    {{--:data-src="waybill.url+'-thumbnail.'+waybill.suffix" src="{{url('icon/img404-thumbnail.jpg')}}"--}}>
                             @can('运输管理-图片上传')<div v-if="!waybill.url">
                                 <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(waybill.waybill_number)" value="上传照片 "/>
                                 <input type="file" @change="submitFile($event,waybill.waybill_number)" :id="waybill.waybill_number"
@@ -134,6 +135,9 @@
                     <td class="td-cool">@{{waybill.recipient}}</td>
                     <td class="td-cool">@{{waybill.recipient_mobile}}</td>
                     <td class="td-cool text-muted">@{{waybill.origination}}</td>
+                    <td class="td-cool text-muted">@{{waybill.province}}</td>
+                    <td class="td-cool text-muted">@{{waybill.city}}</td>
+                    <td class="td-cool text-muted">@{{waybill.district}}</td>
                     <td class="td-cool text-muted">@{{waybill.destination}}</td>
                     <td class="td-cool">@{{waybill.carrier}}</td>
                     <td class="td-cool">
@@ -290,12 +294,12 @@
                         source_bill:'{{$waybill->source_bill}}',
                         wms_bill_number:'{{$waybill->wms_bill_number}}',
                         origination:'{{$waybill->origination}}',
-                        destination:'{{$waybill->destination_city_id}}'?
+                        destination:'{{--{{$waybill->destination_city_id}}'?
                             (('{{$waybill->destination}}'.indexOf('{{$waybill->destinationCity ? $waybill->destinationCity->name : ''}}')===-1 &&
                                 '{{$waybill->destination}}'.indexOf('{{$waybill->destinationCity ? ($waybill->destinationCity->province ? $waybill->destinationCity->province->name : '') : ''}}')===-1)?
                                 '{{($waybill->destinationCity ? ($waybill->destinationCity->province ? $waybill->destinationCity->province->name : '') : '').($waybill->destinationCity ? $waybill->destinationCity->name : '').($waybill->destination)}}'
                                 :'{{$waybill->destination}}')
-                            :'{{$waybill->destination}}',
+                            :'{{$waybill->destination}}--}}{{$waybill->destination}}',
                         recipient:'{{$waybill->recipient}}',
                         recipient_mobile:'{{$waybill->recipient_mobile}}',
                         charge:'{{$waybill->charge}}',
@@ -326,7 +330,9 @@
                         waybillAuditLogs:{!! $waybill->waybillAuditLogs !!},
                         btn_refresh_weight:'zoomIn',
                         remark:'{{$waybill->remark ?? ''}}',
-                        test:{!! $waybill !!}
+                        province:'{{$waybill->destinationCity->province->name ?? ''}}',
+                        city:'{{$waybill->destinationCity->name ?? ''}}',
+                        district:'{{$waybill->district->name ?? ''}}',
                     },
                     @endforeach
                 ],
@@ -360,6 +366,7 @@
                 count : Number('{{$waybills->count()}}'),
                 images:[],
                 batchUploadError:[],
+                size:0,
             },
             watch:{
                 checkData:{
@@ -381,11 +388,11 @@
                 $('#list').removeClass('d-none');
                 let waybill =  $('.table-header-layer-1')[1];
                 $('.top').css('min-width', waybill.scrollWidth);
-                this.imgs=Array.from(document.getElementById('list').querySelectorAll('img'));
+                /*this.imgs=Array.from(document.getElementById('list').querySelectorAll('img'));
                 this.lazy();
                 if (this.imgs&&this.imgs.length>0){
                     window.addEventListener('scroll',this.lazy)
-                }
+                }*/
                 let data=[
                     [
                         {name:'owner_id',type:'select_multiple_select',tip:['输入关键词快速定位下拉列表,回车确定','选择要显示的客户'],
@@ -436,6 +443,9 @@
                     {name:'recipient',value: '收件人', class:"td-cool"},
                     {name:'recipient_mobile',value: '收件人电话', class:"td-cool"},
                     {name:'origination',value: '始发地', class:"td-cool"},
+                    {name:'province',value: '省', class:"td-cool"},
+                    {name:'city',value: '市', class:"td-cool"},
+                    {name:'district',value: '区', class:"td-cool"},
                     {name:'destination',value: '目的地', class:"td-cool"},
                     {name:'carrier',value: '承运商', class:"td-cool"},
                     {name:'carrier_bill',value: '单号/车型', neglect: true, class:"td-cool"},
@@ -475,12 +485,12 @@
                 btnRefreshWeightZoomOut(waybill){
                     waybill.btn_refresh_weight='zoomOut'
                 },
-                lazy(){
+                /*lazy(){
                     //高度
                     let h=(window.innerWidth)+(document.documentElement.scrollTop || document.body.scrollTop);
                     this.imgs.forEach((img,i)=>{
                         let src = img.getAttribute('data-src');
-                        if ((h>this.getElementToPageTop(img)) && src){
+                        if ((h>this.getElementToPageTop(img)-500) && src){
                             let t = new Image();
                             t.src = src;
                             if (t.complete) {
@@ -500,7 +510,7 @@
                         return this.getElementToPageTop(el.parentElement) + el.offsetTop
                     }
                     return el.offsetTop
-                },
+                },*/
                 waybillAudit(id,waybill_number){
                     if(!confirm('确定要通过“'+waybill_number+'”的审核吗?')){return};
                     let _this=this;
@@ -995,6 +1005,7 @@
                     for(let i=0;i<images.length;i++){
                         images[i]['src'] = window.URL.createObjectURL(images[i]);
                         this.images.push(images[i]);
+                        this.size += images[i].size;
                     }
                 },
                 //删除图片
@@ -1003,11 +1014,15 @@
                 },
                 //上传图片
                 batchUploadImages(){
+                    window.tempTip.setDuration(3000);
                     if (this.images.length<1){
-                        window.tempTip.setDuration(3000);
                         window.tempTip.show("未选择图片");
                         return;
                     }
+                    if (this.size > 10485760){
+                        window.tempTip.show("上传图片超出10MB,请分开上传");
+                        return;
+                    }
                     let formData = new FormData();
                     this.images.forEach(image=>{
                         formData.append("images[]",image);
@@ -1034,6 +1049,7 @@
                                         return true;
                                     }
                                 });
+                                this.size = 0;
                             });
                             this.$forceUpdate();
                             window.tempTip.cancelWaitingTip();

+ 1 - 0
routes/apiLocal.php

@@ -107,4 +107,5 @@ Route::group(['prefix'=>'control'],function () {
     Route::post('panel/menu/warehouseCountingRecordsApi','ControlPanelController@warehouseCountingRecordsApi');
     Route::post('panel/menu/laborReportsCountingRecordApi','ControlPanelController@laborReportsCountingRecordApi');
     Route::post('panel/menu/laborReportsUserGroupsCountApi','ControlPanelController@laborReportsUserGroupsCountApi');
+    Route::post('panel/menu/weightApi','ControlPanelController@weightApi');
 });

+ 1 - 0
routes/web.php

@@ -195,6 +195,7 @@ Route::group(['prefix'=>'maintenance'],function(){
     });
     Route::group(['prefix'=>"region"],function (){
         Route::post("get",'RegionController@get');
+        Route::post("store",'RegionController@store');
     });
 
     Route::get('syncRedisLogs','LogController@syncRedisLogs');

Some files were not shown because too many files changed in this diff