eric2h 3 gadi atpakaļ
revīzija
ccb838d93b
100 mainītis faili ar 5090 papildinājumiem un 0 dzēšanām
  1. 15 0
      .editorconfig
  2. 5 0
      .gitattributes
  3. 56 0
      .gitlab-ci.yml
  4. 0 0
      .htaccess
  5. 13 0
      .styleci.yml
  6. 11 0
      apidoc.json
  7. 28 0
      app/AuditLog.php
  8. 60 0
      app/Authority.php
  9. 67 0
      app/Batch.php
  10. 19 0
      app/CarType.php
  11. 18 0
      app/Carrier.php
  12. 31 0
      app/City.php
  13. 54 0
      app/Commodity.php
  14. 23 0
      app/CommodityBarcode.php
  15. 24 0
      app/CommodityMaterialBoxModel.php
  16. 26 0
      app/Components/ApiProcurementResponse.php
  17. 16 0
      app/Components/ApiResponse.php
  18. 45 0
      app/Components/AsyncResponse.php
  19. 22 0
      app/Components/Database.php
  20. 13 0
      app/Components/ErrorPush.php
  21. 27 0
      app/Configuration.php
  22. 175 0
      app/Console/Commands/AccordingToOwnersManualBack.php
  23. 55 0
      app/Console/Commands/BeforeCreateOwnerReport.php
  24. 49 0
      app/Console/Commands/CheckCacheRackStorage.php
  25. 26 0
      app/Console/Commands/ClearCancelledOrderTask.php
  26. 51 0
      app/Console/Commands/CreateOwnerAreaReport.php
  27. 104 0
      app/Console/Commands/CreateOwnerBillReport.php
  28. 128 0
      app/Console/Commands/CreateOwnerReport.php
  29. 88 0
      app/Console/Commands/CreateProcurementTotalBill.php
  30. 61 0
      app/Console/Commands/CreateWeightStatistic.php
  31. 41 0
      app/Console/Commands/EndReceivingTask.php
  32. 76 0
      app/Console/Commands/FluxOrderFix.php
  33. 190 0
      app/Console/Commands/InventoryDailyLoggingOwner.php
  34. 52 0
      app/Console/Commands/LogExpireDelete.php
  35. 47 0
      app/Console/Commands/LoginListenerCommand.php
  36. 49 0
      app/Console/Commands/MakeModelCommand.php
  37. 124 0
      app/Console/Commands/MakeServiceCommand.php
  38. 118 0
      app/Console/Commands/MakeTestCommand.php
  39. 60 0
      app/Console/Commands/OrderCountingRecordTask.php
  40. 58 0
      app/Console/Commands/ReceiveRecord.php
  41. 311 0
      app/Console/Commands/SyncBatchTask.php
  42. 53 0
      app/Console/Commands/SyncCarrier.php
  43. 44 0
      app/Console/Commands/SyncLogCacheTask.php
  44. 56 0
      app/Console/Commands/SyncOrderPackageLogisticRouteTask.php
  45. 45 0
      app/Console/Commands/SyncUserVisitMenuLogsCacheTask.php
  46. 144 0
      app/Console/Commands/SyncWMSOrderTask.php
  47. 90 0
      app/Console/Commands/SyncWmsCommoditiesInformation.php
  48. 47 0
      app/Console/Commands/TestTemp.php
  49. 45 0
      app/Console/Commands/UpdateOrderPackageExceptionTypeCountingRecordTask.php
  50. 71 0
      app/Console/Commands/WASSyncWMSOrderInformation.php
  51. 91 0
      app/Console/Commands/WasSyncWmsAsnInformation.php
  52. 45 0
      app/Console/Commands/WorkOrderTimingTask.php
  53. 14 0
      app/Console/Commands/stubs/model.stub
  54. 15 0
      app/Console/Commands/stubs/test.controller.stub
  55. 37 0
      app/Console/Commands/stubs/test.service.stub
  56. 119 0
      app/Console/Kernel.php
  57. 20 0
      app/CustomField.php
  58. 41 0
      app/Customer.php
  59. 34 0
      app/CustomerLog.php
  60. 18 0
      app/CustomerLogStatus.php
  61. 19 0
      app/CustomerTag.php
  62. 105 0
      app/DeliveryAppointment.php
  63. 39 0
      app/DeliveryAppointmentCar.php
  64. 30 0
      app/DeliveryAppointmentDetail.php
  65. 16 0
      app/DeliveryType.php
  66. 81 0
      app/Demand.php
  67. 27 0
      app/DemandProcess.php
  68. 27 0
      app/DepartmentObligationOwner.php
  69. 18 0
      app/Depository.php
  70. 94 0
      app/DischargeTask.php
  71. 17 0
      app/ErrorTemp.php
  72. 35 0
      app/Events/AddOrUpdateOrderIssues.php
  73. 37 0
      app/Events/BroadcastToStation.php
  74. 36 0
      app/Events/ClockinEvent.php
  75. 36 0
      app/Events/ClockoutEvent.php
  76. 30 0
      app/Events/CustomerStored.php
  77. 67 0
      app/Events/DeliveryAppointmentEvent.php
  78. 38 0
      app/Events/ExportEvent.php
  79. 47 0
      app/Events/GitPushedEvent.php
  80. 37 0
      app/Events/GuardAuditEvent.php
  81. 40 0
      app/Events/ImportEvent.php
  82. 31 0
      app/Events/InformWMSReceivedEvent.php
  83. 29 0
      app/Events/ModelChangedEvent.php
  84. 46 0
      app/Events/OrderIssueProcessLogCreateEvent.php
  85. 24 0
      app/Events/ResetProcessStatisticStartDateEvent.php
  86. 34 0
      app/Events/SendEmailEvent.php
  87. 61 0
      app/Events/SettlementBillCreateEvent.php
  88. 39 0
      app/Events/TeamAuditEvent.php
  89. 41 0
      app/Events/UpdateOrderPackageExceptionListenerEvent.php
  90. 36 0
      app/Events/WaybillPriceModelEvent.php
  91. 36 0
      app/Events/WeighedEvent.php
  92. 25 0
      app/Events/WmsReceiveNewEvent.php
  93. 16 0
      app/Exceptions/ErrorException.php
  94. 45 0
      app/Exceptions/Exception.php
  95. 16 0
      app/Exceptions/FatalException.php
  96. 133 0
      app/Exceptions/Handler.php
  97. 16 0
      app/Exceptions/PanicException.php
  98. 16 0
      app/Exceptions/WarningException.php
  99. 81 0
      app/Exports/Export.php
  100. 24 0
      app/Exports/InventoryBlindReceiveExcelExport.php

+ 15 - 0
.editorconfig

@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.yml]
+indent_size = 2

+ 5 - 0
.gitattributes

@@ -0,0 +1,5 @@
+* text=auto
+*.css linguist-vendored
+*.scss linguist-vendored
+*.js linguist-vendored
+CHANGELOG.md export-ignore

+ 56 - 0
.gitlab-ci.yml

@@ -0,0 +1,56 @@
+stages:
+  - build
+  - test
+  - test_failed
+  - deploy
+
+cache:
+  paths:
+    - vendor/
+    - node_modules/
+
+before_script:
+#配置环境
+  - sudo cp ci/.envCi .env
+  - sudo bash ci/installEnv.sh
+
+build:
+  stage: build
+  tags:
+    - testwas
+  script:
+    - echo "build ....."
+
+test:
+  stage: test
+  tags:
+    - testwas
+  script:
+    - echo "run test....."
+    - path=`pwd`
+    - sudo bash ci/judgePush.sh $path
+    - php vendor/bin/phpunit --testsuite=Services
+    - sudo bash ci/sendEmail.sh
+
+test_failed:
+  stage: test_failed
+  tags:
+    - testwas
+  script:
+    - echo "run test_failed"
+    - email=`sudo git log --pretty=format:"%ce" -1`
+    - sudo bash ci/sendEmail.sh $email
+  when: on_failure
+
+deploy:
+  stage: deploy
+  tags:
+    - testwas
+  script:
+    - echo "deploy ...."
+#    - cd /var/www/bswas_test && sudo git config --global credential.helper store
+#    - sudo git pull
+    - sudo bash ci/scpUpdate.sh
+    - sudo bash ci/executeCommand.sh
+  only:
+    - master

+ 0 - 0
.htaccess


+ 13 - 0
.styleci.yml

@@ -0,0 +1,13 @@
+php:
+  preset: laravel
+  disabled:
+    - unused_use
+  finder:
+    not-name:
+      - index.php
+      - server.php
+js:
+  finder:
+    not-name:
+      - webpack.mix.js
+css: true

+ 11 - 0
apidoc.json

@@ -0,0 +1,11 @@
+{
+    "name": "bswas",
+    "description": "WMS API interface doc",
+    "title": "",
+    "url" : "https://was.baoshi56.com/api/v1",
+    "sampleUrl": "https://was.baoshi56.com/api/v1",
+    "template": {
+        "withCompare": true,
+        "withGenerator": true
+    }
+}

+ 28 - 0
app/AuditLog.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use App\Traits\ModelTimeFormat;
+
+use App\Traits\ModelLogChanging;
+
+class AuditLog extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    use SoftDeletes;
+    protected $table='audit_logs';
+    protected $fillable=[
+        'waybill_id','audit_stage','user_id'
+    ];
+
+    public function waybill(){
+        return $this->belongsTo('App\Waybill','waybill_id','id');
+    }
+    public function user(){
+        return $this->belongsTo('App\User','user_id','id');
+    }
+}

+ 60 - 0
app/Authority.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelTimeFormat;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Support\Facades\DB;
+
+class Authority extends Model
+{
+    use ModelLogChanging;
+    use SoftDeletes;
+    use ModelTimeFormat;
+    protected $fillable = ['name','parent_id','alias_name','permission',"route","method"];
+
+    const METHOD = [
+        0 => "GET",
+        1 => "POST",
+        2 => "PUT",
+        3 => "DELETE",
+        4 => "ANDROID"
+    ];
+
+    function roles(){
+        return $this->belongsToMany('App\Role','authority_role','id_authority','id_role');
+    }
+    function getNameFilteredAttribute(){
+        preg_match('#(.*)(_[0-9]*?$)#',$this['name'],$arr);
+        if($arr){
+            $id=str_replace('_','',$arr[2]);
+            $owner = Owner::find($id);
+            if($owner){return "{$arr[1]}({$owner['name']})";}
+        }
+        return $this['name'];
+    }
+    function getOwnerIdAttribute(){
+        preg_match('#_([0-9]*?)$#',$this['name'],$arr);
+        if(count($arr)>1&&$arr[1]){
+            return $arr[1];
+        }
+        return '';
+    }
+
+    public  static  function  filterRecycle(Collection $authorities)
+    {
+        $owners = Owner::query()->whereNotNull("deleted_at")->get();
+
+        $owner_keys = $owners->map(function($owner){
+            return '_'.$owner['id'];
+        })->toArray();
+
+        return $authorities->filter(function ($authority)use($owner_keys){
+            return !in_array($authority->name,$owner_keys);
+        });
+    }
+}

+ 67 - 0
app/Batch.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+
+class Batch extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable = [
+        'id','code','type', 'wms_type', 'status', 'wms_status', 'wms_created_at',"remark","owner_id","split_size"
+    ];
+
+    const WMS_STATUS = [
+        '00' => '创建',
+        '40' => '部分收货',
+        '90' => '取消',
+        '99' => '完成',
+        '62' => '部分装箱'
+    ];
+
+    public function orders(){
+        return $this->hasMany('App\Order','batch_id','id');
+    }
+    public function setProcessed(){
+        $this['status'] = '已处理';
+        $this->orders()->each(function (Order $order){
+            $order->setProcessed();
+        });
+        $this->update();
+    }
+    public function assignBins(){
+        $this->orders()->each(function (Order $order,$i){
+            $bin=new OrderBin(['order_id'=>$order['id'],'number'=>($i+1)]);
+            $bin->save();
+        });
+        return $this->orders()->count();
+    }
+    public function delete()
+    {
+        $this->orders()->each(function(Order $order){
+            $order->delete();
+        });
+        return parent::delete();
+    }
+    public function owner()
+    {
+        return $this->hasOne(Owner::class,"id","owner_id");
+    }
+    public function stationTaskBatch(): HasOne
+    {
+        return $this->hasOne(StationTaskBatch::class);
+    }
+    public function stationTask()
+    {
+
+        return $this->stationTaskBatch?
+            $this->stationTaskBatch->belongsTo(StationTask::class):
+            null;
+    }
+
+
+}

+ 19 - 0
app/CarType.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelTimeFormat;
+
+use App\Traits\ModelLogChanging;
+
+class CarType extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+
+    protected $fillable=[
+        'name','model','length','load','remark'
+    ];
+}

+ 18 - 0
app/Carrier.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelTimeFormat;
+
+use App\Traits\ModelLogChanging;
+
+class Carrier extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    protected $fillable=[
+        'name','mobile','delivery_fee','remark'
+    ];
+}

+ 31 - 0
app/City.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelTimeFormat;
+
+class City extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    use ModelLogChanging;
+    protected $fillable=[
+        'province_id','name','type'
+    ];
+
+    protected $appends=[
+        'province_name'
+    ];
+
+    public  function province(){
+        return $this->belongsTo('App\Province','province_id','id');
+    }
+
+    public function getProvinceNameAttribute(){
+        return $this['province']? $this['province']['name']:null;
+    }
+
+}

+ 54 - 0
app/Commodity.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelTimeFormat;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+
+class Commodity extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    protected $fillable=['name','sku','owner_id','created_at','length',
+        'width','height','volumn',"type","pack_spec",'updated_at',"remark"];
+
+    public function model():HasOne
+    {
+        return $this->hasOne(MaterialBoxModel::class,"commodity_id");
+    }
+    public function barcodes()
+    {
+        return $this->hasMany('\App\CommodityBarcode');
+    }
+    public function owner(){
+        return $this->belongsTo('App\Owner','owner_id','id');
+    }
+
+    public function getBarcodeAttribute(){
+        return $this->barcodes[0]['code']??'';
+    }
+    public function getOwnerNameAttribute(){
+        return $this->owner['name']??'';
+    }
+    public function getOwnerCodeAttribute(){
+        return $this->owner['code']??'';
+    }
+    public function setNameAttribute($value){
+        $this->attributes['name']=str_replace(PHP_EOL,'',$value);
+    }
+    public function getNameAttribute($value){
+        return str_replace(array("\r\n","\n","\r","\"","&quot;"),' ',$value);
+    }
+
+    public function newBarcode($barcode){
+        $barcodeModel = $this->barcodes()->where('code', $barcode)->first();
+        if(!$barcodeModel){
+            return CommodityBarcode::query()->create(['commodity_id'=>$this['id'],'code'=>$barcode]);
+        }
+        return $barcodeModel;
+    }
+}

+ 23 - 0
app/CommodityBarcode.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelTimeFormat;
+
+use App\Traits\ModelLogChanging;
+
+class CommodityBarcode extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    protected $fillable=['code','commodity_id','created_at'];
+
+    public function getCodeAttribute($value){
+        return str_replace(array("\r\n","\n","\r","\"","&quot;"),' ',$value);
+    }
+    public function commodity(){
+        return $this->belongsTo('App\Commodity','commodity_id','id');
+    }
+}

+ 24 - 0
app/CommodityMaterialBoxModel.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class CommodityMaterialBoxModel extends Model
+{
+    use ModelLogChanging;
+
+    protected $table = "commodity_material_box_model";
+    public $timestamps = false;
+
+    protected $fillable=[
+        "commodity_id","material_box_model_id","maximum"
+    ];
+
+    public function materialBoxModel()
+    {
+        return $this->belongsTo(MaterialBoxModel::class,"material_box_model_id","id");
+    }
+}

+ 26 - 0
app/Components/ApiProcurementResponse.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Components;
+
+use Illuminate\Support\Facades\Gate;
+use Maatwebsite\Excel\Facades\Excel;
+
+trait ApiProcurementResponse{
+
+    public function success($data = null,$message = null): \Illuminate\Http\JsonResponse
+    {
+        $status_code=200;
+        $result = ['status'=>1];
+        if ($data)$result["data"] = $data;
+        if ($message)$result["message"] = $message;
+        return response()->json($result,$status_code);
+    }
+
+    public function error($message = null): \Illuminate\Http\JsonResponse
+    {
+        $status_code=401;
+        $result = ['status'=>0,'message'=>$message];
+        if ($message)$result["message"] = $message;
+        return response()->json($result,$status_code);
+    }
+}

+ 16 - 0
app/Components/ApiResponse.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Components;
+
+
+trait ApiResponse
+{
+    public function response($data, int $code = 200,string $message = null)
+    {
+        $response = ["status_code"=>$code,"data"=>$data,"message"=>$message];
+        header("Content-Type","application/json; charset=UTF-8");
+        echo json_encode($response,JSON_UNESCAPED_UNICODE);
+        exit();
+    }
+}

+ 45 - 0
app/Components/AsyncResponse.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Components;
+
+use Illuminate\Support\Facades\Gate;
+use Maatwebsite\Excel\Facades\Excel;
+
+trait AsyncResponse{
+
+    protected function gate(string $authorityName)
+    {
+        if(!Gate::allows($authorityName)){
+            echo json_encode(["success"=>false,"data"=>"无权操作"]);
+            exit();
+        }
+    }
+
+    public function error(string $message)
+    {
+        echo json_encode(["success"=>false,"data"=>$message]);
+        exit();
+    }
+
+    public function success($message = null)
+    {
+        $result = ["success"=>true];
+        if ($message)$result["data"] = $message;
+        echo json_encode($result);
+        exit();
+    }
+
+    public function importExcel(object $class)
+    {
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
+        $file = request()->file();
+        if (!$file)$this->error("文件不存在");
+        $file = reset($file);
+        $fileSuffix=strtolower($file->getClientOriginalExtension());
+        $types = ["xlsx",'xls','csv'];
+        if (!in_array($fileSuffix,$types)) $this->error("不支持该文件类型");
+        $fileSuffix = ucwords($fileSuffix);
+        Excel::import($class,$file->path(),null,$fileSuffix);
+    }
+}

+ 22 - 0
app/Components/Database.php

@@ -0,0 +1,22 @@
+<?php
+
+
+namespace App\Components;
+
+
+trait Database
+{
+    public function getFluxConnection()
+    {
+        $username = config('database.connections.oracle.username');
+        $password = config('database.connections.oracle.password');
+        $host = config('database.connections.oracle.host');
+        $service_name = config('database.connections.oracle.service_name');
+        return oci_connect($username, $password, $host . '/' . $service_name,"utf8");
+    }
+
+    public function releaseFluxConnection($conn)
+    {
+        oci_close($conn);
+    }
+}

+ 13 - 0
app/Components/ErrorPush.php

@@ -0,0 +1,13 @@
+<?php
+
+
+namespace App\Components;
+
+
+trait ErrorPush
+{
+    public function push(string $path, string $title, string $content)
+    {
+        app("ErrorPushService")->push($path,$title,$content);
+    }
+}

+ 27 - 0
app/Configuration.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class Configuration extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+    protected $fillable = [
+        'name','value','description','operator'
+    ];
+
+    public function operator():BelongsTo
+    {
+        return $this->belongsTo(User::class,'operator');
+    }
+
+    public function scopeFilter($query,$filter)
+    {
+        return $filter->apply($query);
+    }
+}

+ 175 - 0
app/Console/Commands/AccordingToOwnersManualBack.php

@@ -0,0 +1,175 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Database;
+use App\OracleDOCOrderHeader;
+use App\Owner;
+use App\Services\OrderService;
+use App\ValueStore;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Database\Eloquent\HigherOrderBuilderProxy;
+
+class AccordingToOwnersManualBack extends Command
+{
+    use Database;
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'AccordingToOwnersManualBack';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '根据货主自动回传奇门标记';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     */
+    public function handle()
+    {
+        ini_set('max_execution_time', 2500);
+        ini_set('memory_limit', '512M');
+        $owners=Owner::query()->where('is_manual_back',1)->orderBy('interval_time')->get();
+        $sys_last_manual_back_time=$this->getOrderManualBackAt();//系统上次回传时间
+        $now=Carbon::now()->toDateTimeString();//当前时间
+        $manualBackTime=null;
+        $ownerCodes=[];
+        foreach ($owners as $owner){
+            $intervalTime=Carbon::parse($now)->diffInMinutes(Carbon::parse($owner->last_manual_back_time));
+            if ($intervalTime>16*60 || !$owner->last_manual_back_time){ // 隔天回传情况 或者 货主上次回传时间为null
+                $manualBackTime=$sys_last_manual_back_time;
+                $ownerCodes=array_unique(data_get($owners,'*.code'));
+                break;
+            }
+            if ($owner->interval_time==30 && $intervalTime>=25 &&$intervalTime<=35){ //存在每30分钟一回传的货主
+                $manualBackTime=$owner->last_manual_back_time;
+                $ownerCodes[]=$owner->code;
+            }else if ($owner->interval_time==60 && $intervalTime>=55 &&$intervalTime<=65){ //存在每1小时一回传的货主
+                $manualBackTime=$owner->last_manual_back_time;
+                $ownerCodes[]=$owner->code;
+            }else if ($owner->interval_time==120 && $intervalTime>=115 &&$intervalTime<=125){ //存在每2小时一回传的货主
+                $manualBackTime=$owner->last_manual_back_time;
+                $ownerCodes[]=$owner->code;
+            }else if ($owner->interval_time==180 && $intervalTime>=175 &&$intervalTime<=185){ //存在每3小时一回传的货主
+                $manualBackTime=$owner->last_manual_back_time;
+                $ownerCodes[]=$owner->code;
+            }
+        }
+        try {
+            $ordernos=$this->allocation($manualBackTime, $now, $ownerCodes);//分配是创建状态订单
+            $this->manualBack($manualBackTime,$now, $ownerCodes,$ordernos);//回传
+        } catch (\Exception $e) {
+            app('LogService')->log(__METHOD__, __FUNCTION__, "自动回传失败" . $manualBackTime . ' || '
+                .$now. ' || ' . json_encode($ownerCodes).' || ' . json_encode($e->getMessage()));
+        }
+        $this->changeOwnerLastManualTime($ownerCodes,$now);//更新回传货主的回传时间
+        $this->setOrderManualBackAt();//回传结束时间标记
+    }
+
+    /**
+     * @param $last_order_manual_back_at
+     * @param $now
+     * @param $ownerCodes
+     * @return array|void
+     * 分配 状态:创建订单、部分预配、预配完成 的订单
+     */
+    private function allocation($last_order_manual_back_at,$now,$ownerCodes)
+    {
+        $orders=OracleDOCOrderHeader::query()
+            ->whereIn('sostatus',['00','10','20'])//状态:创建订单、部分预配、预配完成
+            ->where('edittime','>=',$last_order_manual_back_at)
+            ->where('edittime','<=',$now)
+            ->whereNotNull('soreference5') //快递单号不为空
+            ->whereIn('customerid',$ownerCodes) //指定货主
+            ->where('releasestatus','!=','H')//订单非冻结状态
+            ->get();
+        if($orders->count()==0)return;
+        /** @var OrderService $orderService */
+        $orderService=app("OrderService");
+        $conn = null;
+        $allocationOrderNos=[];
+        foreach ($orders as $order){
+            if (!$order->soreference5) continue;
+            if (!$conn)$conn = $this->getFluxConnection();
+            $res=$orderService->allocation($order->orderno,null,$order->warehouseid,$conn);
+            if (mb_substr($res,0,3)=='000') array_push($allocationOrderNos,$order->orderno);
+        }
+        if ($conn)$this->releaseFluxConnection($conn);
+        return $allocationOrderNos;
+    }
+
+    /**
+     * @param $last_order_manual_back_at
+     * @param $now
+     * @param $ownerCodes
+     * 回传修改标记状态
+     */
+    private function manualBack($last_order_manual_back_at,$now, $ownerCodes,$ordernos)
+    {
+        OracleDOCOrderHeader::query()
+            ->whereIn('sostatus',['40','50','60','61'])
+            ->where('edittime','>=',$last_order_manual_back_at)
+            ->where('edittime','<=',$now)
+            ->whereNotNull('soreference5')
+            ->where('manualflag','N')
+            ->whereIn('customerid',$ownerCodes) //指定货主
+            ->where('releasestatus','!=','H')
+            ->update(['manualflag'=>'Y','edittime'=>$now]);
+        if (count($ordernos)==0)return;
+        OracleDOCOrderHeader::query()
+            ->whereIn('orderno',$ordernos)
+            ->whereIn('sostatus',['40','50','60','61'])
+            ->whereNotNull('soreference5')
+            ->where('manualflag','N')
+            ->where('releasestatus','!=','H')
+            ->update(['manualflag'=>'Y','edittime'=>$now]);
+    }
+    /**
+     * @return HigherOrderBuilderProxy|mixed|null
+     * 获取订单上次自动回传时间
+     */
+    private function getOrderManualBackAt()
+    {
+        $val = ValueStore::query()
+            ->select("value")
+            ->where("name", "last_order_manual_back_at")
+            ->lockForUpdate()
+            ->first();
+        if (!$val) $val = ValueStore::query()
+            ->create(["name" => "last_order_manual_back_at",'value'=>Carbon::now()->toDateTimeString()]);
+        return $val->value ?? null;
+    }
+
+    /**
+     * 设置订单上次自动回传时间
+     */
+    private function setOrderManualBackAt()
+    {
+        ValueStore::query()
+            ->select("value")
+            ->where("name", "last_order_manual_back_at")
+            ->update(["value" => Carbon::now()->toDateTimeString()]);
+    }
+
+    private function changeOwnerLastManualTime($ownerCodes,$now)
+    {
+        Owner::query()->whereIn('code',$ownerCodes)
+            ->update(['last_manual_back_time'=>$now]);
+    }
+}

+ 55 - 0
app/Console/Commands/BeforeCreateOwnerReport.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OwnerReport;
+use App\Services\OwnerService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
+
+class BeforeCreateOwnerReport extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'beforeCreateOwnerReport';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Create owner report in advance and build cache';
+
+
+    const TTL = 2764800;
+    /**
+     * Execute the console command.
+     *
+     */
+    public function handle()
+    {
+        /** @var OwnerService $ownerService */
+        $ownerService = app('OwnerService');
+        $chunks = ($ownerService->get([],["ownerStoragePriceModels"],false,true))->chunk(50);
+        foreach ($chunks as $owners){
+            $insert = [];
+            $date = date("Y-m-d");
+            foreach ($owners as $owner){
+                $insert[] = [
+                    "owner_id"       => $owner->id,
+                    "counting_month" => date("Y-m-d"),
+                    "created_at"     => $date
+                ];
+                //A:件 B:business C:customer D:date
+                Cache::put(date("Y-m")."|B|".$owner->id,0,self::TTL);
+                Cache::put(date("Y-m")."|C|".$owner->id,0,self::TTL);
+                Cache::put(date("Y-m")."|D|".$owner->id,time(),self::TTL);
+                Cache::put(date("Y-m")."|A|".$owner->id,0,self::TTL);
+            }
+            OwnerReport::query()->insert($insert);
+        }
+    }
+}

+ 49 - 0
app/Console/Commands/CheckCacheRackStorage.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Station;
+use App\StationTask;
+use Illuminate\Console\Command;
+
+class CheckCacheRackStorage extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'check:cacheRack';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'check cache rack storage info';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     */
+    public function handle()
+    {
+        $stations = Station::query()->select("id","code")->where("station_type_id",5)
+            ->whereNotNull("parent_id")
+            ->whereNotIn("id",StationTask::query()->select("station_id")
+                ->where("status","!=","完成")->whereIn("station_id",Station::query()->select("id")->where("station_type_id",5)
+                    ->whereNotNull("parent_id"))->groupBy("station_id"))
+            ->get();
+        app("ForeignHaiRoboticsService")->paddingCacheShelf($stations);
+    }
+}

+ 26 - 0
app/Console/Commands/ClearCancelledOrderTask.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OracleDOCWaveDetails;
+use App\Services\OracleDocWaveDetailService;
+use Illuminate\Console\Command;
+
+class ClearCancelledOrderTask extends Command
+{
+
+    protected $signature = 'clear:cancelledOrder';
+
+
+    protected $description = 'Command description';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        app('OracleDocWaveDetailService')->clearCancelledOrderTask();
+    }
+}

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

@@ -0,0 +1,51 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OwnerAreaReport;
+use App\Services\LogService;
+use App\Services\OwnerService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CreateOwnerAreaReport extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'createOwnerAreaReport';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'create owner area report';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 1号生成盘点面积记录,记录留空由人工填写
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        /** @var OwnerService $ownerService */
+        $ownerService = app('OwnerService');
+        $chunks = ($ownerService->get([],["ownerStoragePriceModels"],false,true))->chunk(50);
+        foreach ($chunks as $owners){
+            app("OwnerAreaReportService")->notExistToInsert($owners);
+        }
+    }
+}

+ 104 - 0
app/Console/Commands/CreateOwnerBillReport.php

@@ -0,0 +1,104 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OwnerAreaReport;
+use App\OwnerFeeStorage;
+use App\OwnerPriceSystem;
+use App\Services\LogService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CreateOwnerBillReport extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'createOwnerBillReport';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'create owner bill report';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 1号生成账单确认,确认金额由人工填写 原始金额默认为:即时账单月记录金额+仓储计费与面积计算金额
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $year = (int)date('Y');
+        $month = (int)date('m');
+        if ($month == 1){
+            $year--;
+            $lastMonth = '12';
+        }else $lastMonth = ($month-1) < 10 ? "0".($month-1) : ($month-1);
+        $sql = "SELECT owner_id,SUM(IFNULL(work_fee,0)) AS work_fee,SUM(IFNULL(logistic_fee,0)) AS logistic_fee FROM owner_fee_details WHERE worked_at LIKE ? AND ((type = '发货' AND logistic_fee IS NOT NULL AND work_fee IS NOT NULL) OR (type <> '发货' AND work_fee IS NOT NULL))  GROUP BY owner_id";
+        $billDetails = DB::select(DB::raw($sql),[$year."-".$lastMonth."%"]);
+
+        $areas = OwnerAreaReport::query()->with(["ownerStoragePriceModel.timeUnit","ownerStoragePriceModel.taxRate","ownerStoragePriceModel.unit"])
+            ->where("counting_month","like",$year."-".$lastMonth."%")->get();
+        $map = [];
+        $mapTax = [];
+        foreach($areas as $area){
+            if (!$area->ownerStoragePriceModel)continue;
+            //信息提取模板
+            $GLOBALS["FEE_INFO"] = [
+                "area_id"           =>$area->id,
+                "counting_type"     =>$area->ownerStoragePriceModel->counting_type,
+                "using_type"        =>$area->ownerStoragePriceModel->using_type,
+                "fee_description"   =>"",
+                "total_fee"         =>0,
+                "tax_rate"          =>0,
+            ];
+            $key = $area->owner_id."_".$area->counting_month;
+            if (!isset($map[$key]))$map[$key] = $mapTax[$key] = 0;
+            list($money,$taxFee) = app('OwnerStoragePriceModelService')
+                ->calculationAmount($area->ownerStoragePriceModel,$area->accounting_area,$area->owner_id,$area->counting_month);
+            $map[$key] += $money;
+            $mapTax[$key] += $taxFee;
+
+            $GLOBALS["FEE_INFO"]["total_fee"] = $money;
+            OwnerFeeStorage::query()->create($GLOBALS["FEE_INFO"]);
+        }
+        foreach (OwnerPriceSystem::query()->with(["timeUnit","taxRate"])->select("owner_id","usage_fee")->whereNull("operation")->orWhere("operation","")->get() as $system){
+            list($systemFee[$system->owner_id],$systemTaxFee[$system->owner_id]) = app("OwnerAreaReportService")->systemFee($system,$year."-".$lastMonth);
+        }
+        $chunks = array_chunk($billDetails,50);
+        foreach ($chunks as $bills){
+            $date = date('Y-m-d H:i:s');
+            $createOwnerBillReport = [];
+            foreach ($bills as $bill){
+                $key = $bill->owner_id."_".$year."-".$lastMonth;
+                $createOwnerBillReport[] = [
+                    "owner_id"          => $bill->owner_id,       //项目ID
+                    "counting_month"    => $year."-".$lastMonth."-01", //结算月
+                    "work_fee"          => $bill->work_fee,
+                    "logistic_fee"      => $bill->logistic_fee,
+                    "storage_fee"       => $map[$key] ?? 0,
+                    "storage_tax_fee"   => $mapTax[$key] ?? 0,
+                    "other_fee"         => $systemFee[$bill->owner_id] ?? null,
+                    "other_tax_fee"     => $systemTaxFee[$bill->owner_id] ?? null,
+                    "created_at"        => $date,
+                ];
+            }
+            LogService::log(__METHOD__,"项目管理-生成确认账单",json_encode($createOwnerBillReport));
+            DB::table("owner_bill_reports")->insert($createOwnerBillReport);
+        }
+    }
+}

+ 128 - 0
app/Console/Commands/CreateOwnerReport.php

@@ -0,0 +1,128 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OwnerAreaReport;
+use App\OwnerBillReport;
+use App\OwnerReport;
+use App\Services\common\BatchUpdateService;
+use App\Services\LogService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
+
+class CreateOwnerReport extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'createOwnerReport';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'create owner report';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 1号生成或修改上月报表  此处假设每月生成报表数 不足1000,超过此数可能在SQL执行上溢出
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        //转化日期格式 取得上月日期与天数 & 两月前月份
+        $year = (int)date('Y');
+        $month = (int)date('m');
+        if ($month == 1){
+            $year--;
+            $lastMonth = '12';
+        }else $lastMonth = ($month-1) < 10 ? "0".($month-1) : ($month-1);
+        $historyYear = $year;
+        if (($month-1) == 1){
+            $historyYear--;
+            $historyMonth = '12';
+        }else $historyMonth = ($month-2) < 10 ? "0".($month-2) : ($month-2);
+        $lastDay = date("d",strtotime("$year-$lastMonth +1 month -1 day"));
+
+        //获取上月面积与报表
+        $areas = OwnerAreaReport::query()->select("id","owner_id","counting_month",DB::raw("SUM(accounting_area) total,YEAR(counting_month) y,MONTH(counting_month) m"))
+            ->with(['owner'=>function($query){
+                $query->select('id',"code");
+            }])->where("counting_month","like",$year."-".$lastMonth."%")
+            ->groupBy("y","m","owner_id")->get();
+        $reports = OwnerReport::query()->where("counting_month","like",$year."-".$lastMonth."%")->orWhere("counting_month","like",$historyYear."-".$historyMonth."%")->get();
+        $bills = OwnerBillReport::query()->where("counting_month","like",$year."-".$lastMonth."%")->get();
+
+        //日均单量统计
+        /*$query = DB::raw("select  count(*) c,CUSTOMERID from DOC_ORDER_HEADER where SOSTATUS = '99' and EDITTIME >= to_date('".$year."-".$lastMonth."-01 00:00:00','yyyy-mm-dd hh24:mi:ss') and EDITTIME <= to_date('".$year."-".$lastMonth."-".$lastDay." 23:59:59','yyyy-mm-dd hh24:mi:ss') group by CUSTOMERID");
+        $orderStatistic = DB::connection("oracle")->select($query);
+        $map = [];
+        foreach ($orderStatistic as $item){
+            $map[$item->customerid] = $item->c;
+        }*/
+
+        //已存在的报表记录
+        $reportMap = [];
+        $historyReportMap = [];
+        foreach ($reports as $report){
+            if ($report->counting_month == ($historyYear."-".$historyMonth)){
+                $historyReportMap[$report->owner_id."_".$report->counting_month] = $report->current_month_counting_area;
+                continue;
+            }
+            $reportMap[$report->owner_id."_".$report->counting_month] = $report;
+        }
+
+        //组装账单记录
+        $billMap = [];
+        foreach ($bills as $index => $bill){
+            $billMap[$bill->owner_id."_".$bill->counting_month] = $bill->id;
+        }
+
+        //组装报表记录数据
+        $updateReports = [[
+            "id","daily_average_order_amount","current_month_counting_area","owner_bill_report_id"
+        ]];
+        $createReports = [];
+        foreach ($areas as $area){
+            $report = $reportMap[$area->owner_id."_".$area->counting_month] ?? false;
+            if ($report){
+                $updateReports[] = [
+                    "id"=>$report->id,
+                    "daily_average_order_amount"=>round(($report->to_business_quantity+$report->to_customer_quantity) / $lastDay,2),
+                    "current_month_counting_area"=>$area->total ?? 0,
+                    "owner_bill_report_id" => $billMap[$area->owner_id."_".$area->counting_month] ?? 0,
+                ];
+            }else $createReports[] = [
+                "owner_id"=>$area->owner_id,
+                "counting_month"=>$area->counting_month."-01",
+                "daily_average_order_amount"=>0,
+                "current_month_counting_area"=>$area->total ?? 0,
+                "owner_bill_report_id" => $billMap[$area->owner_id."_".$area->counting_month] ?? 0,
+                "last_month_counting_area" => $historyReportMap[$area->owner_id."_".($historyYear."-".$historyMonth)] ?? 0,
+            ];
+        }
+        //执行生成或修改
+        if (count($updateReports)>1){
+            app(BatchUpdateService::class)->batchUpdate('owner_reports', $updateReports);
+            app('LogService')->log(__METHOD__,"项目管理-修改原有货主报表",json_encode($updateReports));
+        }
+        if (count($createReports)>0){
+            DB::table("owner_reports")->insert($createReports);
+            app('LogService')->log(__METHOD__,"项目管理-生成货主报表",json_encode($createReports));
+        }
+    }
+}

+ 88 - 0
app/Console/Commands/CreateProcurementTotalBill.php

@@ -0,0 +1,88 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Jobs\ProcurementCheckConfirmInform;
+use App\ProcurementCheckSheet;
+use App\ProcurementTotalBill;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class CreateProcurementTotalBill extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'createProcurementTotalBill';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '采购生成总账单';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        $date=$this->getDate();
+        $procurementCheckSheets=ProcurementCheckSheet::query()
+            ->selectRaw('procurements.supplier_id supplier_id,procurement_deliveries.signed_at signed_at,procurement_check_sheets.status status,SUM(procurement_check_sheets.account_payable) account_payable')
+            ->leftJoin('procurement_deliveries','procurement_check_sheets.procurement_delivery_id','procurement_deliveries.id')
+            ->leftJoin('procurements','procurement_deliveries.procurement_id','procurements.id')
+            ->where('procurement_deliveries.signed_at','like',$date."%")
+            ->groupBy('supplier_id')
+            ->get();
+        $totalBill=[];
+        foreach ($procurementCheckSheets as $procurementCheckSheet){
+            if ($procurementCheckSheet->account_payable<1) continue;
+            $totalBill[]=[
+                'counting_month'=>$date.'-01',
+                'supplier_id'=>$procurementCheckSheet->supplier_id,
+                'total_payable'=>$procurementCheckSheet->account_payable,
+                'status'=>$procurementCheckSheet->status,
+                'created_at'=>date('Y-m-01 00:00:00'),
+                'updated_at'=>date('Y-m-01 00:00:00'),
+            ];
+        }
+        if (count($totalBill)>0){
+            DB::table("procurement_total_bills")->insert($totalBill);
+            app('LogService')->log(__METHOD__,"采购管理-生成月账单报表",json_encode($totalBill));
+            $procurementTotalBills=ProcurementTotalBill::query()
+                ->withCount('procurement')
+                ->with(['supplier.user.userDetail'])
+                ->where('counting_month',$date.'-01')
+                ->get();
+            dispatch(new ProcurementCheckConfirmInform($procurementTotalBills));
+        }
+    }
+
+    private function getDate(){//获取当前日期的上月 月份
+        $month = (int)date('m');
+        $year = (int)date('Y');
+        if ($month == 1){
+            $year--;
+            $lastMonth = '12';
+        }else{
+            $lastMonth = ($month-1) < 10 ? "0".($month-1) : ($month-1);
+        }
+        $date=$year."-".$lastMonth;
+        return $date;
+    }
+}

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

@@ -0,0 +1,61 @@
+<?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(order_packages.created_at,'%Y-%m-%d') date,IFNULL(order_packages.measuring_machine_id, 0) measuring_machine_id,order_packages.owner_id,
+SUM(CASE WHEN order_packages.weighed_at IS NOT NULL THEN 1 ELSE 0 END) AS count,
+COUNT(1) total FROM order_packages LEFT JOIN orders ON order_packages.order_id=orders.id
+WHERE orders.wms_status != '订单取消'
+AND order_packages.created_at BETWEEN '{$yesterday} 00:00:00' AND '{$yesterday} 23:59:59' GROUP BY date,order_packages.measuring_machine_id,order_packages.owner_id
+sql;
+        $result = DB::select(DB::raw($sql));
+        if (!$result) {
+            $obj = [
+                "targeted_at" => $yesterday,
+                "un_weigh_count" => 0,
+                "total_count" => 0,
+                "measuring_machine_id" => 0,
+                "owner_id" => 0
+            ];
+            $model = OrderPackageCountingRecord::query()->create($obj);
+            Cache::put("weight.".$yesterday, $obj);
+        }else{
+            $objs = [];
+            foreach ($result as $v){
+                $obj = [
+                    "targeted_at"    => $v->date,
+                    "un_weigh_count" => $v->count,
+                    "total_count"    => $v->total,
+                    "measuring_machine_id"    => $v->measuring_machine_id,
+                    "owner_id"    => $v->owner_id
+                ];
+                $model = OrderPackageCountingRecord::query()->create($obj);
+                array_push($objs, $obj);
+            }
+            Cache::put("weight.".$yesterday, $objs);
+        }
+    }
+}

+ 41 - 0
app/Console/Commands/EndReceivingTask.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\ReceivingTaskService;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+
+class EndReceivingTask extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'receivingTask:batchEnd';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '延时完结 入库开单任务';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        /** @var ReceivingTaskService $service */
+        $service = app(ReceivingTaskService::class);
+        $service->overtimeToCompleteTask();
+    }
+}

+ 76 - 0
app/Console/Commands/FluxOrderFix.php

@@ -0,0 +1,76 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Http\Controllers\Controller;
+use App\OracleDOCOrderHeader;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+
+class FluxOrderFix extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'FluxOrderFix';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'FluxOrderFix';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->fixEdisendflagAtWrong();
+        $this->youWuFixEdisendflagAtWrong();
+    }
+
+    public function fixEdisendflagAtWrong(){
+        OracleDOCOrderHeader::where('edisendflag','W')
+            ->whereNull('EDI_RESENDTIME')
+            ->where('edisendtime','>',Carbon::now()->subDays(2))
+            ->where('ediremarks2','<>','不支持的单据类型')
+        ->update(['edisendflag'=>'N','manualflag'=>'N','EDI_RESENDTIME'=>Carbon::now()]);
+
+        OracleDOCOrderHeader::where('edisendflag','W')
+            ->where('EDI_RESENDTIME','>',Carbon::now()->subDays(2))
+            ->where('edisendtime','>',Carbon::now()->subDays(2))
+            ->where('ediremarks2','<>','不支持的单据类型')
+        ->update(['edisendflag'=>'N','manualflag'=>'N']);
+
+    }
+
+    public function youWuFixEdisendflagAtWrong(){
+        OracleDOCOrderHeader::where('yw_edisendflag','W')
+            ->where('customerid','YOUWU')
+            ->whereNull('EDI_RESENDTIME')
+            ->where('yw_edisendtime','>',Carbon::now()->subDays(2))
+            ->where('yw_edisendflag','W')
+            ->update(['yw_edisendflag'=>'N','manualflag'=>'N','EDI_RESENDTIME'=>Carbon::now()]);
+
+        OracleDOCOrderHeader::where('yw_edisendflag','W')
+            ->where('customerid','YOUWU')
+            ->where('EDI_RESENDTIME','>',Carbon::now()->subDays(2))
+            ->where('yw_edisendtime','>',Carbon::now()->subDays(2))
+            ->update(['yw_edisendflag'=>'N','manualflag'=>'N']);
+    }
+}

+ 190 - 0
app/Console/Commands/InventoryDailyLoggingOwner.php

@@ -0,0 +1,190 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\CommodityBarcode;
+use App\OwnerAreaReport;
+use App\Services\CommodityService;
+use App\Services\common\BatchUpdateService;
+use App\Services\LogService;
+use Illuminate\Console\Command;
+use App\InventoryDailyLoggingOwner as LoggingOwner;
+use Illuminate\Support\Facades\DB;
+
+class InventoryDailyLoggingOwner extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'InventoryDailyLoggingOwner';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '监听指定货主记录';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     *  增量添加,每天都会重复去录入之前数据,没有限制去重条件. 因业务需要去查看每天同批货的变动
+     *
+     * @param CommodityService $commodityService
+     * @return void
+     */
+    public function handle(CommodityService $commodityService)
+    {
+        //获取需要查询的货主,键值对:code => id
+        $owners = $this->getLoggingOwners();
+        //计算数量,为0直接return
+        $let = count($owners);
+        if ($let == 0)return;
+        //拼接SQL,SELECT仅取指定字段
+        $sql = "SELECT INV_LOT.customerid,INV_LOT.sku,INV_LOT.qty,BAS_SKU.skulength,
+                BAS_SKU.skuwidth,BAS_SKU.skuhigh,BAS_SKU.cube,BAS_SKU.descr_c,BAS_SKU.alternate_sku1,BAS_SKU.grossweight,
+                INV_LOT_ATT.lotatt05
+                FROM INV_LOT
+                LEFT JOIN BAS_SKU ON INV_LOT.sku = BAS_SKU.sku AND INV_LOT.customerid = BAS_SKU.customerid
+                LEFT JOIN INV_LOT_ATT ON INV_LOT.lotnum = INV_LOT_ATT.lotnum
+                WHERE INV_LOT.customerid IN (";
+        $index = 1;
+        foreach ($owners as $code => $id){
+            $sql .= "'".$code."'";
+            if ($index != $let)$sql .= ",";
+            $index++;
+        }
+        $sql .= ")";
+        //执行获取结果:stdClass类型
+        $invLots = DB::connection('oracle')->select(DB::raw($sql));
+        //声明一个数组,作为第一次去重的容器
+        $inventoryDailyLogs = [];
+        foreach ($invLots as $invLot){
+            //以MAP形式记录进数组,货主code与商品sku作为联合主键唯一标识,如重复叠加其数量
+            if ($inventoryDailyLogs[$owners[$invLot->customerid].'-'.$invLot->sku.'-'.$invLot->lotatt05] ?? false){
+                $inventoryDailyLogs[$owners[$invLot->customerid].'-'.$invLot->sku.'-'.$invLot->lotatt05]['amount'] += $invLot->qty;
+            }else{
+                //符合的结果取此对象的关键信息存进第一个数组
+                $inventoryDailyLogs[$owners[$invLot->customerid].'-'.$invLot->sku.'-'.$invLot->lotatt05] = [
+                    'commodity' => [
+                        'owner_id'=>$owners[$invLot->customerid],
+                        'sku'=>$invLot->sku,
+                        'name'=>$invLot->descr_c,
+                        'length'=>$invLot->skulength,
+                        'width'=>$invLot->skuwidth,
+                        'height'=>$invLot->skuhigh,
+                        'volumn'=>$invLot->cube,
+                        'code'=>$invLot->alternate_sku1,
+                        'weight' => $invLot->grossweight,
+                    ],
+                    'amount' => $invLot->qty,
+                    'volumn_occupied' => 0,
+                    'gross_weight' => 0,
+                    'depository_code' => $invLot->lotatt05,
+                ];
+            }
+        }
+        //第二个数组作为批量插入使用
+        $data = [];
+        //盘点货主记录
+        $inventories = [];
+        //遍历第一个数组,此时已经去重完成,直接取对应参数push进data中
+        foreach ($inventoryDailyLogs as $inventoryDailyLog){
+            //寻找己方库中是否存在对应商品,存在更新其长宽高体积,不存在录入
+            $commodity = $inventoryDailyLog['commodity'];
+            $param = ['owner_id'=>$commodity['owner_id'],'sku'=>$commodity["sku"]];
+            //体积存在为0的情况,需再次计算一次,此处体积为m³
+            if (!$commodity['volumn'] || $commodity['volumn'] == "0"){
+                $commodity['volumn'] = $commodity['length']*$commodity['width']*$commodity['height'];
+            }
+            $column = [
+                'owner_id'=>$commodity['owner_id'],
+                'sku'=>$commodity['sku'],
+                'name'=>$commodity['name'],
+                'length'=>$commodity['length'],
+                'width'=>$commodity['width'],
+                'height'=>$commodity['height'],
+                'volumn'=>$commodity['volumn'],
+            ];
+            $result = $commodityService->updateOrCreate($param,$column);
+            app('LogService')->log(__METHOD__,"同步库存每日记录时修改或生成商品",json_encode($column));
+
+            $commodity_id = $result->id;
+            //寻找对应barcode是否存在,不存在录入
+            if ($commodity['code']) CommodityBarcode::query()->firstOrCreate(['commodity_id'=>$commodity_id,'code'=>$commodity['code']]);
+            //计算总体积,商品体积×该单数量
+            $volumn_occupied = $commodity['volumn']*$inventoryDailyLog["amount"];
+            $gross_weight = $commodity['weight']*$inventoryDailyLog["amount"];
+
+            $depository = null;
+            if ($inventoryDailyLog['depository_code']){
+                $depository = app('DepositoryService')->firstOrCreate(["code"=>$inventoryDailyLog['depository_code']],[
+                    "name"=>$inventoryDailyLog['depository_code'],
+                    "code"=>$inventoryDailyLog['depository_code'],
+                ]);
+            }
+
+            $data[]  = [
+                "owner_id"=>$commodity['owner_id'],
+                "created_at"=>date('Y-m-d H:i:s'),
+                "commodity_id"=>$commodity_id,
+                "amount"=>$inventoryDailyLog['amount'],
+                "volumn_occupied"=>$volumn_occupied,
+                "gross_weight"=>$gross_weight,
+                "depository_id"=>$depository ? $depository->id : null,
+            ];
+            if (array_key_exists($commodity['owner_id'],$inventories)){
+                $inventories[$commodity['owner_id']]["volume"] += $volumn_occupied;
+                $inventories[$commodity['owner_id']]["amount"] += $inventoryDailyLog['amount'];
+            }else{
+                $inventories[$commodity['owner_id']] = [
+                    "volume" => $volumn_occupied,
+                    "amount" => $inventoryDailyLog['amount'],
+                ];
+            }
+        }
+        DB::table('inventory_daily_logs')->insert($data);
+        app('LogService')->log(__METHOD__,"同步库存每日记录",json_encode($data));
+        if (count($inventories)>0){
+            $update = [["id","accounting_area"]];
+            $areas = OwnerAreaReport::query()->with("ownerStoragePriceModel.unit")
+                ->whereIn("owner_id",array_keys($inventories))
+                ->where("counting_month",'like',date("Y-m")."%")->get();
+            foreach ($areas as $area){
+                $unit = $area->ownerStoragePriceModel->unit->name ?? null;
+                if ($unit!='m³' || $unit!='件')continue;
+                $update[] = [
+                    "id"              => $area->id,
+                    "accounting_area" => $unit=='m³' ? $inventories[$area->owner_id]["volume"] : $inventories[$area->owner_id]["amount"],
+                ];
+            }
+            if (count($update)>1){
+                app(BatchUpdateService::class)->batchUpdate("owner_area_reports",$update);
+                LogService::log(__CLASS__,"监听货主记录时修改面积报信息",json_encode($inventories));
+            }
+        }
+    }
+
+    public function getLoggingOwners(){
+        $loggingOwners = LoggingOwner::with('owner')->select('id','owner_id')->where('status','启用')->get();
+        $owners = [];
+        foreach ($loggingOwners as $loggingOwner){
+            if ($loggingOwner->owner){
+                $owners[$loggingOwner->owner->code] = $loggingOwner->owner_id;
+            }
+        }
+        return $owners;
+    }
+}

+ 52 - 0
app/Console/Commands/LogExpireDelete.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Http\Controllers\Controller;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class LogExpireDelete extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'LogExpireDelete';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'LogExpireDelete';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->deleteLog();
+    }
+
+    public function deleteLog(){
+        $expire_duration=config('logging.expire_duration');//保留的日志天数
+        $date=Carbon::now()->subDays($expire_duration)->format('Y-m-d');
+        DB::table('logs')->where('created_at','<',$date)->delete();
+        DB::statement('OPTIMIZE TABLE logs');
+    }
+}

+ 47 - 0
app/Console/Commands/LoginListenerCommand.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+use Workerman\Worker;
+
+class LoginListenerCommand extends Command
+{
+    protected $signature = 'workman {action} {--d}';
+
+    protected $description = 'Start a Workerman server.';
+
+    public function handle()
+    {
+        global $argv;
+        $action = $this->argument('action');
+
+        $argv[0] = 'wk';
+        $argv[1] = $action;
+        $argv[2] = $this->option('d') ? '-d' : '';
+        $ws_worker = new Worker('websocket://0.0.0.0:2346');
+
+        // Emitted when new connection come
+        /*$ws_worker->onConnect = function ($connection) {
+        };*/
+
+        // Emitted when data received
+        $ws_worker->onMessage = function ($connection, $data) {
+            try {
+                $data = json_decode($data);
+                $_SERVER['HTTP_USER_AGENT'] = $data->userAgent;
+                $connection->send(app("UserService")->verifySingleTag($data->user, $data->token) ? "true" : "false");
+            }catch (\Exception $e){
+                Log::error("SOCKET连接恶意信息",[$e->getMessage(),$data]);
+            }
+        };
+
+        // Emitted when connection closed
+        $ws_worker->onClose = function ($connection) {
+        };
+
+        // Run worker
+        Worker::runAll();
+    }
+}

+ 49 - 0
app/Console/Commands/MakeModelCommand.php

@@ -0,0 +1,49 @@
+<?php
+
+
+namespace App\Console\Commands;
+
+
+use Illuminate\Support\Str;
+use Symfony\Component\Console\Input\InputOption;
+
+class MakeModelCommand extends \Illuminate\Foundation\Console\ModelMakeCommand
+{
+    protected function getStub()
+    {
+        if ($this->option('pivot')) {
+            return parent::getStub();
+        }
+        return __DIR__ . '/stubs/model.stub';
+    }
+    public function handle()
+    {
+        if (parent::handle() === false && ! $this->option('force')) {
+            return false;
+        }
+
+        if ($this->option('all')) {
+            $this->input->setOption('service', true);
+        }
+
+        if ($this->option('service')) {
+            $this->createService();
+        }
+    }
+    public function createService()
+    {
+        $modelName = Str::studly(class_basename($this->argument('name')));
+
+        $this->call('make:service', [
+            'name' => "{$modelName}Service",
+        ]);
+    }
+
+    protected function getOptions(): array
+    {
+        $options= parent::getOptions();
+        $options[]=['service', 'sv', InputOption::VALUE_NONE, 'Create a new service file'];
+        return $options;
+    }
+
+}

+ 124 - 0
app/Console/Commands/MakeServiceCommand.php

@@ -0,0 +1,124 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Traits\ServiceAppAop;
+use Illuminate\Console\Command;
+use Illuminate\Support\Str;
+
+class MakeServiceCommand extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'make:service
+    {--noProvider : Register in the provider}
+    {name : fileName}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Create Service file';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        if (!file_exists(base_path('app\\Services'))){
+            mkdir('app\\Services',666,false);
+        }
+        preg_match('/(.*?)Service/',$this->argument('name'),$resultNames);
+        if(count($resultNames)==0) {
+            $fileName = $this->argument('name');
+            $modelName = $this->argument('name');
+        }else{
+            $fileName=$resultNames[0];
+            $modelName=Str::studly($resultNames[1]);
+        }
+
+        if (!file_exists(base_path('app\\Services\\'.$fileName.'.php'))){
+            file_put_contents(base_path('app\\Services\\'.$fileName.'.php'),
+                '<?php '
+                .PHP_EOL
+                .PHP_EOL
+                .'namespace App\Services;'
+                .PHP_EOL
+                .PHP_EOL
+                .'use App\Traits\ServiceAppAop;'
+                .PHP_EOL
+                .'use App\\'.$modelName.';'
+                .PHP_EOL
+                .PHP_EOL
+                .'class '.$fileName
+                .PHP_EOL
+                .'{'
+                .PHP_EOL
+                .'    use ServiceAppAop;'
+                .PHP_EOL
+                .'    protected $modelClass='.$modelName.'::class;'
+                .PHP_EOL
+                .PHP_EOL.
+                '}');
+        }
+        else $this->error("ERROR: file exists;");
+        if (!$this->option("noProvider")){
+            $path = base_path("app\\Providers\\AppServiceProvider.php");
+            $i = 0;
+            $fop = fopen($path,"r+");
+            $endLine = 0;
+            $startLine = 0;
+            $sign = 0;
+            while (!feof($fop)){
+                $i += 1;
+                $lineStr = fgets($fop);
+                if (strpos($lineStr,"loadingService(){"))$sign = $i;
+                if (strpos($lineStr,"app()->singleton"))$endLine = $i;
+                if (strpos($lineStr,"App\Services"))$startLine = $i;
+            };
+            fclose($fop);
+            $fop = fopen($path,"r+");
+            $i = 0;
+            $header = [];
+            $content = [];
+            $footer = [];
+            while (!feof($fop)){
+                $i += 1;
+                $lineStr = fgets($fop);
+                if ($i == $startLine){
+                    $lineStr = $lineStr."use App\Services\\$fileName;".PHP_EOL;
+                }
+                if ($i<=$sign)$header[] = $lineStr;
+                if ($i>$sign && $i<= $endLine){
+                    $content[] = $lineStr;
+                }
+                if ($i>$endLine)$footer[] = $lineStr;
+            };
+            $content[] = "        app()->singleton('{$fileName}',{$fileName}::class);".PHP_EOL;
+            array_multisort($content);
+            fclose($fop);
+            unlink($path);
+            foreach (array_merge($header,$content,$footer) as $value){
+                file_put_contents($path,$value,FILE_APPEND);
+            }
+        }
+        $this->info("File create success!");
+    }
+
+}

+ 118 - 0
app/Console/Commands/MakeTestCommand.php

@@ -0,0 +1,118 @@
+<?php
+
+
+namespace App\Console\Commands;
+
+
+use Illuminate\Filesystem\Filesystem;
+use Symfony\Component\Console\Input\InputArgument;
+
+class MakeTestCommand extends \Illuminate\Foundation\Console\TestMakeCommand
+{
+    protected $signature = 'make:test {name : The name of the class}
+    {--unit : Create a unit test}
+    {--controller : Create a controller test}
+    {--controllers : Create a controllers test}
+    {--service : Create a service test}
+    {--services : Create a services test}
+    ';
+    protected function getDefaultNamespace($rootNamespace)
+    {
+        if ($this->option('controller')
+            ||$this->option('controllers')) {
+            return $rootNamespace.'\Controllers';
+        }
+        if ($this->isForService()) {
+            return $rootNamespace.'\Services\\'
+                .$this->getServiceName()
+                ;
+        }
+        if ($this->option('unit')) {
+            return $rootNamespace.'\Unit';
+        } else {
+            return $rootNamespace.'\Feature';
+        }
+    }
+
+    protected function isForService()
+    {
+        if ($this->option('services')
+            ||$this->option('service')) {
+            return true;
+        }
+        return false;
+    }
+    protected function getNameInput()
+    {
+        $input= trim($this->argument('name'));
+        if(!$this->isForService()){
+            return $input;
+        }
+        $inputs = explode(':', $input);
+        return $inputs[1]
+            ?$this->getMethodName()
+            :$inputs[0]
+            ;
+    }
+    protected function getServiceName()
+    {
+        $input= trim($this->argument('name'));
+        if(!$this->isForService()){
+            return $input;
+        }
+        return ucfirst(explode(':',$input)[0]);
+    }
+    protected function getModelName()
+    {
+        $input= trim($this->argument('name'));
+        if(!$this->isForService()){
+            return $input;
+        }
+        return str_replace('Service','',(explode(':',$input)[0]));
+    }
+    protected function getModelNamePlural()
+    {
+        $modelName=preg_replace('/(s|x|ch|sh)$/','$1es',lcfirst($this->getModelName()));
+        $modelName=preg_replace('/y$/','ies',$modelName);
+        $modelName=preg_replace('/[cC]hild$/','children',$modelName);
+        if(preg_match('/[cC]hildren$/',$modelName)==0){
+            $modelName=preg_replace('/([^s])$/','$1s',$modelName);
+        }
+        return $modelName;
+    }
+    protected function getMethodName()
+    {
+        $input= trim($this->argument('name'));
+        if(!$this->isForService()){
+            return $input;
+        }
+        return ucfirst(explode(':',$input)[1]).'Test';
+    }
+
+    protected function getStub()
+    {
+        if ($this->option('controller')
+            ||$this->option('controllers')) {
+            return __DIR__.('/stubs/test.controller.stub');
+        }
+        if ($this->option('services')
+            ||$this->option('service')) {
+            return __DIR__.('/stubs/test.service.stub');
+        }
+        return $this->option('unit')
+            ? $this->resolveStubPath('/stubs/test.unit.stub')
+            : $this->resolveStubPath('/stubs/test.stub');
+    }
+
+    protected function replaceClass($stub, $name)
+    {
+        $class = str_replace($this->getNamespace($name).'\\', '', $this->getMethodName());
+        $class = str_replace('\\', '', $class);
+        $stub = str_replace(['{{ serviceName }}', '{{serviceName}}'], $this->getServiceName(), $stub);
+        $stub = str_replace(['{{ modelName }}', '{{modelName}}'], $this->getModelName(), $stub);
+        $stub = str_replace(['{{ modelNameUc }}', '{{modelNameUc}}'], ucfirst($this->getModelName()), $stub);
+        $stub = str_replace(['{{ modelNamePlural }}', '{{modelNamePlural}}'], lcfirst($this->getModelNamePlural()), $stub);
+
+        return str_replace(['DummyClass', '{{ class }}', '{{class}}'], $class, $stub);
+    }
+}

+ 60 - 0
app/Console/Commands/OrderCountingRecordTask.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\LogService;
+use App\Services\NewOrderCountingRecordService;
+use Illuminate\Console\Command;
+
+class OrderCountingRecordTask extends Command
+{
+    /**
+     * @var NewOrderCountingRecordService $service
+     */
+    public $service;
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'orderCountingRecordTask';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @throws \Exception
+     */
+    public function handle()
+    {
+        LogService::log(OrderCountingRecordTask::class, "订单量统计", '');
+        ini_set('memory_limit', '2226M');
+        $this->service = app('NewOrderCountingRecordService');
+        if (now()->toDateString() == now()->startOfMonth()->toDateString()) {//是否为月初
+            //统计上月的数据
+            $this->service->recordOrder(now()->subMonth()->startOfMonth()->toDateString(), now()->subMonth()->endOfMonth()->toDateString(), '月');
+        }
+        if (now()->toDateString() == now()->startOfYear()->toDateString()) {//是否为年初
+            //统计上年的数据
+            $this->service->recordOrder(now()->subYear()->startofYear()->toDateString(), now()->subYear()->endOfYear()->toDateString(), '年');
+        }
+        //统计前一天的数据
+        $this->service->recordOrder(now()->subDay()->toDateString(), now()->subDay()->toDateString(), '日');
+    }
+}

+ 58 - 0
app/Console/Commands/ReceiveRecord.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\RejectedBill;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+
+class ReceiveRecord extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'record:scan';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'scan rejected record status';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    private static $delayedHour = 48;
+    /**
+     * Execute the console command.
+     *
+     */
+    public function handle()
+    {
+        $delayedDateTime = Carbon::now()->subHours(self::$delayedHour)->toDateTimeString();
+        Log::info("退件记录",["signTime"=>$delayedDateTime,"result"=>\App\ReceiveRecord::query()->where("record_at","<=",$delayedDateTime)
+            ->where("delayed",0)->select("logistic_number")->pluck("logistic_number")->toArray()]);
+        \App\ReceiveRecord::query()->where("record_at","<=",$delayedDateTime)
+            ->where("delayed",0)
+            ->update(["delayed"=>2]);
+        \App\ReceiveRecord::query()
+            ->where("record_at",">",$delayedDateTime)
+            ->where("delayed",0)
+            ->whereIn("logistic_number",RejectedBill::query()->select("logistic_number_return")
+            ->where("created_at",">",$delayedDateTime)->whereIn("logistic_number_return",
+                    \App\ReceiveRecord::query()->select("logistic_number")
+                    ->where("record_at",">",$delayedDateTime)
+                    ->where("delayed",0)))->update(["delayed"=>1]);
+    }
+}

+ 311 - 0
app/Console/Commands/SyncBatchTask.php

@@ -0,0 +1,311 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Jobs\BatchTaskJob;
+use App\Jobs\BroadcastBatchToZhengCangJob;
+use App\Order;
+use App\OrderBin;
+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\DB;
+
+class SyncBatchTask extends Command
+{
+    protected $signature = 'sync:batch';
+
+    protected $description = 'sync wms batch task';
+
+    /** @var DocWaveHeaderService $service */
+    private $service;
+    /** @var BatchService $batchService */
+    private $batchService;
+
+    public function __construct()
+    {
+        parent::__construct();
+        $this->service = app(DocWaveHeaderService::class);
+        $this->batchService = app(BatchService::class);
+    }
+
+    public function handle()
+    {
+        sleep(10+rand(0,10));
+        $this->disposeHeader();
+        sleep(rand(0,10));
+        $this->disposeDetail();
+    }
+
+    private function disposeHeader($date = null)
+    {
+        DB::transaction(function ()use($date){
+            //获取更新时间与WMS数据
+            if (!$date){
+                $valueStore = ValueStore::query()->where("name","wave_last_sync_date")->first();
+                $date = $valueStore->value ?? Carbon::now()->subSeconds(65)->toDateTimeString();
+            }
+
+            $count = DB::connection("oracle")->selectOne(DB::raw("SELECT COUNT(*) count FROM DOC_WAVE_HEADER WHERE EDITTIME >= TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')"),[$date]);
+
+            if ($count->count > 500){
+                $query = DB::raw(<<<sql
+                    SELECT * FROM (SELECT header.*, ROWNUM AS rowno FROM (
+SELECT * FROM DOC_WAVE_HEADER WHERE EDITTIME >= TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')
+ORDER BY EDITTIME)header WHERE ROWNUM <= 500)wave WHERE wave.rowno >= 0
+sql
+                );
+                $waves = DB::connection("oracle")->select($query,[$date]);
+                $this->headerExe($waves);
+                $this->disposeHeader($waves[count($waves)-1]->edittime);
+            }else{
+                $waves = $this->service->get(["edittime"=>$date],["edittime"=>"gtOrEqual"]);
+                $this->headerExe($waves);
+            }
+        });
+    }
+
+    private function headerExe($waves)
+    {
+        if (count($waves) < 1)return;
+        //获取本地数据对比差异
+        $codes = [];
+        foreach ($waves as $wave){
+            $codes[] = $wave->waveno;
+        }
+        $map = [];
+        $batches = $this->batchService->get(["code"=>$codes]);
+        if ($batches){
+            foreach ($batches as $index=>$batch)$map[$batch->code] = $index;
+        }
+        $update = [["id","wms_status","wms_type","updated_at"]];
+        $insert = [];
+
+        foreach ($waves as $wave){
+            if (isset($map[$wave->waveno])){
+                $bat = $batches[$map[$wave->waveno]];
+                $wms_status = $this->wms_status($wave);
+                if ($bat->wms_status != $wms_status || $bat->wms_type != $wave->descr){
+                    $update[] = [
+                        "id" => $bat->id,
+                        "wms_status" => $this->wms_status($wave),
+                        "wms_type"=>$wave->descr,
+                        "updated_at"=>$wave->edittime,
+                    ];
+                }
+                continue;
+            }
+            $owner = app("OwnerService")->codeGetOwner($wave->customerid);
+            $insert[] = [
+                "code" => $wave->waveno,
+                "wms_type"=>$wave->descr,
+                "status" => '未处理',
+                "wms_status" => $this->wms_status($wave),
+                "created_at"=>$wave->addtime,
+                "updated_at"=>$wave->edittime,
+                "owner_id"=>$owner->id,
+            ];
+        }
+
+        //存在则更新
+        if (count($update)>1){
+            $bool = app(BatchUpdateService::class)->batchUpdate("batches",$update);
+            if ($bool!==false)LogService::log(__METHOD__,"SUCCESS-同步更新波次成功",json_encode($update));
+            else LogService::log(__METHOD__,"ERROR-同步更新波次失败",json_encode($update));
+        }
+
+        //不存在则录入
+        if ($insert){
+            $this->batchService->insert($insert);
+            LogService::log(__METHOD__,"SUCCESS-同步插入波次成功",json_encode($insert));
+        }
+        ValueStore::query()->where("name","wave_last_sync_date")->update(["value"=>$waves[count($waves)-1]->edittime]);
+    }
+
+    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);
+            }else{
+                $sql = "SELECT ORDERNO,WAVENO,SEQNO,EDITTIME FROM DOC_WAVE_DETAILS WHERE EDITTIME >= TO_DATE(?,'yyyy-mm-dd hh24:mi:ss')";
+                $details = DB::connection("oracle")->select(DB::raw($sql),[$date]);
+                $this->detailExe($details);
+            }
+        });
+    }
+
+    private function detailExe($details)
+    {
+        if (count($details) < 1)return;
+        $map = [];
+        $nos = [];
+        $orderCodes = [];
+        $seqnos = [];
+        $batchMapping = [];
+        foreach ($details as $detail){
+            if (isset($map[$detail->waveno]))$map[$detail->waveno][] = $detail->orderno;
+            else {
+                $map[$detail->waveno] = [$detail->orderno];
+                $nos[] = $detail->waveno;
+            }
+            $orderCodes[] = $detail->orderno;
+            $seqnos[$detail->orderno] = $detail->seqno;
+            $batchMapping[$detail->orderno] = $detail->waveno;
+        }
+        $orders = Order::query()->select("id","batch_id","code")->whereIn("code",$orderCodes)->get();
+        if (count($orderCodes) != count($orders))LogService::log(__CLASS__,"格口号-订单存在差异",json_encode($orderCodes));
+        $existOrder = [];
+        if ($orders){
+            $orderIds = [];
+            $orderMap = [];
+            foreach ($orders as $order){
+                $orderIds[] = $order->id;
+                $orderMap[$order->id] = $seqnos[$order->code];
+                $existOrder[$order->code] = $order->batch_id;
+            }
+            $updateBin = [["id","number"]];
+            $insertBin = [];
+            $deleteBin = [];
+            $orderBins = OrderBin::query()->select("id","order_id","number")->whereIn("order_id",$orderIds)->get();
+            foreach ($orderBins as $orderBin){
+                if (!isset($orderMap[$orderBin->order_id])){
+                    $deleteBin[] = $orderBin->id;
+                    continue;
+                }
+                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,
+                    'created_at' => $d
+                ];
+            }
+            if (count($updateBin)>1){
+                app(BatchUpdateService::class)->batchUpdate("order_bins",$updateBin);
+                LogService::log(__METHOD__,"波次同步-更新订单格口号",json_encode($updateBin));
+            }
+            if ($insertBin){
+                OrderBin::query()->insert($insertBin);
+                LogService::log(__METHOD__,"波次同步-录入订单格口号",json_encode($insertBin));
+            }
+            if ($deleteBin){
+                OrderBin::destroy($deleteBin);
+                LogService::log(__METHOD__,"波次同步-删除订单格口号",json_encode($deleteBin));
+            }
+        }
+        $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"]];
+        $updatingBatches = [];
+        foreach ($batches as $batch){
+            $mark = false;
+            foreach ($map[$batch->code] as $on){
+                if ((!isset($existOrder[$on])) || $existOrder[$on]!=$batch->id){
+                    $updateOrder[] = [
+                        "code"=>$on,
+                        "batch_id"=>$batch->id
+                    ];
+                    $mark = true;
+                }
+            }
+            if ($mark)$updatingBatches[] = $batch;
+            unset($map[$batch->code]);
+        }
+        if (count($updateOrder)>1){
+            app("OrderService")->batchUpdate($updateOrder);//反向修改订单
+            LogService::log(__METHOD__,"波次同步-修改订单波次号",json_encode($updateOrder));
+            app("BatchService")->checkBatchOrderInfo($updatingBatches);
+            LogService::log(__METHOD__,"波次注册一入口",json_encode($updatingBatches));
+            BatchTaskJob::dispatch($updatingBatches);    //在这里为波次注册队列任务!
+            BroadcastBatchToZhengCangJob::dispatch($updatingBatches);    //在这里为波次注册祯仓推送任务!
+        }
+        if ($map){
+            $waveCodes = array_keys($map);
+            $waves = $this->service->get(["waveno"=>$waveCodes],["waveno"=>"in"]);
+            $insert = [];
+            foreach ($waves as $wave){
+                $owner = app("OwnerService")->codeGetOwner($wave->customerid);
+                $insert[] = [
+                    "code" => $wave->waveno,
+                    "status" => '未处理',
+                    "wms_status" => $this->wms_status($wave),
+                    "wms_type"=>$wave->descr,
+                    "created_at"=>$wave->addtime,
+                    "updated_at"=>$wave->edittime,
+                    "owner_id"=>$owner->id,
+                ];
+            }
+            if ($insert){
+                $this->batchService->insert($insert);
+                LogService::log(__METHOD__,"SUCCESS-同步插入波次成功",json_encode($insert));
+                $batches = $this->batchService->get(["code"=>$waveCodes]);
+                foreach ($batches as $batch){
+                    app("OrderService")->update(["code"=>$map[$batch->code]],["batch_id"=>$batch->id]);
+                }
+                app("BatchService")->checkBatchOrderInfo($batches);
+                LogService::log(__METHOD__,"波次注册二入口",json_encode($batches));
+                BatchTaskJob::dispatch($batches);    //在这里为波次注册队列任务!
+                BroadcastBatchToZhengCangJob::dispatch($batches);    //在这里为波次注册祯仓推送任务!
+            }
+        }
+        ValueStore::query()->where("name","wave_detail_last_sync_date")->update(["value"=>$details[count($details)-1]->edittime]);
+    }
+
+    /**
+     * @param $wave
+     * @return string
+     */
+    public function wms_status($wave): string
+    {
+        switch ($wave->wavestatus) {
+            case 00:
+                $wms_status = '创建';
+                break;
+            case 40:
+                $wms_status = '部分收货';
+                break;
+            case 90:
+                $wms_status = '取消';
+                break;
+            case 99:
+                $wms_status = '完成';
+                break;
+            case 62:
+                $wms_status = '部分装箱';
+                break;
+            default:
+                $wms_status = (string)$wave->wavestatus;
+        }
+        return $wms_status;
+    }
+}

+ 53 - 0
app/Console/Commands/SyncCarrier.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Logistic;
+use App\Services\common\BatchUpdateService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class SyncCarrier extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sync:carrier';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Sync carriers every hour';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $carriers = DB::connection("oracle")->select(DB::raw("SELECT CUSTOMERID,CUSTOMER_TYPE,DESCR_C,CASE DESCR_E WHEN 'WL' THEN '物流' ELSE '快递' END AS TYPE FROM BAS_CUSTOMER WHERE CUSTOMER_TYPE = 'CA'"));
+        $logistics = Logistic::query()->whereIn("code",array_column($carriers,"customerid"))->get();
+        $changes = diff($carriers,$logistics,"code",["code"=>"customerid","name"=>"descr_c","type"=>"type"]);
+        if ($changes['attached'])Logistic::query()->insert($changes['attached']);
+        if ($changes['updated']){
+            array_unshift($changes['updated'],["code","name","type"]);
+            app(BatchUpdateService::class)->batchUpdate("logistics",$changes['updated']);
+        }
+        if ($changes["detached"])Logistic::query()->whereIn("code",$changes["detached"])->delete();
+    }
+}

+ 44 - 0
app/Console/Commands/SyncLogCacheTask.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Log;
+use App\Services\LogService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Redis;
+
+class SyncLogCacheTask extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'syncLogCacheTask';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     */
+    public function handle()
+    {
+        LogService::syncRedisLogs();
+    }
+}

+ 56 - 0
app/Console/Commands/SyncOrderPackageLogisticRouteTask.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\LogService;
+use App\Services\OrderPackageReceivedSyncService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+
+class SyncOrderPackageLogisticRouteTask extends Command
+{
+    /**
+     * @var OrderPackageReceivedSyncService $service
+     */
+    public $service;
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'syncOrderPackageLogisticRouteTask';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @throws \Exception
+     */
+    public function handle()
+    {
+        $usage = memory_get_usage();
+        $exeTime = microtime(true);
+        ini_set('memory_limit', '2226M');
+        $this->service = app('OrderPackageReceivedSyncService');
+        $this->service->syncLogisticRoute();
+        $this->service->syncLogisticRouteByAliJiSu();
+        Log::warning("快递路由同步任务",["usage"=>(memory_get_usage()-$usage)/1048576,
+            "elapsedTime"=>round(microtime(true)-$exeTime,3)]);//MB SECOND
+    }
+}

+ 45 - 0
app/Console/Commands/SyncUserVisitMenuLogsCacheTask.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\LogService;
+use App\Services\CheckActiveMenuService;
+use App\UserVisitMenuLog;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Redis;
+
+class SyncUserVisitMenuLogsCacheTask extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'syncUserVisitMenuLogsCacheTask';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     */
+    public function handle()
+    {
+        CheckActiveMenuService::sync();
+    }
+}

+ 144 - 0
app/Console/Commands/SyncWMSOrderTask.php

@@ -0,0 +1,144 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\OracleDOCOrderHeader;
+use App\Services\OracleDOCOrderHeaderService;
+use App\Services\OrderService;
+use App\ValueStore;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
+
+class SyncWMSOrderTask extends Command
+{
+    /**
+     * @var OrderService $service
+     */
+    private $service;
+    protected $signature = 'sync:order';
+    private $last_start_key ;       // 上一次任务开始时间
+    private $last_end_key ;         // 上一次任务结束时间
+    private $last_err_key ;         // 上一次任务异常时间
+    private $restart;               // 重启时间
+    private $is_enabled;            // 是否开启
+    protected $description = 'Command description';
+    public function __construct()
+    {
+        parent::__construct();
+        $this->service = app('OrderService');
+    }
+    public function init()
+    {
+        $this->last_start_key = config('sync.order_sync.cache_prefix.last_start_at');
+        $this->last_end_key = config('sync.order_sync.cache_prefix.last_end_at');
+        $this->last_err_key = config('sync.order_sync.cache_prefix.last_err_at');
+        $this->restart = config('sync.order_sync.cache_prefix.restart');
+        $this->is_enabled= config('sync.order_sync.enabled');
+    }
+    public function handle()
+    {
+        $this->init();
+        if($this->is_enabled===false)return;
+        sleep(rand(2,3));
+        $start_time =  Cache::remember($this->last_start_key,null,function (){
+            return ValueStore::query()->firstOrCreate(['name'=>$this->last_start_key])->first()->value;
+        });
+        $end_time =  Cache::remember($this->last_end_key,null,function (){
+            return  ValueStore::query()->firstOrCreate(['name'=>$this->last_end_key])->first()->value;
+        });
+
+        $start = Carbon::now();
+        // 判断上一次任务异常了
+        // 第一次出现异常没有记录上任务结束时间
+        if(isset($start_time) && empty($end_time) && $start->diffInMinutes(Carbon::parse($start_time)) < $this->restart)return;
+        // 这次任务启动时间 距离上一次任务的一个启动时间 小于10
+        if(isset($start_time) && isset($end_time)
+            && Carbon::parse($end_time)->lt(Carbon::parse($start_time))
+            && $start->diffInMinutes(Carbon::parse($start_time)) < $this->restart)
+            return;
+
+        $start = (string)$start;
+        Cache::put($this->last_start_key,$start);
+        ValueStore::query()->where('name',$this->last_start_key)->update(['value'=>$start]);
+        $this->syncCreatedOrder();
+        $this->syncUpdatedOrder();
+        $end = (string)Carbon::now();
+        Cache::put($this->last_end_key,$end);
+        ValueStore::query()->where('name',$this->last_end_key)->update(['value'=>$end]);
+    }
+
+    public function syncCreatedOrder()
+    {
+        /**
+         * @var OracleDocOrderHeaderService  $oracleDOCOrderHeaderService
+         */
+        $oracleDOCOrderHeaderService = app('OracleDocOrderHeaderService');
+
+        $newest_key         = config('sync.order_sync.cache_prefix.created_at');
+        $newest_list_key    = config('sync.order_sync.cache_prefix.newest_list');
+        $hasKey         = config('sync.order_sync.cache_prefix.newest_has');
+        $prefixKey      = config('sync.order_sync.cache_prefix.newest');
+        ini_set('memory_limit', '1024M');
+        $last_date = $this->service->getOrderSyncAt($newest_key,'newest');                             // 获取创建时间点
+
+        $orderHeaders = OracleDOCOrderHeader::query()
+            ->selectRaw(implode(',',OracleDOCOrderHeaderService::$columns))
+            ->whereColumn('DOC_Order_Header.editTime','=','DOC_Order_Header.addTime')
+            ->where('addTime','>=',$last_date)
+            ->orderBy('DOC_Order_Header.addTime')->get();
+
+        if($orderHeaders->count()==0)return;
+        $orderHeaderList = $orderHeaders->chunk(100);
+        foreach ($orderHeaderList as $item) {
+            $item = $oracleDOCOrderHeaderService->loadMissing($item);
+            $last_order = $item->last();                                                               // 时间点靠后的
+            $newest_orders = $item->where('addtime',$last_order->addtime);
+            $orderHeaders = $this->service->filterOrderByCache($item,$newest_list_key);                  // 对比缓存
+            if(count($newest_orders)>0 && count($orderHeaders) >0){
+                $this->service->syncOrder($orderHeaders);                                                    //  同步订单
+                $this->service->cancelOrderCache($newest_list_key,$prefixKey);                                   //  清除缓存
+                $this->service->pushOrderCache($newest_orders,$prefixKey,$hasKey,$newest_list_key);              //  添加缓存
+                $this->service->setOrderSyncAt($newest_key,$last_order->addtime,count($orderHeaders)>0);   //  更新时间
+            }
+        }
+        unset($orderHeaders,$newest_orders,$last_order);
+    }
+
+    public function syncUpdatedOrder()
+    {
+        /**
+         * @var OracleDOCOrderHeaderService $oracleDOCOrderHeaderService
+         */
+        $oracleDOCOrderHeaderService = app('OracleDocOrderHeaderService');
+        $renewal_key        = config('sync.order_sync.cache_prefix.updated_at');
+        $renewal_list_key   = config('sync.order_sync.cache_prefix.renewal_list');
+        $hasKey         = config('sync.order_sync.cache_prefix.renewal_has');
+        $prefixKey      = config('sync.order_sync.cache_prefix.renewal');
+        ini_set('memory_limit', '1024M');
+        $last_date = $this->service->getOrderSyncAt($renewal_key,'renewal');                               // 获取更新时间点
+
+        $orderHeaders = OracleDOCOrderHeader::query()
+            ->selectRaw(implode(',',OracleDOCOrderHeaderService::$columns))
+            ->whereColumn('DOC_Order_Header.editTime','!=','DOC_Order_Header.addTime')
+            ->where('editTime',">=",$last_date)
+            ->orderBy('editTime')->get();
+
+        if($orderHeaders->count()==0)return;
+
+        $orderHeaderList = $orderHeaders->chunk(100);
+        foreach ($orderHeaderList as $item) {
+            $item  = $oracleDOCOrderHeaderService->loadMissing($item);
+            $renewal_order = $item->last();                                                            // 时间点靠后的
+            $renewal_orders =  $item->where('edittime',$renewal_order->edittime);
+            $orderHeaders = $this->service->filterOrderByCache($orderHeaders,$renewal_list_key);                     // 对比缓存
+            if(count($renewal_orders)>0 && count($orderHeaders)>0){
+                $this->service->syncOrder($item);                                                    // 同步订单
+                $this->service->cancelOrderCache($renewal_list_key,$prefixKey);                                      // 清除缓存
+                $this->service->pushOrderCache($renewal_orders,$prefixKey,$hasKey,$renewal_list_key);                // 添加缓存
+                $this->service->setOrderSyncAt($renewal_key,$renewal_order->edittime,count($orderHeaders)>0);   // 更新时间
+            }
+        }
+        unset($orderHeaders,$renewal_orders,$renewal_order);
+    }
+}

+ 90 - 0
app/Console/Commands/SyncWmsCommoditiesInformation.php

@@ -0,0 +1,90 @@
+<?php
+
+namespace App\Console\Commands;
+
+
+use App\Services\CommodityService;
+use App\ValueStore;
+use Illuminate\Console\Command;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Cache;
+
+class SyncWmsCommoditiesInformation extends Command
+{
+
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SyncWmsCommoditiesInformation';
+    private $task_start_at;
+    private $task_end_at;
+    private $restart;
+    private $is_enabled;
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '同步WMS的商品信息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function init()
+    {
+        $this->task_start_at = config('sync.commodity_sync.task_start_at');
+        $this->task_end_at = config('sync.commodity_sync.task_end_at');
+        $this->restart = config('sync.commodity_sync.restart');
+        $this->is_enabled= config('sync.commodity_sync.enabled');
+    }
+    /**
+     * Execute the console command.
+     */
+    public function handle()
+    {
+        $this->init();
+        if($this->is_enabled==false)return;
+        sleep(rand(5,20));
+        $start_time =  Cache::remember($this->task_start_at,null,function (){
+            return ValueStore::query()->firstOrCreate(['name'=>$this->task_start_at])->first()->value;
+        });
+        $end_time =  Cache::remember($this->task_end_at,null,function (){
+            return  ValueStore::query()->firstOrCreate(['name'=>$this->task_end_at])->first()->value;
+        });
+
+        $start = Carbon::now();
+        // 判断上一次任务异常了
+        //1.第一次就异常了
+        if(isset($start_time) && empty($end_time) && $start->diffInMinutes(Carbon::parse($start_time)) < $this->restart)return;
+        //2.中间某次异常了
+        if(isset($start_time) && isset($end_time)
+            && Carbon::parse($end_time)->lt(Carbon::parse($start_time))
+            && $start->diffInMinutes(Carbon::parse($start_time)) < $this->restart)
+            return;
+
+        $start = (string)$start;
+        Cache::put($this->task_start_at,$start);
+        ValueStore::query()->where('name',$this->task_start_at)->update(['value'=>$start]);
+        $this->SyncWmsCommoditiesInformation();
+        $end = (string)Carbon::now();
+        Cache::put($this->task_end_at,$end);
+        ValueStore::query()->where('name',$this->task_end_at)->update(['value'=>$end]);
+    }
+
+    public function SyncWmsCommoditiesInformation(){
+        /** @var CommodityService $commodityService */
+        $commodityService  = app(CommodityService::class);
+        $commodityService->syncCommodityCreated();
+        $commodityService->syncCommodityUpdated();
+    }
+}

+ 47 - 0
app/Console/Commands/TestTemp.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Http\Controllers\Controller;
+use App\Http\Controllers\TestController;
+use App\OracleDOCOrderHeader;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+
+class TestTemp extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'TestTemp';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'TestTemp';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        return (new TestController())->cleanOrderRepeat();
+    }
+
+}

+ 45 - 0
app/Console/Commands/UpdateOrderPackageExceptionTypeCountingRecordTask.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\LogService;
+use Illuminate\Console\Command;
+
+class UpdateOrderPackageExceptionTypeCountingRecordTask extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'updateOrderPackageExceptionTypeCountingRecordTask';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新order_package_exception_type_counting_records';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        LogService::log(__CLASS__,"更新order_package_exception_type_counting_records",'');
+        ini_set('memory_limit','2226M');
+        app('OrderPackageExceptionTypeCountingRecordService')->updateOrCreate(7);
+    }
+}

+ 71 - 0
app/Console/Commands/WASSyncWMSOrderInformation.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\LogService;
+use App\Services\OrderTrackingService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Auth;
+
+class WASSyncWMSOrderInformation extends Command
+{
+
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'WASSyncWMSOrderInformation';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '同步WMS的订单信息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        sleep(rand(15,30));
+        $this->WasSyncWmsOrder();
+    }
+
+    public function WasSyncWmsOrder(){
+
+        /** @var OrderTrackingService $orderTrackingService */
+        $orderTrackingService  = app('OrderTrackingService');
+
+        $dataInterval = intval(data_get(config('sync'), 'order_tracking_import.interval')) * 60 + 5;
+
+        $startDate = Carbon::now()->subSeconds($dataInterval);
+
+        $syncStartDate = data_get(config('sync'), 'order_tracking_import.start_at');
+
+        if($syncStartDate ?? false){
+            $syncStartDate = Carbon::parse($syncStartDate);
+            if ($startDate->lt($syncStartDate)) {
+                $startDate = $syncStartDate;
+            }
+        }
+
+//        $startDate = Carbon::parse('2020-05-06 13:16:51')->toDateTimeString();
+//        $orderTrackingService->根据设置从WMS同步追踪货主的订单($startDate);
+        $orderTrackingService->trackingWmsOrder($startDate);
+    }
+}

+ 91 - 0
app/Console/Commands/WasSyncWmsAsnInformation.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace App\Console\Commands;
+
+
+use App\Services\StoreService;
+use App\ValueStore;
+use Illuminate\Console\Command;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Cache;
+
+class WasSyncWmsAsnInformation extends Command
+{
+
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'WasSyncWmsAsnInformation';
+    private $task_start_at;
+    private $task_end_at;
+    private $restart;
+    private $is_enabled;
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '同步WMS的入库信息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function init()
+    {
+        $this->task_start_at = config('sync.asn_sync.task_start_at');
+        $this->task_end_at = config('sync.asn_sync.task_end_at');
+        $this->restart = config('sync.asn_sync.restart');
+        $this->is_enabled= config('sync.asn_sync.enabled');
+    }
+    /**
+     * Execute the console command.
+     * @return void
+     */
+    public function handle()
+    {
+        $this->init();
+        if($this->is_enabled==false)return;
+        sleep(rand(1,2));
+        $start_time =  Cache::remember($this->task_start_at,null,function (){
+            return ValueStore::query()->firstOrCreate(['name'=>$this->task_start_at])->first()->value;
+        });
+        $end_time =  Cache::remember($this->task_end_at,null,function (){
+            return  ValueStore::query()->firstOrCreate(['name'=>$this->task_end_at])->first()->value;
+        });
+
+        $start = Carbon::now();
+        // 判断上一次任务异常了
+        //1.第一次就异常了
+        if(isset($start_time) && empty($end_time) && $start->diffInMinutes(Carbon::parse($start_time)) < $this->restart)return;
+        //2.中间某次异常了
+        if(isset($start_time) && isset($end_time)
+            && Carbon::parse($end_time)->lt(Carbon::parse($start_time))
+            && $start->diffInMinutes(Carbon::parse($start_time)) < $this->restart)
+            return;
+
+        $start = (string)$start;
+        Cache::put($this->task_start_at,$start);
+        ValueStore::query()->where('name',$this->task_start_at)->update(['value'=>$start]);
+        $this->WasSyncWmsAsn();
+        $end = (string)Carbon::now();
+        Cache::put($this->task_end_at,$end);
+        ValueStore::query()->where('name',$this->task_end_at)->update(['value'=>$end]);
+    }
+
+    public function WasSyncWmsAsn(){
+        /** @var StoreService $storeService */
+        $storeService  = app(StoreService::class);
+        ini_set('memory_limit', '1024M');
+        $storeService->storeCreateByWms();
+        $storeService->storeUpdateByWms();
+    }
+}

+ 45 - 0
app/Console/Commands/WorkOrderTimingTask.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\WorkOrderService;
+use Illuminate\Console\Command;
+
+class WorkOrderTimingTask extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'workOrder:timingTask';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        /** @var WorkOrderService $service */
+        $service = App('WorkOrderService');
+        $service->timingTask();
+    }
+}

+ 14 - 0
app/Console/Commands/stubs/model.stub

@@ -0,0 +1,14 @@
+<?php
+
+namespace {{ namespace }};
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class {{ class }} extends Model
+{
+    use ModelLogChanging;
+
+    //
+}

+ 15 - 0
app/Console/Commands/stubs/test.controller.stub

@@ -0,0 +1,15 @@
+<?php
+
+namespace {{ namespace }};
+
+use Tests\TestCase;
+
+class {{ class }} extends TestCase
+{
+
+    public function testExample()
+    {
+    {{ class }};
+        $this->assertTrue(true);
+    }
+}

+ 37 - 0
app/Console/Commands/stubs/test.service.stub

@@ -0,0 +1,37 @@
+<?php
+
+namespace {{ namespace }};
+use App\Services\{{ serviceName }};
+use Tests\TestCase;
+use App\{{ modelNameUc }};
+use App\Traits\TestMockSubServices;
+
+class {{ class }} extends TestCase
+{
+    use TestMockSubServices;
+    /** @var {{ serviceName }} $service */
+    public $service;
+    private $data;
+    private $amount=2;
+    function setUp(): void
+    {
+        parent::setUp();
+        $this->service = app('{{ serviceName }}');
+        $this->data['{{ modelNamePlural }}']
+            = factory({{ modelNameUc }}::class, $this->amount)
+            ->create();
+    }
+
+    public function testReturned()
+    {
+        $this->assertTrue(true);
+    }
+
+    function tearDown(): void
+    {
+        {{ modelNameUc }}::query()
+            ->whereIn('id',data_get($this->data['{{ modelNamePlural }}'],'*.id')??[])
+            ->delete();
+        parent::tearDown();
+    }
+}

+ 119 - 0
app/Console/Kernel.php

@@ -0,0 +1,119 @@
+<?php
+
+namespace App\Console;
+
+use App\Console\Commands\BeforeCreateOwnerReport;
+use App\Console\Commands\ClearCancelledOrderTask;
+use App\Console\Commands\CreateProcurementTotalBill;
+use App\Console\Commands\CreateWeightStatistic;
+use App\Console\Commands\EndReceivingTask;
+use App\Console\Commands\FluxOrderFix;
+use App\Console\Commands\InventoryDailyLoggingOwner;
+use App\Console\Commands\LogExpireDelete;
+use App\Console\Commands\MakeServiceCommand;
+use App\Console\Commands\ReceiveRecord;
+use App\Console\Commands\SyncBatchTask;
+use App\Console\Commands\SyncCarrier;
+use App\Console\Commands\SyncLogCacheTask;
+use App\Console\Commands\SyncOrderPackageLogisticRouteTask;
+use App\Console\Commands\SyncUserVisitMenuLogsCacheTask;
+use App\Console\Commands\SyncWmsCommoditiesInformation;
+use App\Console\Commands\SyncWMSOrderTask;
+use App\Console\Commands\TestTemp;
+use App\Console\Commands\WasSyncWmsAsnInformation;
+use App\Console\Commands\WASSyncWMSOrderInformation;
+use App\Console\Commands\WorkOrderTimingTask;
+use App\Jobs\CalculationArrivedManNumJob;
+use App\Jobs\LaborApplyRecordJob;
+use App\Services\LaborApplyService;
+use Illuminate\Console\Scheduling\Schedule;
+use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
+use Illuminate\Foundation\Console\ModelMakeCommand;
+
+class  Kernel extends ConsoleKernel
+{
+    /**
+     * The Artisan commands provided by your application.
+     *
+     * @var array
+     */
+    protected $commands = [
+        LogExpireDelete::class,
+        MakeServiceCommand::class,
+        FluxOrderFix::class,
+        InventoryDailyLoggingOwner::class,
+        WASSyncWMSOrderInformation::class,
+        SyncLogCacheTask::class,
+        SyncUserVisitMenuLogsCacheTask::class,
+        TestTemp::class,
+        SyncBatchTask::class,
+        SyncWMSOrderTask::class,
+        SyncOrderPackageLogisticRouteTask::class,
+        SyncWmsCommoditiesInformation::class,
+        ClearCancelledOrderTask::class,
+        WasSyncWmsAsnInformation::class,
+        CreateWeightStatistic::class,
+        BeforeCreateOwnerReport::class,
+        CreateProcurementTotalBill::class,
+        SyncCarrier::class,
+        ReceiveRecord::class,
+        EndReceivingTask::class,
+        WorkOrderTimingTask::class,
+    ];
+
+    /**
+     * Define the application's command schedule.
+     *
+     * @param  Schedule  $schedule
+     * @return void
+     */
+    protected function schedule(Schedule $schedule)
+    {
+        $schedule->command('LogExpireDelete')->dailyAt('00:01');
+        $schedule->command('InventoryDailyLoggingOwner')->dailyAt('08:00')->runInBackground();
+        $schedule->command('FluxOrderFix')->hourlyAt(1);
+        $schedule->command('WASSyncWMSOrderInformation')->everyMinute();
+        $schedule->command('syncLogCacheTask')->everyMinute();
+        $schedule->command('createOwnerReport')->monthlyOn(1);
+        $schedule->command('createOwnerBillReport')->monthlyOn(1);
+        $schedule->command('createOwnerAreaReport')->monthlyOn(1);
+        $schedule->command('beforeCreateOwnerReport')->monthlyOn(1);
+        $schedule->command('sync:batch')->everyMinute();
+        $schedule->command('sync:order')->everyMinute();
+        $schedule->command('syncOrderPackageLogisticRouteTask')->dailyAt('6:01')->runInBackground();//同步快递信息到orderPackage
+        $schedule->command('syncOrderPackageLogisticRouteTask')->dailyAt('12:01')->runInBackground();//同步快递信息到orderPackage
+        $schedule->command('syncOrderPackageLogisticRouteTask')->dailyAt('18:01')->runInBackground();//同步快递信息到orderPackage
+//        $schedule->command('updateOrderPackageExceptionTypeCountingRecordTask')->dailyAt('2:20');//更新OrderPackageExceptionTypeCountingRecord
+        $schedule->command('SyncWmsCommoditiesInformation')->everyMinute();
+        $schedule->command('clear:cancelledOrder')->everyMinute();
+        $schedule->command('WasSyncWmsAsnInformation')->everyMinute();
+        $schedule->command('create:weightStatistic')->dailyAt("00:30")->runInBackground();
+        $schedule->command('sync:carrier')->hourlyAt(1);
+        $schedule->command('createProcurementTotalBill')->monthlyOn(1);
+        $schedule->command('orderCountingRecordTask')->dailyAt("1:00")->runInBackground();
+        //$schedule->command('check:cacheRack')->everyMinute();
+        $schedule->command('AccordingToOwnersManualBack')->everyThirtyMinutes()->between('9:00','16:30')->runInBackground();
+
+        $schedule->job(new LaborApplyRecordJob(false))->dailyAt(LaborApplyService::TIME_OUT_HOUR.':01')->runInBackground();//生成临时工派遣数据
+
+        $schedule->job(new CalculationArrivedManNumJob(now()->subDays(2)->startOfDay()))->dailyAt('01:01')->runInBackground();//生成实际到岗人数数据
+
+        $schedule->command("record:scan")->hourlyAt(1);//退件信息标记
+        $schedule->command("receivingTask:batchEnd")->dailyAt('0:15')->runInBackground();   //批量完成入库单任务
+        $schedule->command("workOrder:timingTask")->dailyAt('0:15')->runInBackground();     // 工单定时任务
+    }
+
+    /**
+     * Register the commands for the application.
+     *
+     * @return void
+     */
+    protected function commands()
+    {
+        $this->load(__DIR__ . '/Commands');
+        $this->app->extend('command.model.make',function(ModelMakeCommand $base,$app){
+            return new \App\Console\Commands\MakeModelCommand($app['files']);
+        });
+        require base_path('routes/console.php');
+    }
+}

+ 20 - 0
app/CustomField.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class CustomField extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable=['table',
+        'field',
+        'present_name',
+        'authority_name',
+        'authority_id',
+        'condition_field',
+        'condition_value'];
+}

+ 41 - 0
app/Customer.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\HasMany;
+
+use App\Traits\ModelLogChanging;
+
+class Customer extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+
+    protected $fillable = [
+        "code",             //客户代码
+        "name",             //客户名称
+        "company_name",     //公司名称
+        "invoice_address",  //发票地址
+        "contact_man",      //联系人
+        "phone",            //联系电话
+        "remark",           //公司备注
+    ];
+
+    public function customerLogs(): HasMany
+    {
+        return $this->hasMany(CustomerLog::class,'customer_id','id');
+    }
+
+    public function owners()
+    {   //子项目
+        return $this->hasMany(Owner::class,"customer_id","id");
+    }
+
+    public function tags()
+    {   //标签
+        return $this->belongsToMany(CustomerTag::class,"customer_tag_customer");
+    }
+}

+ 34 - 0
app/CustomerLog.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class CustomerLog extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+
+    protected $fillable = ['customer_id', 'customer_log_status_id', 'user_id', 'description'];
+    protected $guarded = ['id'];
+
+
+    public function status()
+    {   //状态
+        return $this->belongsTo(CustomerLogStatus::class,"customer_log_status_id","id");
+    }
+
+    public function user()
+    {
+        return $this->belongsTo(User::class);
+    }
+
+    public function customer()
+    {
+        return $this->belongsTo(Customer::class);
+    }
+}

+ 18 - 0
app/CustomerLogStatus.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class CustomerLogStatus extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+
+    protected $fillable = ['name', 'description'];
+    protected $guarded = ['id'];
+}

+ 19 - 0
app/CustomerTag.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class CustomerTag extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+
+    protected $fillable=[
+        "name","explanation","count"
+    ];
+}

+ 105 - 0
app/DeliveryAppointment.php

@@ -0,0 +1,105 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class DeliveryAppointment extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    protected $fillable=[
+        "user_id",
+        "owner_id",
+        "procurement_number",
+        "asn_number",
+        "warehouse_id",
+        "tonne",
+        "cubic_meter",
+        "box_amount",
+        "capacity",
+        "appointment_date",
+        "date_period",
+        "status",
+        "logistic_id",
+        "logistic_number",
+        "type_mark",
+        "remark",
+    ];
+    //时段 映射date_period字段 必须有序 否则展示数据错乱
+    const PERIOD=[
+        0 => "09-12",
+        1 => "13-15",
+        2 => "15-17",
+    ];
+    //时长 映射PERIOD常量
+    const HOUR=[
+        0 => 3,
+        1 => 2,
+        2 => 2,
+    ];
+    //状态
+    const STATUS=[
+        0 => "待收",
+        1 => "取消",
+        2 => "完成",
+        3 => "已逾期",
+        4 => "逾期收货",
+    ];
+    //类型标记
+    const TYPE = [
+        0 => "质检",
+    ];
+    //禁止送货日期列表 REDIS key
+    const BAN = "DELIVERY_BAN_ON_DATE";
+
+    protected $appends=[
+        "period"
+    ];
+
+    public function cars()
+    {   //车辆
+        return $this->hasMany(DeliveryAppointmentCar::class,"delivery_appointment_id","id");
+    }
+    public function car()
+    {   //单车辆
+        return $this->belongsTo(DeliveryAppointmentCar::class,"id","delivery_appointment_id");
+    }
+    public function details()
+    {   //明细
+        return $this->hasMany(DeliveryAppointmentDetail::class);
+    }
+    public function user()
+    {   //用户
+        return $this->belongsTo(User::class);
+    }
+    public function owner()
+    {   //货主
+        return $this->belongsTo(Owner::class);
+    }
+    public function warehouse()
+    {   //仓库
+        return $this->belongsTo(Warehouse::class);
+    }
+    public function logistic()
+    {   //快递
+        return $this->belongsTo(Logistic::class);
+    }
+
+    /**
+     * 2021-08-05 在此之前所有 period为1的时间都为13-17
+     *
+     * @return string
+     */
+    public function getPeriodAttribute(){
+        /** @var Carbon $create */
+        $create = $this["created_at"];
+        if ($create->lt(Carbon::parse("2021-08-05")) && $this["date_period"]==1)return '13-17';
+        return self::PERIOD[$this["date_period"]];
+    }
+}

+ 39 - 0
app/DeliveryAppointmentCar.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class DeliveryAppointmentCar extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable=[
+        "delivery_appointment_id",
+        "license_plate_number",
+        "car_id",
+        "driver_name",
+        "driver_phone",
+        "appointment_number",
+        "delivery_time",
+        "status",
+        "unloaded_at",
+    ];
+    const STATUS = [
+        0 => "未送达",
+        1 => "作业中",
+        2 => "已完成",
+    ];
+    public $timestamps=false;
+
+    public function deliveryAppointment()
+    {   //预约信息
+        return $this->belongsTo(DeliveryAppointment::class);
+    }
+    public function car()
+    {   //车辆
+        return $this->belongsTo(CarType::class,"car_id","id");
+    }
+}

+ 30 - 0
app/DeliveryAppointmentDetail.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class DeliveryAppointmentDetail extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable=[
+        "delivery_appointment_id",
+        "commodity_id",
+        "bar_code",
+        "name",
+        "amount",
+    ];
+    public $timestamps=false;
+
+    public function deliveryAppointment()
+    {   //预约信息
+        return $this->belongsTo(DeliveryAppointment::class);
+    }
+    public function commodity()
+    {   //商品
+        return $this->belongsTo(Commodity::class);
+    }
+}

+ 16 - 0
app/DeliveryType.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class DeliveryType extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    protected $fillable = ['id', 'name', 'status'];
+}

+ 81 - 0
app/Demand.php

@@ -0,0 +1,81 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelLogChanging;
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+use Illuminate\Database\Eloquent\Builder;
+
+class Demand extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    protected $fillable = ['authority_id', 'initiator', 'description', 'type', 'status', 'handler','title','route'];
+
+    // 需求类型
+    protected static $type = ['需求', '问题'];
+
+    // 状态
+    protected static $status = ['未处理', '处理中', '已处理'];
+
+
+    public function authority(): BelongsTo
+    {
+        return $this->belongsTo(Authority::class);
+    }
+
+    public function initiator(): BelongsTo
+    {
+        return $this->belongsTo(User::class, 'initiator', 'id');
+    }
+
+    public function handle(): BelongsTo
+    {
+        return $this->belongsTo(User::class, 'handler', 'id');
+    }
+
+    public function uploadFile(): HasOne
+    {
+        return $this->hasOne(UploadFile::class, 'table_id', 'id')->where('table_name', 'Demands');
+    }
+
+    public function processes(): HasMany
+    {
+        return $this->hasMany(DemandProcess::class, 'demand_id', 'id');
+    }
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+
+    /**
+     * 保存文件创建对应的文件对象
+     *
+     * @param $fileName
+     * @param  $fileSuffix
+     * @return Builder|Model
+     */
+    public function saveFile($fileName,$fileSuffix)
+    {
+        return UploadFile::query()->create(['table_name' => $this->getTable(), 'table_id' => $this['id'], 'url' => '/files/'.$fileName, 'type' => $fileSuffix]);
+    }
+
+    /**
+     * 删除需求的同时删除处理过程
+     *
+     * @return bool|null
+     * @throws \Exception
+     */
+    public function delete()
+    {
+        $this->processes()->delete();
+        return parent::delete();
+    }
+
+}

+ 27 - 0
app/DemandProcess.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelLogChanging;
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class DemandProcess extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    protected $fillable = ['demand_id', 'processor', 'explain'];
+
+    public function demand(): BelongsTo
+    {
+        return $this->belongsTo(Demand::class);
+    }
+
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(User::class, 'processor', 'id');
+    }
+
+}

+ 27 - 0
app/DepartmentObligationOwner.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class DepartmentObligationOwner extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    public $timestamps=false;
+
+    protected $table='department_obligation_owner';
+
+    protected $fillable=[
+        'department_id','obligation_id', 'owner_id', 'valid_time','create_time', 'update_time','delete_flag','failure_time'
+    ];
+
+    public function department()
+    {
+        return $this->hasOne(UserWorkgroup::class,"id","department_id");
+    }
+}

+ 18 - 0
app/Depository.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+use App\Traits\ModelTimeFormat;
+
+use App\Traits\ModelLogChanging;
+
+class Depository extends Model
+{
+    use ModelLogChanging;
+
+    use ModelTimeFormat;
+    protected $fillable=[
+        'name','code'
+    ];
+}

+ 94 - 0
app/DischargeTask.php

@@ -0,0 +1,94 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class DischargeTask extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    const status = [
+        '创建',
+        '接单',
+        '作业中',
+        '完成'
+    ];
+
+    const types = [
+        '装车',
+        '卸车',
+        '翻托',
+        '包膜'
+    ];
+
+    const units = [
+        'm³',
+        '吨',
+        '托',
+        '件'
+    ];
+
+    protected $fillable = [
+        'owner_id',  // 货主
+        'type',      // 类型
+        'numbers',   // 任务编号
+        'status',    // 状态
+        'income_amount', // 数量
+        'income_unit',   // 单位
+        'income_unit_price', // 单价
+        'income_total_cost', // 总价
+        'income_remark',     // 备注
+        'facilitator_id',    // 卸货商
+        'expenditure_amount',  // 成本数量
+        'expenditure_unit',    // 成本单位
+        'expenditure_unit_price',  // 成本单价
+        'expenditure_total_cost',  // 成本总价
+        'expenditure_remark',      // 成本备注
+        'income_at',                // 预约时间
+        'expenditure_at',          // 卸货时间
+        'warehouse_id',              // 仓库
+        'created_at',  // 创建时间->卸货任务:预约时间->结算报表:日期
+    ];
+
+    // 货主
+    function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+
+    // 卸货商
+    function facilitator(): BelongsTo
+    {
+        return $this->belongsTo(Facilitator::class);
+    }
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+
+    // 仓库
+    public function warehouse(): BelongsTo
+    {
+        return $this->belongsTo(Warehouse::class);
+    }
+
+    // 任务创建人
+    public function creator(): BelongsTo
+    {
+        return $this->belongsTo(User::class,'creator_id');
+    }
+
+    // 成本录入人
+    public function constEntry():BelongsTo
+    {
+        return $this->belongsTo(User::class,'const_entry_id');
+    }
+
+}

+ 17 - 0
app/ErrorTemp.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+
+class ErrorTemp extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable=[
+        "position","title","content","created_at"
+    ];
+    public $timestamps=false;
+}

+ 35 - 0
app/Events/AddOrUpdateOrderIssues.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class AddOrUpdateOrderIssues
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public $order_ids;
+
+    /**
+     * AddOrderIssues constructor.
+     * @param $order_ids
+     */
+    public function __construct($order_ids)
+    {
+        $this->order_ids = $order_ids;
+    }
+
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 37 - 0
app/Events/BroadcastToStation.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+
+class BroadcastToStation implements ShouldBroadcastNow
+{
+    public $json;
+    private $id;
+    const ALL_STATION=0;
+    /**
+     * Create a new event instance.
+     *
+     * @param int $id
+     * @param string $json
+     * @return void
+     */
+    public function __construct(int $id, string $json)
+    {
+        app('LogService')->log('海柔','broadcast1',$id.$json);
+        $this->id = $id;// 0意味着通用站,所有站都需要收发的意思
+        $this->json = $json;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return Channel|array
+     */
+    public function broadcastOn()
+    {
+        app('LogService')->log('海柔','broadcast2',$this->id.$this->json);
+        return new Channel('station-'.$this->id);
+    }
+}

+ 36 - 0
app/Events/ClockinEvent.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Events;
+
+use App\LaborReport;
+use App\UserDutyCheck;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+use Illuminate\Queue\SerializesModels;
+
+
+class ClockinEvent implements ShouldBroadcastNow
+{
+    use  SerializesModels;
+
+    public $laborReport;
+
+    /**
+     * Create a new event instance.
+     * @param LaborReport $laborReport
+     */
+    public function __construct(LaborReport $laborReport)
+    {
+        $this->laborReport=$laborReport;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     */
+    public function broadcastOn(): Channel
+    {
+        return new Channel($this->laborReport->userWorkgroup->token);
+    }
+
+}

+ 36 - 0
app/Events/ClockoutEvent.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Events;
+
+use App\Http\Controllers\Controller;
+use App\LaborReport;
+use App\UserDutyCheck;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Queue\SerializesModels;
+
+
+class ClockoutEvent implements ShouldBroadcast
+{
+    use  SerializesModels;
+
+    public $laborReport;
+
+    /**
+     * Create a new event instance.
+     * @param LaborReport $laborReport
+     */
+    public function __construct(LaborReport $laborReport)
+    {
+        $this->laborReport=$laborReport;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     */
+    public function broadcastOn(): Channel
+    {
+        return new Channel($this->laborReport->userWorkgroup->token);
+    }
+
+}

+ 30 - 0
app/Events/CustomerStored.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Events;
+
+use App\Owner;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+
+class CustomerStored
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public $owner;
+
+    /**
+     * Create a new event instance.
+     * @param Owner $owner
+     * @return void
+     */
+    public function __construct(Owner $owner)
+    {
+        $this->owner=$owner;
+    }
+
+}

+ 67 - 0
app/Events/DeliveryAppointmentEvent.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Events;
+
+use App\DeliveryAppointment;
+use App\DeliveryAppointmentCar;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class DeliveryAppointmentEvent implements ShouldBroadcastNow
+{
+    use Dispatchable, SerializesModels;
+
+    public $delivery;
+    /**
+     * Create a new event instance.
+     *
+     * @param DeliveryAppointmentCar|\stdClass $delivery
+     *
+     * @return void
+     */
+    public function __construct(DeliveryAppointmentCar $delivery)
+    {
+        $delivery->load(["deliveryAppointment"=>function($query){
+            /** @var Builder $query */
+            $query->withCount("cars");
+        }]);
+
+        $owner = $delivery->deliveryAppointment->owner->name ?? "";
+        $len = mb_strlen($owner);
+        $ownerName = "";
+        for($i=0;$i<$len-1;$i++)$ownerName .= "*";
+        $ownerName .= mb_substr($owner,$len-1,1);
+
+        $count = $delivery->deliveryAppointment->cars_count ?? 0;
+        $delivery->warehouse = $delivery->deliveryAppointment->warehouse_id ?? "";
+        $delivery->cubic_meter = isset($delivery->deliveryAppointment->cubic_meter) && $delivery->deliveryAppointment->cubic_meter>0 ? ($count>1 ? $delivery->deliveryAppointment->cubic_meter."/".$count : $delivery->deliveryAppointment->cubic_meter) : "";
+        $delivery->tonne = isset($delivery->deliveryAppointment->tonne) && $delivery->deliveryAppointment->tonne>0 ? ($count>1 ? $delivery->deliveryAppointment->tonne."/".$count : $delivery->deliveryAppointment->tonne) : "";
+        $delivery->license_plate_number = $delivery->license_plate_number ? $delivery->license_plate_number : substr($delivery->appointment_number,0,5)."****".substr($delivery->appointment_number,9,1);
+        $delivery->owner_name = $ownerName;
+        $delivery->status = DeliveryAppointmentCar::STATUS[$delivery->status];
+        $delivery->type = DeliveryAppointment::TYPE[$delivery->deliveryAppointment->type_mark] ?? '';
+        $delivery->period = isset($delivery->deliveryAppointment->date_period) ? ($delivery->deliveryAppointment->date_period==0 ? '上午' : '下午') : '';
+        $delivery->delivery_time = $delivery->delivery_time ? substr($delivery->delivery_time,11,5) : '';
+
+        $delivery->morrow = $delivery->deliveryAppointment->appointment_date != date('Y-m-d'/*,strtotime("+1 day")*/);
+        $this->delivery = $delivery->withoutRelations();
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new Channel('delivery');
+    }
+
+    public function broadcastAs()
+    {
+        return "car";
+    }
+}

+ 38 - 0
app/Events/ExportEvent.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace App\Events;
+
+use App\LaborReport;
+use App\UserDutyCheck;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Queue\SerializesModels;
+
+
+class ExportEvent implements ShouldBroadcast
+{
+    use  SerializesModels;
+
+    public $laborReport;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct(LaborReport $laborReport)
+    {
+        $this->laborReport=$laborReport;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new Channel('laborReport');
+    }
+
+}

+ 47 - 0
app/Events/GitPushedEvent.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class GitPushedEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public $email;
+    /**
+     * [
+     *  'title'=>''
+     *  'description'='信息'
+     * ]
+     */
+    public $load;
+
+    /**
+     * GitPushedEvent constructor.
+     * @param $email
+     * @param $load
+     */
+    public function __construct($email, $load)
+    {
+        $this->email = $email;
+        $this->load = $load;
+    }
+
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 37 - 0
app/Events/GuardAuditEvent.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Events;
+
+use App\UserDutyCheck;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+use Illuminate\Queue\SerializesModels;
+
+
+class GuardAuditEvent implements ShouldBroadcastNow
+{
+    use  SerializesModels;
+
+    public $userDutyCheck;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct(UserDutyCheck $userDutyCheck)
+    {
+        $this->userDutyCheck=$userDutyCheck;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new Channel('userDutyCheck');
+    }
+
+}

+ 40 - 0
app/Events/ImportEvent.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Events;
+
+use App\LaborReport;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+use Illuminate\Queue\SerializesModels;
+
+
+class ImportEvent implements ShouldBroadcastNow
+{
+    use  SerializesModels;
+
+    public $laborReport;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct(LaborReport $laborReport)
+    {
+        $this->laborReport=$laborReport;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        $tokenOfBroadcastEnterAndLeave=LaborReport::tokenOfBroadcastEnterAndLeave();
+        return new Channel($tokenOfBroadcastEnterAndLeave);
+        //return new Channel('laborReport');
+    }
+
+}

+ 31 - 0
app/Events/InformWMSReceivedEvent.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Events;
+
+use App\Http\Controllers\Controller;
+use App\Listeners\InformWMSReceivedListener;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Support\Facades\Auth;
+
+class InformWMSReceivedEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public $rejectedBill;
+    public function __construct($rejectedBill)
+    {
+        $this->rejectedBill=$rejectedBill;
+    }
+    public function directRun()
+    {
+        if(config('api.jianshang_rejecteds_log_switch'))Controller::logS(__METHOD__,__FUNCTION__,'直接调用推送WMS事件,退单号:'.$this->rejectedBill['logistic_number_return'],Auth::user()['id']);
+        return (new InformWMSReceivedListener())->handle($this);
+    }
+
+}
+
+
+//通知WMS接收
+

+ 29 - 0
app/Events/ModelChangedEvent.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Events;
+
+use App\LaborReport;
+use App\UserDutyCheck;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Queue\SerializesModels;
+
+
+class ModelChangedEvent
+{
+    use  SerializesModels;
+
+    public $model;
+
+    /**
+     * Create a new event instance.
+     *
+     * @param Model $model
+     */
+    public function __construct(Model $model)
+    {
+        $this->model=$model;
+    }
+
+}

+ 46 - 0
app/Events/OrderIssueProcessLogCreateEvent.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class OrderIssueProcessLogCreateEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public $orderPackageIds;
+    /**
+     * @var int
+     * 1 返回派件
+     * 2 已签收
+     */
+    public $status;
+
+    /**
+     * OrderIssueProcessLogCreateEvent constructor.
+     * @param array $orderPackageIds
+     * @param int $status
+     */
+    public function __construct(array $orderPackageIds, int $status)
+    {
+        $this->orderPackageIds = $orderPackageIds;
+        $this->status = $status;
+    }
+
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 24 - 0
app/Events/ResetProcessStatisticStartDateEvent.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Events;
+
+use App\Process;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class ResetProcessStatisticStartDateEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public $process;
+    /**
+     * Create a new event instance.
+     * @param Process $process
+     * @return void
+     */
+    public function __construct(Process $process)
+    {
+        $this->process = $process;
+    }
+}

+ 34 - 0
app/Events/SendEmailEvent.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class SendEmailEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    /**
+     * SendEmailEvent constructor.
+     */
+    public function __construct()
+    {
+    }
+
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 61 - 0
app/Events/SettlementBillCreateEvent.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Events;
+
+use App\OwnerLogisticFeeDetail;
+use App\OwnerStoreFeeDetail;
+use App\OwnerStoreOutFeeDetail;
+use App\OwnerWayBillFeeDetail;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+
+class SettlementBillCreateEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+    //快递费
+    const OWNER_LOGISTIC_FEE_DETAIL = OwnerLogisticFeeDetail::class;
+    //入库费
+    const OWNER_STORE_FEE_DETAIL = OwnerStoreFeeDetail::class;
+    //出库
+    const OWNER_STORE_OUT_FEE_DETAIL = OwnerStoreOutFeeDetail::class;
+    //物流费
+    const OWNER_WAY_BILL_FEE_DETAIL = OwnerWayBillFeeDetail::class;
+
+    public $createData;
+
+    /**
+     * OWNER_LOGISTIC_FEE_DETAIL
+     * OWNER_STORE_FEE_DETAIL
+     * OWNER_STORE_OUT_FEE_DETAIL
+     * OWNER_WAY_BILL_FEE_DETAIL
+     */
+    public $modelName;
+
+    /**
+     * SettlementBillCreateEvent constructor.
+     * @param array $createData
+     * @param string $modelName
+     */
+    public function __construct(array $createData, string $modelName)
+    {
+        $this->createData = $createData;
+        $this->modelName = $modelName;
+    }
+
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 39 - 0
app/Events/TeamAuditEvent.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Events;
+
+use App\LaborReport;
+use App\UserDutyCheck;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+use Illuminate\Queue\SerializesModels;
+
+
+class TeamAuditEvent implements ShouldBroadcastNow
+{
+    use  SerializesModels;
+
+    public $laborReport;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct(LaborReport $laborReport)
+    {
+        $this->laborReport=$laborReport;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new Channel('laborReport');
+    }
+
+}

+ 41 - 0
app/Events/UpdateOrderPackageExceptionListenerEvent.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class UpdateOrderPackageExceptionListenerEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    /**
+     * @var $order_package_ids array
+     */
+    public $order_package_ids;
+
+    /**
+     * UpdateOrderPackageExceptionListenerEvent constructor.
+     * @param $order_package_ids
+     */
+    public function __construct($order_package_ids)
+    {
+        $this->order_package_ids = $order_package_ids;
+    }
+
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 36 - 0
app/Events/WaybillPriceModelEvent.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Events;
+
+use App\WaybillPriceModel;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Broadcasting\PrivateChannel;
+
+class WaybillPriceModelEvent
+{
+    use  SerializesModels;
+
+    public $waybillPriceModel;
+
+    /**
+     * Create a new event instance.
+     *
+     * @param WaybillPriceModel $waybillPriceModel
+     *
+     * @return void
+     */
+    public function __construct(WaybillPriceModel $waybillPriceModel)
+    {
+        $this->waybillPriceModel=$waybillPriceModel;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 36 - 0
app/Events/WeighedEvent.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Events;
+
+use App\OrderPackage;
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+use Illuminate\Queue\SerializesModels;
+
+class WeighedEvent implements ShouldBroadcastNow
+{
+    use  SerializesModels;
+
+    public $package;
+
+    /**
+     * Create a new event instance.
+     * @param OrderPackage $package
+     * @return void
+     */
+    public function __construct(OrderPackage $package)
+    {
+        $this->package=$package;
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new Channel('package');
+    }
+
+}

+ 25 - 0
app/Events/WmsReceiveNewEvent.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Events;
+
+use App\WMSReflectReceive;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Broadcasting\InteractsWithSockets;
+
+class WmsReceiveNewEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    public $logisticNumberReturn;
+//    public $downloadedSkuItems;
+    public $wmsReceive;
+
+    public function __construct(string $logisticNumberReturn,$wmsReceive)
+    {
+        $this->logisticNumberReturn=$logisticNumberReturn;
+//        $this->downloadedSkuItems=$downloadedSkuItems;
+        $this->wmsReceive=$wmsReceive;
+    }
+
+}

+ 16 - 0
app/Exceptions/ErrorException.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Exceptions;
+
+
+use Illuminate\Support\Facades\Auth;
+use Throwable;
+
+class ErrorException extends Exception
+{
+    public function __construct($message = "",  $code = 0, Throwable $previous = null)
+    {
+        parent::__construct($message,$type='error',$code, $previous);
+    }
+}

+ 45 - 0
app/Exceptions/Exception.php

@@ -0,0 +1,45 @@
+<?php
+
+
+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;
+        $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()??'')
+            .'调用堆栈e:'.$tracesAll,
+            Auth::id()??'',
+            $this->type
+        );
+    }
+}

+ 16 - 0
app/Exceptions/FatalException.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Exceptions;
+
+
+use Throwable;
+
+class FatalException extends Exception
+{
+
+    public function __construct($message = "",  $code = 0, Throwable $previous = null)
+    {
+        parent::__construct($message,$type='fatal',$code, $previous);
+    }
+}

+ 133 - 0
app/Exceptions/Handler.php

@@ -0,0 +1,133 @@
+<?php
+
+namespace App\Exceptions;
+
+use App\Log;
+use App\Services\LogService;
+use Exception;
+use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Validation\ValidationException;
+use Symfony\Component\ErrorHandler\Error\FatalError;
+use Throwable;
+
+class Handler extends ExceptionHandler
+{
+    /**
+     * A list of the exception types that are not reported.
+     *
+     * @var array
+     */
+    protected $dontReport = [
+        //
+    ];
+
+    /**
+     * A list of the inputs that are never flashed for validation exceptions.
+     *
+     * @var array
+     */
+    protected $dontFlash = [
+        'password',
+        'password_confirmation',
+    ];
+
+    /**
+     * Report or log an exception.
+     *
+     * @param Throwable $exception
+     * @return void
+     * @throws Exception|Throwable
+     */
+    public function report(Throwable $exception)
+    {
+        parent::report($exception);
+    }
+
+
+    public function render( $request, Throwable $exception)
+    {
+        $errMsg='';
+        try{
+            $type = $exception->type ?? 'error';
+            $errMsg=(function()use($request,$exception){
+                return $errMsg=
+                    '异常: '
+                    .' URL:'.(
+                    method_exists($request,'fullUrl')
+                        ?($request->fullUrl()??'')
+                        :'')
+                    .' method:'.(
+                    method_exists($request,'method')
+                        ?($request->method()??'')
+                        :'')
+                    .' params:'.(
+                    method_exists($request,'all')
+                        ?json_encode($request->all()??'')
+                        :'')
+                    .' errors:'.(
+                    method_exists($exception,'errors')
+                        ?(json_encode($exception->errors(),JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES)??'')
+                        :'')
+                    .' header:'.(
+                    method_exists($request,'header')
+                        ?json_encode($request->headers->all()??'')
+                        :'')
+                    .' code:'.(
+                    method_exists($exception,'getStatusCode')
+                        ?($exception->getStatusCode()??'')
+                        :'')
+                    .' message:'.(
+                    method_exists($exception,'getMessage')
+                        ?($exception->getMessage()??'')
+                        :'')
+                    .' trace:'.
+                    (method_exists($exception,'getTraceAsString')
+                        ?($exception->getTraceAsString()??'')
+                        :'');
+            })();
+            if($request->is("api/*")
+                && $exception instanceof ValidationException){
+                return response()->json($exception->errors(),200,[],JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
+            }
+            if(strpos($exception->getMessage(),'This action is unauthorized')!==false){
+                return response()->view('exception.unauthorized');
+            }
+            if (method_exists($exception,'getStatusCode')) {
+                $code = $exception->getStatusCode();
+                switch ($code){
+                    case 419: $view='exception.login';break;
+                    case 404:$view='exception.404';break;
+                    default: $view='exception.default';break;
+                }
+                return response()->view($view,[
+                    'code'=> $code,
+                    'message'=>$exception->getMessage(),
+                ]);
+            }
+        }catch (\Exception $e){}finally{
+            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,
+                ($errMsg??'')
+                .'请求:'.json_encode($request->all())
+                .'调用堆栈r:'.$tracesAll,
+                Auth::id()??'',
+                $type
+            );
+        }
+        return parent::render($request, $exception);
+    }
+}

+ 16 - 0
app/Exceptions/PanicException.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Exceptions;
+
+
+use Throwable;
+
+class PanicException extends Exception
+{
+
+    public function __construct($message = "", $code = 0, Throwable $previous = null)
+    {
+        parent::__construct($message,  $type='panic', $code,$previous = null);
+    }
+}

+ 16 - 0
app/Exceptions/WarningException.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Exceptions;
+
+
+use Throwable;
+
+class WarningException extends Exception
+{
+
+    public function __construct($message = "",  $code = 0, Throwable $previous = null)
+    {
+        parent::__construct($message,$type='warning',$code, $previous);
+    }
+}

+ 81 - 0
app/Exports/Export.php

@@ -0,0 +1,81 @@
+<?php
+namespace App\Exports;
+use Maatwebsite\Excel\Concerns\FromCollection;
+use Maatwebsite\Excel\Concerns\ShouldAutoSize;
+use Maatwebsite\Excel\Concerns\WithColumnFormatting;
+use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
+use Maatwebsite\Excel\Concerns\WithEvents;
+use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
+use Maatwebsite\Excel\Events\AfterSheet;
+use PhpOffice\PhpSpreadsheet\Cell\StringValueBinder;
+use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
+
+class Export extends StringValueBinder implements FromCollection,
+    ShouldAutoSize,WithColumnFormatting,WithCustomValueBinder,WithStrictNullComparison,WithEvents
+{
+    private $row;
+    private $data;
+    private $mergeCell;
+    private $columnName;
+    private $formatNumber;
+
+    /*
+     * $mergeCell $columnName :合并单元格所需参数;
+     * $mergeCell 需要合并的位置数组以MAP形式存储 [开始行=>结束行]
+     * $columnName 需要合并列 与合并行数结合使用ARRAY存储 ['A','B']
+     */
+    public function __construct($row,$data,$mergeCell=null,$columnName=null,$formatNumber=['D','H','I','L','O','Q','S','T','U','V'])
+    {
+        $this->row = $row;
+        $this->data = $data;
+        $this->mergeCell = $mergeCell;
+        $this->columnName = $columnName;
+        $this->formatNumber = $formatNumber;
+    }
+
+    public function collection()
+    {
+        $row = $this->row;
+        $data = $this->data;
+
+//设置表头
+        foreach ($row[0] as $key => $value) {
+            $key_arr[] = $key;
+        }
+
+//输入数据
+        foreach ($data as $key => &$value) {
+            $js = [];
+            for ($i=0; $i < count($key_arr); $i++) {
+                $js = array_merge($js,[ $key_arr[$i] => $value[ $key_arr[$i] ] ]);
+            }
+            array_push($row, $js);
+            unset($val);
+        }
+        return collect($row);
+    }
+    public function registerEvents(): array
+    {
+        if ($this->mergeCell && $this->columnName){
+            return [
+                AfterSheet::class => function(AfterSheet $event){
+                    foreach ($this->columnName as $column){
+                        foreach ($this->mergeCell as $key=>$value){
+                            $event->sheet->getDelegate()->mergeCells($column.$key.':'.$column.$value);
+                        }
+                    }
+                }
+            ];
+        }
+        return [];
+    }
+
+    public function columnFormats(): array{
+        $formatNumber = [];
+        foreach ($this->formatNumber as $column){
+            $formatNumber[$column] = NumberFormat::FORMAT_TEXT;
+        }
+        return $formatNumber;
+    }
+}
+

+ 24 - 0
app/Exports/InventoryBlindReceiveExcelExport.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Exports;
+
+use App\User;
+use Illuminate\Support\Collection;
+use Maatwebsite\Excel\Concerns\FromCollection;
+
+class InventoryBlindReceiveExcelExport implements FromCollection
+{
+    private $data;
+    public function __construct($data)
+    {
+        $this->data=new Collection($data);
+    }
+
+    /**
+    * @return \Illuminate\Support\Collection
+    */
+    public function collection()
+    {
+        return $this->data;
+    }
+}

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels