Browse Source

Merge branch 'master' into zzd

dream 5 years ago
parent
commit
99f35138f0
100 changed files with 3763 additions and 1223 deletions
  1. 44 0
      app/Console/Commands/SyncOrderPackageLogisticRouteTask.php
  2. 3 0
      app/Console/Kernel.php
  3. 35 0
      app/Events/SendEmailEvent.php
  4. 423 0
      app/Filters/OrderIssueFilters.php
  5. 93 0
      app/Filters/OrderPackageFilters.php
  6. 1 0
      app/Http/Controllers/LogisticController.php
  7. 1 1
      app/Http/Controllers/MeasureMonitorController.php
  8. 1 0
      app/Http/Controllers/OrderController.php
  9. 57 45
      app/Http/Controllers/OrderIssueController.php
  10. 36 0
      app/Http/Controllers/PackageLogisticController.php
  11. 17 5
      app/Http/Controllers/RejectedBillController.php
  12. 6 0
      app/Http/Controllers/RejectedBillItemController.php
  13. 75 0
      app/Http/Controllers/SendEmailsController.php
  14. 127 4
      app/Http/Controllers/TestController.php
  15. 4 4
      app/Http/Controllers/WeighController.php
  16. 79 79
      app/Http/Controllers/api/thirdPart/flux/SortingController.php
  17. 1 0
      app/Imports/RejectedImport.php
  18. 44 0
      app/Jobs/OrderPackageReceivedSync.php
  19. 63 0
      app/Listeners/SendEmailListener.php
  20. 23 0
      app/MailEvent.php
  21. 63 0
      app/Notifications/SendEmailNotification.php
  22. 17 0
      app/OracleDOCOrderHeader.php
  23. 15 2
      app/Order.php
  24. 57 97
      app/OrderIssue.php
  25. 16 1
      app/OrderPackage.php
  26. 1 4
      app/Policies/CustomerLogPolice.php
  27. 4 0
      app/Providers/AppServiceProvider.php
  28. 3 0
      app/Providers/EventServiceProvider.php
  29. 29 0
      app/Providers/LogisticProvider.php
  30. 25 6
      app/RejectedBill.php
  31. 206 0
      app/Services/LogisticSFService.php
  32. 32 0
      app/Services/LogisticZopService.php
  33. 16 2
      app/Services/OracleDOCOrderHeaderService.php
  34. 6 2
      app/Services/OracleDocWaveDetailService.php
  35. 0 4
      app/Services/OrderIssueRejectedBillService.php
  36. 12 301
      app/Services/OrderIssueService.php
  37. 137 0
      app/Services/OrderPackageReceivedSyncService.php
  38. 51 2
      app/Services/OrderPackageService.php
  39. 23 14
      app/Services/OrderService.php
  40. 6 10
      app/Services/PackageService.php
  41. 104 15
      app/Services/RejectedBillService.php
  42. 0 1
      app/Services/StationTaskCommodityService.php
  43. 1 0
      app/Services/WaybillService.php
  44. 6 0
      app/UserWorkgroup.php
  45. 23 0
      app/library/zop/README.md
  46. 61 0
      app/library/zop/ZopClient.php
  47. 20 0
      app/library/zop/ZopHttpUtil.php
  48. 46 0
      app/library/zop/ZopProperties.php
  49. 59 0
      app/library/zop/ZopRequest.php
  50. 60 0
      bashupMysql.sh
  51. 5 1
      composer.json
  52. 44 468
      composer.lock
  53. 110 0
      config/api_logistic.php
  54. 2 1
      database/factories/OracleActAllocationDetailsFactory.php
  55. 16 16
      database/factories/OrcaleDOCOrderHeaderFactory.php
  56. 13 0
      database/factories/OrderIssueRejectedBillFactory.php
  57. 32 0
      database/migrations/2020_12_16_114152_delete_status_to_order_package.php
  58. 45 0
      database/migrations/2020_12_16_114253_add_status_and_sent_and_at_and_received_at_and_execption_and_tarnsfer_status_and_remark_to_order_package.php
  59. 35 0
      database/migrations/2021_01_08_101028_create_notifications_table.php
  60. 36 0
      database/migrations/2021_01_08_110021_create_mail_events_table.php
  61. 33 0
      database/migrations/2021_01_08_110329_create_mail_event_role_table.php
  62. 43 0
      database/migrations/2021_01_08_110607_add_default_email.php
  63. 36 0
      database/migrations/2021_01_08_112003_add_default_mail_event_role.php
  64. 32 0
      database/migrations/2021_01_14_174209_create_order_issue_user_workgroup_table.php
  65. 32 0
      database/migrations/2021_01_15_175210_sync_order_issue_user_workgroup.php
  66. 29 0
      database/migrations/2021_01_19_151928_fix_order_package_status.php
  67. 61 0
      database/migrations/2021_01_20_145822_add_owner_id_to_order_packages.php
  68. 36 0
      database/migrations/2021_01_20_150801_add_authority_to_level_3_page.php
  69. 32 0
      database/migrations/2021_01_20_165051_add_orders_unique_to_column_code.php
  70. 32 0
      database/migrations/2021_01_22_104216_add_column_frozen_to_orders.php
  71. 7 19
      public/.htaccess
  72. 6 2
      resources/views/customer/menu.blade.php
  73. 5 5
      resources/views/customer/project/menu.blade.php
  74. 2 0
      resources/views/emails/test.blade.php
  75. 3 3
      resources/views/layouts/menu.blade.php
  76. 243 0
      resources/views/maintenance/emails/index.blade.php
  77. 12 0
      resources/views/maintenance/emails/menu.blade.php
  78. 4 0
      resources/views/maintenance/menu.blade.php
  79. 192 21
      resources/views/order/issue/index.blade.php
  80. 5 6
      resources/views/order/issue/recycle.blade.php
  81. 187 0
      resources/views/package/logistic/index.blade.php
  82. 4 1
      resources/views/package/measureMonitor/index.blade.php
  83. 1 1
      resources/views/package/measureMonitor/menu.blade.php
  84. 20 0
      resources/views/package/menu.blade.php
  85. 4 3
      resources/views/package/weigh/create.blade.php
  86. 3 2
      resources/views/package/weigh/index.blade.php
  87. 20 0
      resources/views/package/weigh/menu.blade.php
  88. 1 1
      resources/views/package/weigh/record/menu.blade.php
  89. 2 1
      resources/views/package/weigh/statistics.blade.php
  90. 0 0
      resources/views/package/weightExcepted/index.blade.php
  91. 0 0
      resources/views/package/weightExcepted/menu.blade.php
  92. 2 0
      resources/views/personnel/menu.blade.php
  93. 2 1
      resources/views/process/menu.blade.php
  94. 23 29
      resources/views/rejected/create.blade.php
  95. 4 2
      resources/views/store/blindReceive/menu.blade.php
  96. 19 4
      resources/views/waybill/index.blade.php
  97. 0 31
      resources/views/weight/menu.blade.php
  98. 3 1
      routes/apiLocal.php
  99. 28 5
      routes/web.php
  100. 25 0
      syncProject.sh

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

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\OrderPackageReceivedSyncService;
+use Illuminate\Console\Command;
+
+class SyncOrderPackageLogisticRouteTask extends Command
+{
+    /**
+     * 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()
+    {
+        ini_set('memory_limit','1226M');
+        (new OrderPackageReceivedSyncService)->syncLogisticRoute();
+    }
+}

+ 3 - 0
app/Console/Kernel.php

@@ -9,6 +9,7 @@ use App\Console\Commands\LogExpireDelete;
 use App\Console\Commands\MakeServiceCommand;
 use App\Console\Commands\SyncBatchTask;
 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;
@@ -37,6 +38,7 @@ class Kernel extends ConsoleKernel
         TestTemp::class,
         SyncBatchTask::class,
         SyncWMSOrderTask::class,
+        SyncOrderPackageLogisticRouteTask::class,
         SyncWmsCommoditiesInformation::class,
         ClearCancelledOrderTask::class,
         WasSyncWmsAsnInformation::class,
@@ -60,6 +62,7 @@ class Kernel extends ConsoleKernel
         $schedule->command('createOwnerAreaReport')->monthlyOn(1);
         $schedule->command('sync:batch')->everyMinute();
         $schedule->command('sync:order')->everyMinute();
+        $schedule->command('syncOrderPackageLogisticRouteTask')->dailyAt('1:20');//同步快递信息到orderPackage
         $schedule->command('SyncWmsCommoditiesInformation')->everyMinute();
         $schedule->command('clear:cancelledOrder')->everyTenMinutes();
         $schedule->command('WasSyncWmsAsnInformation')->everyMinute();

+ 35 - 0
app/Events/SendEmailEvent.php

@@ -0,0 +1,35 @@
+<?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');
+    }
+}

+ 423 - 0
app/Filters/OrderIssueFilters.php

@@ -0,0 +1,423 @@
+<?php
+
+
+namespace App\Filters;
+
+
+use App\Commodity;
+use App\Order;
+use App\OrderIssue;
+use App\OrderIssueProcessLog;
+use App\OrderIssueRejectedBill;
+use App\OrderPackage;
+use App\OrderPackageCommodities;
+use App\RejectedBill;
+use App\RejectedBillItem;
+use App\Shop;
+use App\UserWorkgroup;
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use PhpMyAdmin\Server\UserGroups;
+
+
+class OrderIssueFilters
+{
+    protected $request;
+    protected $queryBuilder;
+    protected $orderQuery;
+    protected $commodityQuery;
+    protected $orderPackageQuery;
+    protected $orderPackageCommodityQuery;
+    protected $orderIssueRejectedBIllQuery;
+    protected $rejectedBillQuery;
+    protected $rejectedBillItemQuery;
+    protected $orderIssueProcessLogQuery;
+    protected $shopQuery;
+    protected $filters = [
+        'log_content',
+        'is_imported',
+        'is_new_rejecting',
+        'logistic_id',
+        'custom_code',
+        'hiddenTag',
+        'client_code',
+        'consignee_name',
+        'consignee_phone',
+        'logistic_number',
+        'good_barcode',
+        'good_name',
+        'send_client_code',
+        'id_quality_label',
+        'id',
+        'created_at_start',
+        'created_at_end',
+        'order_issue_type_id',
+        'logistic_indemnity_money',
+        'baoshi_indemnity_money',
+        'rejectingStatus',
+        'order_issue_ids',
+        'settlement_at_start',
+        'settlement_at_end',
+        'sendOrderClientCode',
+        'sendOrderLogisticNumber',
+        'user_workgroups',
+        'shop_name',
+        'finance_confirm',
+        'logistic_number_return',
+        'final_status'
+    ];
+    protected $array_filter;
+    protected $params = [];
+
+    public function __construct(Request $request)
+    {
+        $this->request = $request;
+        $this->params = $request->all();
+        $this->array_filter = array_filter($this->request->only($this->filters));
+    }
+
+    private function getOrderQuery()
+    {
+        if(!$this->orderQuery)
+            $this->orderQuery = Order::query()->selectRaw('id');
+        return $this->orderQuery;
+    }
+
+    private function getCommodityQuery()
+    {
+        if(!$this->commodityQuery)
+            $this->commodityQuery = Commodity::query()->selectRaw('id');
+        return  $this->commodityQuery;
+    }
+
+    private function getOrderPackageQuery()
+    {
+        if(is_null($this->orderPackageQuery))
+            $this->orderPackageQuery = OrderPackage::query()->selectRaw('order_packages.order_id');
+        return $this->orderPackageQuery;
+    }
+
+    private function getRejectedBillQuery()
+    {
+        if(!$this->rejectedBillQuery)
+            $this->rejectedBillQuery= RejectedBill::query()->selectRaw('logistic_number_return');
+        return $this->rejectedBillQuery;
+    }
+
+    private function getRejectedBillItemQuery()
+    {
+        if(!$this->rejectedBillItemQuery)
+            $this->rejectedBillItemQuery =  RejectedBillItem::query()->selectRaw('id_rejected_bill');
+        return $this->rejectedBillItemQuery;
+    }
+
+    private function getOrderPackageCommodityQuery()
+    {
+        if(!$this->orderPackageCommodityQuery)
+            $this->orderPackageCommodityQuery = OrderPackageCommodities::query()->selectRaw('order_package_commodities.order_package_id');
+        return $this->orderPackageCommodityQuery;
+    }
+
+    private function getOrderIssueRejectedBillQuery()
+    {
+        if(!$this->orderIssueRejectedBIllQuery)
+            $this->orderIssueRejectedBIllQuery = OrderIssueRejectedBill::query()->selectRaw('order_issue_id');
+        return $this->orderIssueRejectedBIllQuery;
+    }
+
+    private function getOrderIssueProcessLogQuery()
+    {
+        if(!$this->orderIssueProcessLogQuery)
+            $this->orderIssueProcessLogQuery = OrderIssueProcessLog::query()->selectRaw('order_issue_id');
+        return $this->orderIssueProcessLogQuery;
+    }
+
+    private function getShopQuery()
+    {
+        if(!$this->shopQuery)
+            $this->shopQuery = Shop::query()->selectRaw('id');
+        return $this->shopQuery;
+    }
+
+    public function apply($builder)
+    {
+        $this->queryBuilder = $builder;
+        $this->beforeApply();
+        foreach ($this->array_filter as $filter => $value) {
+            if (method_exists($this, $filter)) {
+                $this->$filter($value, $this->queryBuilder);
+            }
+        }
+        $this->afterApply();
+        return $this->queryBuilder;
+    }
+
+    private function beforeApply()
+    {
+        if(empty($this->params['hidden_tag']))
+            $this->queryBuilder->whereNull('order_issues.hidden_tag');
+
+        if(isset($this->params['data'])){
+            $ids = explode(',',$this->params['data']);
+            $this->id($ids);
+        }elseif(!($this->params['is_handle'] ?? false) && !($this->params['final_status'] ?? false)){
+            if(!(isset($this->params['settlement_at_start']) || isset($this->params['settlement_at_end']))) {
+                $this->queryBuilder->where(function ($query) {
+                    $query->whereNotIn('order_issues.final_status', ['已解决', '已归档'])->orWhereNull('order_issues.final_status');
+                });
+            }
+        }
+
+        $user = Auth::user();
+        $owner_ids = $user ? app('UserService')->getPermittingOwnerIds($user) : [];
+        if (isset($this->params['owner_id'])){
+            $this->searchWay($this->getOrderQuery(),$this->params['owner_id'],'orders.owner_id');
+        } else{
+            $this->getOrderQuery()->whereIn('owner_id',$owner_ids);
+        }
+    }
+
+    public function afterApply()
+    {
+        if($this->commodityQuery)
+            $this->getOrderPackageCommodityQuery()->whereIn('commodity_id',$this->commodityQuery);
+
+        if($this->orderPackageCommodityQuery)
+            $this->getOrderPackageQuery()->whereIn('order_packages.id',$this->orderPackageCommodityQuery);
+
+        if($this->orderPackageQuery)
+            $this->getOrderQuery()->whereIn('order_id',$this->orderPackageQuery);
+
+        if($this->shopQuery)
+            $this->getOrderQuery()->whereIn('shop_id',$this->shopQuery);
+
+        if($this->orderQuery)
+            $this->queryBuilder->whereIn('order_issues.order_id',$this->orderQuery);
+
+        if($this->rejectedBillItemQuery)
+            $this->getRejectedBillQuery()->whereIn('id',$this->rejectedBillItemQuery);
+
+        if($this->rejectedBillQuery)
+            $this->getOrderIssueRejectedBIllQuery()->whereIn('logistic_number_return',$this->rejectedBillQuery);
+
+        if($this->orderIssueRejectedBIllQuery)
+            $this->queryBuilder->whereIn('order_issues.id',$this->orderIssueRejectedBIllQuery);
+
+        if($this->orderIssueProcessLogQuery)
+            $this->queryBuilder->whereIn('order_issues.id',$this->orderIssueProcessLogQuery);
+
+    }
+
+    private function isSearchLike($str)
+    {
+        if (substr($str, 0, 1) == "%" || substr($str, strlen($str) - 1, 1) == "%") {
+            return true;
+        }
+        return false;
+    }
+
+    private function searchWay($query, $param, $column)
+    {
+        if ($this->isSearchLike($param)) {
+            $query->where($column, 'like', $param);
+        } else {
+            $query->whereIn($column, array_filter(preg_split('/[,, ]+/is', $param)));
+        }
+        return $query;
+    }
+
+    public function log_content($log_content)
+    {
+        $order_issue_process_log_query = OrderIssueProcessLog::query()->selectRaw('order_issue_id')->where('content','like',$log_content);
+        if(!$this->params['addtime']){
+            $order_issue_process_log_query->where('created_at', '>=', Carbon::now()->subDays(31));
+        }else{
+            $order_issue_process_log_query->where('created_at', '>=', Carbon::now()->subDays($this->params['addtime']));
+        }
+        $this->queryBuilder->whereIn('order_issues.id',$order_issue_process_log_query);
+    }
+
+    public function is_imported($is_imported)
+    {
+        $this->queryBuilder->where('order_issues.imported_status',$is_imported);
+    }
+
+    public function is_new_rejecting($is_new_rejecting)
+    {
+        $this->queryBuilder->where('order_issues.is_new_rejecting',$is_new_rejecting);
+    }
+
+    public function logistic_id($logistic_id)
+    {
+        $this->getOrderQuery()->where('orders.logistic_id',$logistic_id);
+    }
+
+    public function custom_code($custom_code)
+    {
+        $this->queryBuilder->where('order_issues.custom_code',$custom_code);
+    }
+
+    public function hiddenTag($hiddenTag)
+    {
+        $this->queryBuilder->where('order_issues.hidden_tag',$hiddenTag);
+    }
+
+    public function client_code($client_code)
+    {
+        $this->searchWay($this->getOrderQuery(),$client_code,'orders.client_code');
+    }
+
+    public function consignee_name($consignee_name)
+    {
+        $this->searchWay($this->getOrderQuery(),$consignee_name,'orders.consignee_name');
+    }
+
+    public function consignee_phone($consignee_name)
+    {
+        $this->searchWay($this->getOrderQuery(),$consignee_name,'orders.consignee_phone');
+    }
+
+    public function logistic_number($logistic_number)
+    {
+        $this->searchWay($this->getOrderPackageQuery(),$logistic_number,'logistic_number');
+    }
+
+    public function good_barcode($good_barcode)
+    {
+        $this->searchWay($this->getCommodityQuery(),$good_barcode,'sku');
+    }
+
+    public function good_name($good_name)
+    {
+        $this->searchWay($this->getCommodityQuery(),$good_name,'name');
+    }
+
+    public function send_client_code($send_client_code)
+    {
+        $this->searchWay($this->queryBuilder,$send_client_code,'order_issues.second_client_no');
+    }
+
+    public function logistic_number_return($logistic_number_return)
+    {
+        $this->searchWay($this->getOrderIssueRejectedBillQuery(),$logistic_number_return,'logistic_number_return');
+     }
+
+    public function id_quality_label($id_quality_label)
+    {
+        $this->getRejectedBillItemQuery()->where('id_quality_label',$id_quality_label);
+    }
+
+    public function id($id)
+    {
+        $this->queryBuilder->whereIn('order_issues.id',$id);
+    }
+
+    public function created_at_start($created_at_start)
+    {
+        $this->queryBuilder->where('order_issues.created_at', '>=', $created_at_start . " 00:00:00");
+    }
+
+    public function created_at_end($created_at_end)
+    {
+        $this->queryBuilder->where('order_issues.created_at', '<=', $created_at_end . " 23:59:59");
+    }
+
+    public function order_issue_type_id($order_issue_type_id)
+    {
+        $this->searchWay($this->queryBuilder,$order_issue_type_id,'order_issues.order_issue_type_id');
+    }
+
+    public function logistic_indemnity_money($logistic_indemnity_money)
+    {
+        if($logistic_indemnity_money==='是')
+            $this->queryBuilder->whereNotNull('order_issues.logistic_indemnity_money');
+        elseif($logistic_indemnity_money==='否')
+            $this->queryBuilder->whereNull('order_issues.logistic_indemnity_money');
+    }
+
+    public function baoshi_indemnity_money($baoshi_indemnity_money)
+    {
+        if($baoshi_indemnity_money==='是')
+            $this->queryBuilder->whereNotNull('order_issues.baoshi_indemnity_money');
+        elseif($baoshi_indemnity_money==='否')
+            $this->queryBuilder->whereNull('order_issues..baoshi_indemnity_money');
+    }
+
+    public function rejectingStatus($rejectingStatus)
+    {
+        $this->queryBuilder->where('order_issues.rejecting_status',$rejectingStatus);
+    }
+
+    public function order_issue_ids($order_issue_ids)
+    {
+        $this->searchWay($this->queryBuilder,$order_issue_ids,'order_issues.id');
+    }
+
+    public function settlement_at_start($settlement_at_start)
+    {
+        $this->getOrderIssueProcessLogQuery()->where('created_at','>=',$settlement_at_start.' 00:00:00')->where('type','结束');
+    }
+
+    public function settlement_at_end($settlement_at_end)
+    {
+        $this->getOrderIssueProcessLogQuery()->where('created_at','<=',$settlement_at_end.' 23:59:59')->where('type','结束');
+    }
+
+    public function sendOrderClientCode($sendOrderClientCode)
+    {
+        $this->searchWay($this->queryBuilder,$sendOrderClientCode,'order_issues.second_client_no');
+    }
+
+    public function user_workgroups($user_work_groups)
+    {
+        if(is_string($user_work_groups)){
+            $user_work_groups = explode(',', $user_work_groups);
+        }
+        $this->queryBuilder->whereIn('order_issues.id',function($query)use($user_work_groups){
+            $query->from('order_issue_user_workgroup')->selectRaw('order_issue_id')->whereIn('user_workgroup_id',$user_work_groups);
+        });
+    }
+
+    public function sendOrderLogisticNumber($sendOrderLogisticNumber)
+    {
+        $order_issue_query = OrderIssue::query()->selectRaw('id');
+        $this->searchWay($order_issue_query,$sendOrderLogisticNumber,'second_logistic_number');
+        $order_issues = $order_issue_query->get();
+        if(count($order_issues)>0){
+            $this->queryBuilder->where('order_issues.id',$order_issues->map(function($orderIssue){
+                return $orderIssue->id;
+            }));
+        }
+        $orders = Order::query()->selectRaw('client_code')->whereIn('id',function($query)use($sendOrderLogisticNumber){
+            $query->from('order_packages')->selectRaw('order_id');
+            $this->searchWay($query,$sendOrderLogisticNumber,'logistic_number');
+        })->get();
+         if($orders->count()>0){
+            $this->queryBuilder->where('order_issues.second_client_no',$orders->map(function($order){
+                return $order->client_code;
+            }));
+        }
+    }
+
+    public function shop_name($shop_name)
+    {
+        $this->searchWay($this->getShopQuery(),$shop_name,'name');
+        if (isset($this->params['shop_name_limit_time'])) {
+            $this->queryBuilder->Where('order_issues.created_at','>=', Carbon::now()->subDays($this->params['shop_name_limit_time']));
+        } else {
+            $this->queryBuilder->Where('order_issues.created_at','>=', Carbon::now()->subDays(31));
+        }
+    }
+
+    public function final_status($final_status)
+    {
+        $this->queryBuilder->where('order_issues.final_status',$final_status);
+    }
+
+    public function finance_confirm($finance_confirm)
+    {
+        $this->queryBuilder->where('order_issues.finance_confirm',$finance_confirm);
+    }
+
+}

+ 93 - 0
app/Filters/OrderPackageFilters.php

@@ -0,0 +1,93 @@
+<?php
+
+
+namespace App\Filters;
+
+use App\Order;
+use App\Services\UserService;
+use Illuminate\Http\Request;
+use phpDocumentor\Reflection\Types\Boolean;
+
+class OrderPackageFilters
+{
+    protected $request;
+    protected $queryBuilder;
+    protected $filters = ['logistic_number', 'status', 'received_at_start',
+        'received_at_end', 'is_weighed', 'logistic_id', 'owner_id', 'sent_at_start', 'sent_at_end', 'is_exception'];
+
+    public function __construct(Request $request)
+    {
+        $this->request = $request;
+    }
+
+    public function apply($builder)
+    {
+        $this->queryBuilder = $builder;
+        $filters = array_filter($this->request->only($this->filters));
+        foreach ($filters as $filter => $value) {
+            if (method_exists($this, $filter)) {
+                $this->$filter($value, $this->queryBuilder);
+            }
+        }
+        return $this->queryBuilder;
+    }
+
+
+    private function logistic_number($logistic_number)
+    {
+        $this->queryBuilder->where('logistic_number', $logistic_number);
+    }
+
+    private function status($status)
+    {
+        $this->queryBuilder->where('status', $status);
+    }
+
+    private function received_at_start($received_at_start)
+    {
+        $this->queryBuilder->where('received_at', '>=', $received_at_start);
+    }
+
+    private function received_at_end($received_at_end)
+    {
+        $this->queryBuilder->where('received_at', '<=', $received_at_end);
+    }
+
+    private function is_weighed($is_weighed)
+    {
+        if ($is_weighed == 'true') {
+            $this->queryBuilder->whereNotNull('weighed_at');
+        } else {
+            $this->queryBuilder->whereNull('weighed_at');
+        }
+    }
+
+    private function logistic_id($logistic_id)
+    {
+        $logistic_ids = array_filter(preg_split('/[,, ]+/is', $logistic_id));
+        $this->queryBuilder->whereIn('order_id',function($query)use($logistic_ids){
+            $query->from('orders')->select('id')->whereIn('logistic_id',$logistic_ids);
+        });
+    }
+
+    private function owner_id($owner_id)
+    {
+        $owner_ids = array_filter(preg_split('/[,, ]+/is', $owner_id));
+        $this->queryBuilder->whereIn('owner_id', $owner_ids);
+    }
+
+    private function sent_at_start($sent_at_start)
+    {
+        $this->queryBuilder->where('sent_at', '>=', $sent_at_start);
+    }
+
+    private function sent_at_end($sent_at_end)
+    {
+        $this->queryBuilder->where('sent_at', '<=', $sent_at_end);
+    }
+
+    private function is_exception($is_exception)
+    {
+        $this->queryBuilder->where('exception', $is_exception);
+    }
+}

+ 1 - 0
app/Http/Controllers/LogisticController.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers;
 
 use App\Logistic;
+use App\Services\UserService;
 use Exception;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;

+ 1 - 1
app/Http/Controllers/MeasureMonitorController.php

@@ -17,7 +17,7 @@ class MeasureMonitorController extends Controller
     {
         $measuringMachines=MeasuringMachine::query()->select('id','name','code','status')->get();
         $laravelEchoPrefix = config('database.redis.options.prefix');
-        return view('weight.measureMonitor.index',compact('laravelEchoPrefix','measuringMachines'));
+        return view('package.measureMonitor.index',compact('laravelEchoPrefix','measuringMachines'));
     }
 
     public function data(Request $request){

+ 1 - 0
app/Http/Controllers/OrderController.php

@@ -138,6 +138,7 @@ sql;
         $rejectedBillItemService->insert($rejectedBillItems);
         LogService::log(__METHOD__,"批量生成退货单详情",json_encode($rejectedBillItems),Auth::user()['id']);
         $rejectedBill_collect->each(function($rejectedBill)use($rejectedBillService){
+            $rejectedBillService->joinOrderIssue($rejectedBill);
             $rejectedBillService->syncOrderIssue($rejectedBill);
         });
         return ['success'=>true];

+ 57 - 45
app/Http/Controllers/OrderIssueController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Filters\OrderIssueFilters;
 use App\Imports\OrderIssueImport;
 use App\Logistic;
 use App\OracleDOCOrderHeader;
@@ -20,11 +21,10 @@ use App\Services\OwnerService;
 use App\Shop;
 use App\UserWorkgroup;
 use Exception;
+use Illuminate\Database\QueryException;
 use Illuminate\Http\Request;
-use Illuminate\Support\Arr;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
-use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Validator;
@@ -33,7 +33,7 @@ use Maatwebsite\Excel\Facades\Excel;
 class OrderIssueController extends Controller
 {
 
-    public function index(Request $request)
+    public function index(Request $request, OrderIssueFilters $filter)
     {
         if (!Gate::allows('订单管理-问题件-查询')) {
             return redirect(url('/'));
@@ -41,7 +41,7 @@ class OrderIssueController extends Controller
         /** @var OrderIssueService $orderIssueService */
         $orderIssueService = app('OrderIssueService');
         $owners = app(OwnerService::class)->getAuthorizedOwners();
-        $orderIssues = $orderIssueService->paginate($request->all());
+        $orderIssues = OrderIssue::query()->filter($filter)->defaultWith()->paginate($request['paginate'] ?? 50);
         $orderIssueType = OrderIssueType::all();
         $qualityLabel = QualityLabel::all();
         $logistics = Logistic::all();
@@ -377,32 +377,6 @@ class OrderIssueController extends Controller
         }
     }
 
-    public function updateLogisticNumberReturnApi(Request $request){
-        if (!Gate::allows('订单管理-问题件-编辑')) {
-            return ['success'=>false,'fail_info' => '没有对应权限'];
-        }
-        try {
-            /** @var OrderIssue $orderIssue */
-            $orderIssue = OrderIssue::query()->where('id',$request->input('id'))->first();
-            $rejectedBill = RejectedBill::query()
-                ->with('items')
-                ->where('logistic_number_return',$request->input('logisticNumberReturn'))
-                ->first();
-            app('LogService')->log(__METHOD__, __FUNCTION__, json_encode($request->getContent()));
-            if(!$rejectedBill){
-                $orderIssue->update(['logistic_number_return' => $request->input('logisticNumberReturn')]);
-                return ['success' => false, 'message' => '退回单号已修改,退回单号没有相应退件信息'];
-            }else{
-                $orderIssue->update(['logistic_number_return' => $request->input('logisticNumberReturn'),'is_new_rejecting' => '有']);
-                $orderIssue->同步退单状态();
-                return ['success' => true, 'rejectedBill' => $rejectedBill,'rejectingStatus' =>$orderIssue->rejecting_status];
-            }
-        } catch (Exception $e) {
-            app('LogService')->log(__METHOD__, __FUNCTION__,'error'. json_encode($request->getContent()).'||'.$e->getMessage().'||'.$e->getTraceAsString());
-            return ['success' => false ,'fail_info' => $e->getMessage()];
-        }
-    }
-
     public function apiUpdateValidator(array $arr)
     {
         return Validator::make($arr, [
@@ -595,22 +569,12 @@ class OrderIssueController extends Controller
         }
     }
 
-    public function exportJsonExcel(Request $request)
+    public function exportJsonExcel(Request $request, OrderIssueFilters $filter)
     {
         if (!Gate::allows('订单管理-问题件-查询')) {
             return redirect(url('/'));
         }
-        $params = $request->input();
-        if ($request->checkAllSign){
-            $params = $request->input();
-            unset($params['checkAllSign']);
-        }else{
-            $params['id'] = $request['data'];
-            $params['is_handle'] = true;
-        }
-        /** @var OrderIssueService $service */
-        $service = app('OrderIssueService');
-        $order_Issues  = $service->getJsonObj($params);
+        $order_Issues = OrderIssue::query()->filter($filter)->jsonWith()->get();
         return $this->getJson($order_Issues);
     }
 
@@ -675,7 +639,10 @@ class OrderIssueController extends Controller
                     $send_order_amount.=$commodities->amount.",\r\n";
                 });
             });
-
+            $userWorkgroupsName = '';
+            $order_issue->userWorkgroups->each(function ($userWorkgroup)use (&$userWorkgroupsName) {
+                $userWorkgroupsName.=($userWorkgroup->name).",\r\n";
+            });
             $json[] = [
                 isset($order_issue->created_at) ? str_split($order_issue->created_at,10)[0] :'',       // 登记日期
                 isset($order->created_at) ? str_split($order->created_at,10)[0] :'',             // 创建日期
@@ -727,7 +694,7 @@ class OrderIssueController extends Controller
                 $order_issue->logistic_express_remission,
                 $order_issue->baoshi_indemnity_money,
                 $order_issue->baoshi_express_remission,
-                $order_issue->userWorkGroup->name ?? '',
+                rtrim($userWorkgroupsName,",\r\n")
             ];
         }
         $mergeColumn = ['A','B','C','D','E','F','G','H','I','J','K','L','P','T','X','Y','Z','AA','AF','AG','AH','AI','AJ','AK'];   // 合并行
@@ -766,7 +733,7 @@ class OrderIssueController extends Controller
             return ['success'=>false,'error'=>'没有对应权限'];
         }
         try {
-            $bool = OrderIssue::query()->whereIn('id', $request['ids'])->update(['finance_confirm' => '是']);
+            $bool = OrderIssue::query()->whereIn('id', $request['ids'])->update(['finance_confirm' => $request->flag]);
             if($bool==false)return ['success'=>false,'error'=>'财务确认失败'];
             app('LogService')->log(__METHOD__, __FUNCTION__,'财务确认'. json_encode($request->getContent()), Auth::user()['id']);
             return ['success'=>true];
@@ -794,4 +761,49 @@ class OrderIssueController extends Controller
         return ['success' =>true];
     }
 
+    public function addUserWorkgroup(Request $request)
+    {
+        $orderIssueId = $request->orderIssueId;
+        $userWorkgroupId = $request->userWorkgroupId;
+        try {
+            OrderIssue::query()->find($orderIssueId)->userWorkgroups()->attach($userWorkgroupId);
+        } catch (QueryException $e) {
+            return ['success' => false,'data' =>'事故责任方已存在'];
+        }
+        return ['success' => true,'data' =>UserWorkgroup::find($userWorkgroupId)];
+    }
+    public function destroyUserWorkgroup(Request $request)
+    {
+        $orderIssueId = $request->orderIssueId;
+        $userWorkgroupId = $request->userWorkgroupId;
+        OrderIssue::query()->find($orderIssueId)->userWorkgroups()->detach($userWorkgroupId);
+        return ['success' => true,'data' =>UserWorkgroup::find($userWorkgroupId)];
+    }
+
+    public function batchOthers(Request $request)
+    {
+        $orderIssueIds = $request->input("orderIssueIds");
+        $data = [];
+        if ($request->input("logistic_indemnity_money")) {
+            $data['logistic_indemnity_money'] = $request->input("logistic_indemnity_money");
+        }
+        if ($request->input("logistic_express_remission")) {
+            $data['logistic_express_remission'] = $request->input("logistic_express_remission");
+        }
+        if ($request->input("baoshi_indemnity_money")) {
+            $data['baoshi_indemnity_money'] = $request->input("baoshi_indemnity_money");
+        }
+        if ($request->input("baoshi_express_remission")) {
+            $data['baoshi_express_remission'] = $request->input("baoshi_express_remission");
+        }
+        OrderIssue::query()->whereIn('id',$orderIssueIds)->update($data);
+        $userWorkGroupIds = $request->input("userWorkGroupIds");
+        if (isset($userWorkGroupIds)) {
+            $orderIssues = OrderIssue::query()->whereIn('id', $orderIssueIds)->get();
+            foreach ($orderIssues as $orderIssue) {
+                $orderIssue->userWorkGroups()->sync($userWorkGroupIds);
+            }
+        }
+        return ['success' => true];
+    }
 }

+ 36 - 0
app/Http/Controllers/PackageLogisticController.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Filters\OrderPackageFilters;
+use App\Logistic;
+use App\OrderPackage;
+use App\Owner;
+use App\Services\UserService;
+use Illuminate\Http\Request;
+
+class PackageLogisticController extends Controller
+{
+    /**
+     * PackageLogisticsController constructor.
+     */
+    public function __construct()
+    {
+        $this->middleware('auth');
+    }
+
+    public function index(Request $request,OrderPackageFilters $filters)
+    {
+        /** @var UserService $userService */
+        $userService = app('UserService');
+        $owner_ids = $userService->getPermittingOwnerIds(auth()->user());
+        $paginateParams = $request->input();
+        $orderPackages = OrderPackage::query()->filter($filters)
+            ->whereIn('owner_id',$owner_ids)->with(['order' => function ($query) {
+            $query->with(['logistic', 'owner', 'packages.commodities']);
+        }])->orderByDesc('id')->paginate($request->paginate ?? 50);
+        $logistics = Logistic::all();
+        $owners = Owner::find($owner_ids);
+        return view('package.logistic.index', compact('orderPackages', 'logistics', 'owners','paginateParams'));
+    }
+}

+ 17 - 5
app/Http/Controllers/RejectedBillController.php

@@ -8,6 +8,7 @@ use App\Logistic;
 use App\OracleActAllocationDetails;
 use App\OracleBasSKU;
 use App\OracleDOCOrderHeader;
+use App\Order;
 use App\Owner;
 use App\QualityLabel;
 use App\Rejected;
@@ -100,7 +101,7 @@ class RejectedBillController extends Controller
          * @var RejectedBillService $rejectedBillService
          */
         $rejectedBillService=app(RejectedBillService::class);
-        $rejectedBillService->syncOrderIssue($rejectedBill);
+        $rejectedBillService->joinOrderIssue($rejectedBill);
         $rejectedBillService->updateCheckedStatusByWms($request->input('logistic_number_return'));
 //        $rejectedBill->同步问题件退件状态();
 
@@ -293,10 +294,20 @@ class RejectedBillController extends Controller
         return ['success'=>'true','result'=>'true'];
     }
 
-    function seekOrder(Request $request){
-        if (!$request->soreference5)return ['success'=>false];
-        $order=OracleDOCOrderHeader::select('soreference1','customerid','c_contact','c_tel2','c_tel1','carrierid')->where('soreference5',$request->soreference5)->first();
-        if ($order)return ['success'=>true,'data'=>$order];
+    function seekOrder(Request $request)
+    {
+        if (!$request['logistic_number_return'])return ['success'=>false];
+        /** @var RejectedBillService $service */
+        $service = app('RejectedBillService');
+        $result = $service->findOrderByOrderPackage($request['logistic_number_return']);
+        if($result)return ['success' => true,'data' => $result];
+        $result = $service->findOrderByStoreRejected($request['logistic_number_return']);
+        if($result)return ['success' => true,'data' => $result];
+        $result = $service->findOrderByOrderHeader($request['logistic_number_return']);
+        if($result)return ['success' => true,'data' => $result];
+        $result = $service->findOrderByOrderIssue($request['logistic_number_return']);
+        if($result)return ['success' => true,'data' => $result];
+        else return ['success'=>false];
     }
 
     public function disposeImportApi(Request $request)
@@ -417,6 +428,7 @@ class RejectedBillController extends Controller
                 LogService::log(__METHOD__, "批量生成退货单详情", json_encode($inner_items_params), Auth::user()['id']);
             }
             $rejectedBill_collect->each(function ($rejectedBill)use($service){
+                $service->joinOrderIssue($rejectedBill);
                 $service->syncOrderIssue($rejectedBill);
             });
             return ['success'=>true];

+ 6 - 0
app/Http/Controllers/RejectedBillItemController.php

@@ -95,7 +95,9 @@ class RejectedBillItemController extends Controller
 //        }
 
 
+        /** @var RejectedBill $rejectedBill */
         $rejectedBill = RejectedBill::query()->where('id',$request->input('id_rejected_bill'))->first();
+        $rejectedBill->updateIsNewRejecting();
         $rejectedBill->syncOrderIssue();     // 同步问题件 修改问题件退货状态
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
         return ['success'=>'true','id'=>$rejectedBillItem['id']];
@@ -119,6 +121,7 @@ class RejectedBillItemController extends Controller
             //$rejectedBillItem->injectCommodityName();  Haozi 2020-12-09
             /** @var RejectedBill $rejectedBill */
             $rejectedBill = RejectedBill::query()->where('id',$rejectedBillItem->id_rejected_bill)->first();
+            $rejectedBill->updateIsNewRejecting();
             $rejectedBill->syncOrderIssue(); // 同步问题件 修改问题件退货状态
             app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
             return ['success'=>'true','id'=>$rejectedBillItem['id']];
@@ -361,6 +364,9 @@ class RejectedBillItemController extends Controller
         }
         $rejectedBillItem = RejectedBillItem::find($request->input('id'));
         $rejectedBillItem->forceDelete();
+        /** @var RejectedBill $rejectedBill */
+        $rejectedBill = RejectedBill::query()->where('id',$rejectedBillItem->id_rejected_bill)->first();
+        $rejectedBill->syncOrderIssue(); // 同步问题件 修改问题件退货状态
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($rejectedBillItem),Auth::user()['id']);
         return ['success'=>'true','id'=>$request->input('id')];
     }

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

@@ -0,0 +1,75 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\MailEvent;
+use App\Role;
+use Illuminate\Http\Request;
+
+class SendEmailsController extends Controller
+{
+    //
+    public function index()
+    {
+        $roles = Role::all();
+        $emailEvents = MailEvent::query()->with('roles')->orderBy('id')->paginate();
+        foreach ($emailEvents as $emailEvent) {
+            $emailEvent->template = json_decode($emailEvent->template);
+            $emailEvent->remark_show = true;
+            $emailEvent->remark_edit = false;
+            $emailEvent->template_show = true;
+            $emailEvent->template_edit = false;
+            $emailEvent->role_selected = '';
+        }
+        return view('maintenance.emails.index', compact('roles', 'emailEvents'));
+    }
+
+    public function addRole(Request $request)
+    {
+        $roleId = $request->roleId;
+        $role = Role::find($roleId);
+        $eventMailId = $request->eventMailId;
+        if (MailEvent::query()->find($eventMailId)->roles()->where('roles.id', $roleId)->exists()) {
+            return ['success' => false, 'data' => '角色已存在'];
+        } else {
+            MailEvent::query()->find($eventMailId)->roles()->attach($role->id);
+            return ['success' => true, 'data' => ['role' => $role]];
+        }
+    }
+
+    public function deleteRole(Request $request)
+    {
+        $roleId = $request->roleId;
+        $role = Role::find($roleId);
+        $eventMailId = $request->eventMailId;
+        MailEvent::query()->find($eventMailId)->roles()->detach($role->id);
+        return ['success' => true, 'data' => $role];
+    }
+
+    public function updateTemplate(Request $request)
+    {
+        $model = MailEvent::query()->find($request->id);
+        $model->update([
+            'template' => $request->template,
+        ]);
+        return ['success' => true];
+    }
+
+    public function active(Request $request)
+    {
+        $model = MailEvent::query()->find($request->id);
+        $model->update([
+            'is_active' => !$model->is_active,
+        ]);
+        return ['success' => true, 'data' => !$model->is_active];
+    }
+
+    public function updateRemark(Request $request)
+    {
+        $model = MailEvent::query()->find($request->id);
+        $model->update([
+            'remark' => $request->remark,
+        ]);
+        return ['success' => true];
+    }
+}

+ 127 - 4
app/Http/Controllers/TestController.php

@@ -16,6 +16,10 @@ use App\Console\Commands\SyncBatchTask;
 use App\Console\Commands\SyncWmsCommoditiesInformation;
 use App\Console\Commands\SyncWMSOrderTask;
 use App\Console\Commands\WasSyncWmsAsnInformation;
+use App\Events\CancelOrder;
+use App\Events\SendEmailEvent;
+use App\Http\Requests\ForeignHaiRobotic_taskUpdateRequest;
+use App\Http\Requests\TestAaRequest;
 use App\Imports\OrderTrackingImport;
 use App\InventoryAccount;
 use App\Jobs\OrderFreeze;
@@ -23,6 +27,7 @@ use App\LaborReport;
 use App\Log;
 use App\Logistic;
 use App\Menu;
+use App\Notifications\SendEmailNotification;
 use App\OracleActAllocationDetails;
 use App\OracleBasCustomer;
 use App\OracleBasSKU;
@@ -59,18 +64,21 @@ use App\Services\DocWaveHeaderService;
 use App\Services\FeatureService;
 use App\Services\InventoryCompareService;
 use App\Services\LogisticService;
+use App\Services\LogisticZopService;
 use App\Services\LogService;
 use App\Services\OracleBasSkuService;
 use App\Services\OracleDocAsnHerderService;
 use App\Services\OracleDOCOrderHeaderService;
 use App\Services\OracleDocWaveDetailService;
 use App\Services\OrderCommodityService;
+use App\Services\OrderPackageReceivedSyncService;
 use App\Services\OrderPackageService;
 use App\Services\OrderService;
 use App\Services\OrderTrackingOwnerService;
 use App\Services\OrderTrackingService;
 use App\Services\OwnerPriceOperationService;
 use App\Services\OwnerService;
+use App\Services\RejectedBillService;
 use App\Services\ShopService;
 use App\Services\StoreService;
 use App\Services\WarehouseService;
@@ -178,6 +186,8 @@ sql;
 
     public function sync()
     {
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
         foreach (Batch::query()->with("orders")->where("created_at",">","2021-01-20 15:00:00")->get() as $batch){
             $order = [];
             $map = [];
@@ -186,7 +196,7 @@ sql;
                 $map[$o->code] = $o->id;
             }
             $sql = <<<sql
-SELECT ORDERNO,WAVENO,SEQNO,EDITTIME FROM DOC_WAVE_DETAILS WHERE WAVENO = ? AND ORDERNO IN ('' 
+SELECT ORDERNO,WAVENO,SEQNO,EDITTIME FROM DOC_WAVE_DETAILS WHERE WAVENO = ? AND ORDERNO IN (''
 sql;
             foreach($order as $o){
                 $sql .= ",'".$o."'";
@@ -1058,7 +1068,7 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
 
     public function reNewBatches3()
     {
-        $batches = Batch::query()->where('id', 6384)->get('code');
+        $batches = Batch::query()->where('id','>', 73620)->get('code');
         $batchCodes = $batches->map(function ($batch) {
             return $batch['code'];
         })->toArray();
@@ -1084,8 +1094,8 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
 //        dd($logs);
         foreach ($batchCodes as $code) {
 //            $request=Cache::get('temp'.$code)['description'];
-            $request = Log::query()->select('description')->where('CREATED_AT', '>', '2020-12-16')
-                ->where('type', "issued_newBatch")
+            $request = Log::query()->select('description')->where('CREATED_AT', '>', '2021-01-22')
+                ->where('method', "issued_newBatch")
                 ->where('description', 'like', "%{$code}%")
                 ->first();
             if ($request) {
@@ -1362,12 +1372,67 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
         }
     }
 
+    public function testHz(){
+        dump('start'.Carbon::now()->toDateTimeString());
+        $ownerAreaReportTask=new CreateOwnerAreaReport();
+        $ownerAreaReportTask->handle();
+        $ownerBillReportTask= new CreateOwnerBillReport();
+        $ownerBillReportTask->handle();
+        $ownerReportTask= new CreateOwnerReport();
+        $ownerReportTask->handle();
+        dump('end'.Carbon::now()->toDateTimeString());
+    }
+
+    public function testGetLogisticNumbers(): array
+    {
+        $orderPackageReceivedSyncService = new OrderPackageReceivedSyncService();
+        return $orderPackageReceivedSyncService->getLogisticNumbers();
+    }
+
+    public function test_orderPackage_updated()
+    {
+        $orderPackageReceivedSyncService = new OrderPackageReceivedSyncService();
+        $response = $orderPackageReceivedSyncService->getLogisticRoutes(['SF' => ['SF1038343374236']]);
+
+        $orderPackage = OrderPackage::query()->where('logistic_number', 'SF1038343374236')->first();
+        $orderPackage->transfer_status = json_decode($orderPackage->transfer_status);
+
+        $orderPackageReceivedSyncService->update($response);
+        $orderPackage = OrderPackage::query()->where('logistic_number', 'SF1038343374236')->first();
+        $orderPackage->transfer_status = json_decode($orderPackage->transfer_status);
+        dump($orderPackage);
+    }
+
+    public function logistic_route_sync_SF()
+    {
+        $orderPackageReceivedSyncService = new OrderPackageReceivedSyncService();
+        $orderPackageReceivedSyncService->syncLogisticRoute();
+    }
+
+    public function logistic_route_sync_ZT()
+    {
+        $service = new LogisticZopService();
+       $result = $service->get([]);
+       dd($result);
+    }
+
     public function testCancelOrder()
     {
         $service = new OracleDocWaveDetailService();
         $service->clearCancelledOrderTask();
     }
 
+    public function sendEmail()
+    {
+        event(new SendEmailEvent());
+    }
+
+    public function y111()
+    {
+        $controller = new SendEmailsController();
+        $controller->index();
+    }
+
     public function processOrderIssueRejectedBill()
     {
         OrderIssue::query()->withTrashed()->whereNotNull('logistic_number_return')->chunkById(200,function($orderIssues){
@@ -1451,4 +1516,62 @@ where (commodities.owner_id,commodity_barcodes.code) in (select commodities.owne
             }
         });
     }
+
+    public function deleteOrderTracking()
+    {
+        $deleteId_arr = [];
+        $deleteCommoditiesId_arr = [];
+        OrderTracking::query()->with(['commodities.package'])
+            ->where('created_at','!=','0000-00-00 00:00:00')
+            ->chunkById('200',function($orderTrackings)use(&$deleteId_arr,&$deleteCommoditiesId_arr){
+                $deleteIds = [];
+                $deleteCommoditiesId = [];
+                foreach ($orderTrackings as $orderTracking) {
+                    if(!($orderTracking->commodities->package ?? false)){
+                        $deleteIds[]  = $orderTracking->id;
+                        if($orderTracking->commodities){
+                            $deleteCommoditiesId[] = $orderTracking->commodities->id;
+                        }
+                    }
+                }
+                if($deleteIds){
+                    $deleteId_arr[] = $deleteIds;
+                    $deleteCommoditiesId_arr[] = $deleteCommoditiesId;
+                    OrderTracking::query()->whereIn('id',$deleteIds)->delete();
+                    OrderPackageCommodities::query()->whereIn('id',$deleteCommoditiesId)->delete();
+                }
+            });
+    }
+
+//    public function testNumber()
+//    {
+//        $asnnos=['ASN2101200684','ASN2101220543','ASN2101220542'];
+//        $asnHeaders=OracleDOCASNHeader::query()->whereIn('asnno',$asnnos)->get();
+//        /**
+//         * @var RejectedBillService $rejectedBillService
+//         */
+//        $rejectedBillService=app(RejectedBillService::class);
+//
+//        $updates = $rejectedBillService->getNeedUpdateCheckedStatusByWms($asnHeaders);
+//        app(BatchUpdateService::class)->batchUpdate('rejected_bills', $updates);
+//        dump($updates);
+//        //$logisticNumberReturn = $rejectedBillService->getLogisticNumberReturn($arr);
+//        //$rejectedBills = $rejectedBillService->getRejectedBills($logisticNumberReturn);
+//    }
+
+    public function updateRejectBillCheckedStatus()
+    {
+        $time=Carbon::parse("2021-01-22 00:00:00")->subDays(15)->toDateTimeString();
+        $asnHeaders=OracleDOCASNHeader::query()
+            ->where('addtime','>=',$time)
+            ->select('asnno','addtime','edittime','customerid','notes','asnreference3')
+            ->get();
+        $chunks=$asnHeaders->chunk(1000);
+        foreach ($chunks as $chunk) {
+         /** @var RejectedBillService $rejectedBillService */
+        $rejectedBillService=app(RejectedBillService::class);
+        $updates = $rejectedBillService->getNeedUpdateCheckedStatusByWms($chunk);
+        app(BatchUpdateService::class)->batchUpdate('rejected_bills', $updates);
+        }
+    }
 }

+ 4 - 4
app/Http/Controllers/PackageController.php → app/Http/Controllers/WeighController.php

@@ -17,7 +17,7 @@ use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Validator;
 
 
-class PackageController extends Controller
+class WeighController extends Controller
 {
     public function index(Request $request,OwnerService $ownerService)
     {
@@ -26,14 +26,14 @@ class PackageController extends Controller
         /** @var PackageService $application */
         $application = app('PackageService');
         $packages = $application->paginate($request);
-        return view('weight.package.index',['packages'=>$packages,'owners'=>$ownerService->getIntersectPermitting(),'paginateParams'=>$paginateParams]);
+        return view('package.weigh.index',['packages'=>$packages,'owners'=>$ownerService->getIntersectPermitting(),'paginateParams'=>$paginateParams]);
     }
 
     public function create()
     {
         if(!Gate::allows('称重管理-录入')){ return redirect(url('/'));  }
         $paperBoxes=PaperBox::select('id','model')->get();
-        return view('weight.package.create',['paperBoxes'=>$paperBoxes]);
+        return view('package.weigh.create',['paperBoxes'=>$paperBoxes]);
     }
 
     /**
@@ -171,7 +171,7 @@ class PackageController extends Controller
         foreach ($ps as &$p){
             $p = json_encode($p,JSON_UNESCAPED_UNICODE);
         }
-        return view('weight.package.statistics',["packages"=>$ps,'owners'=>$owners,'logistics'=>$logistics]);
+        return view('package.weigh.statistics',["packages"=>$ps,'owners'=>$owners,'logistics'=>$logistics]);
     }
 
     public function export(Request $request){

+ 79 - 79
app/Http/Controllers/api/thirdPart/flux/SortingController.php

@@ -24,91 +24,91 @@ class SortingController extends Controller
      * 返回:Response{return{returnFlag(1/0),returnCode(0000/0001),returnDesc,resultInfo}}
      *
      * @param Request $request
-     * @return Response
+     * @return \Illuminate\Http\JsonResponse|Response|\Symfony\Component\HttpFoundation\JsonResponse
      *
      * 2021-01-20 zzd 因同步订单,波次等已上线,弃用该通知接口
      */
     public function newBatch(Request $request)
     {
-        $requestArr=$request->all();
+//       $requestArr=$request->all();
         app('LogService')->log(__METHOD__, 'issued_' . __FUNCTION__, json_encode($request->all()));
-        !$requestArr?$requestArr=json_decode($request->getContent(),true):false;
-        $errors=$this->newBatchValidator($requestArr)->errors();
-        if(count($errors)>0){
-            app('LogService')->log(__METHOD__, 'error' . __FUNCTION__, 'fields wrong, see Errors report please.'.'|'.json_encode($request->all()).'|'.json_encode($errors));
-            return response()->json(['Response'=>['return'=>['returnFlag'=>'0','returnCode'=>'0001',
-                'returnDesc'=>':Failure','resultInfo'=>'','errors'=>$errors]]])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
-        }
-        $requestBatches = $requestArr['request']?? '';
-
-        foreach ($requestBatches as $requestBatch){
-            $requestBatch['edittime']&&strpos(trim($requestBatch['edittime']),' ')?$editTimeFormat='Y-m-d H:i:s':$editTimeFormat='YmdHis';
-            $batch=Batch::query()->firstOrCreate(['code' => $requestBatch['waveno']]);
-
-            if(!$batch)$batch=new Batch();
-            $batch->fill([
-                    'code' => $requestBatch['waveno'],
-                    'wms_type' => $requestBatch['batch_type']??'',
-                    'wms_status' => $requestBatch['docstatus']??'',
-                    'status' => '未处理',
-                    'wms_created_at' => $requestBatch['edittime']?Carbon::createFromFormat($editTimeFormat,$requestBatch['edittime']):'',
-            ]);
-            $batch->save();
-            $oracleAlloactions=OracleActAllocationDetails::query()->where('waveno',$requestBatch['waveno'])->get();
-            foreach($requestBatch['order_list'] as $requestOrder){
-                $owner=Owner::query()->where('code',$requestOrder['customerid'])->first();
-                $order=app("OrderService")->first(['code'=>$requestOrder['docno']]);
-                if(!$order){
-                    $order=app("OrderService")->createOrder([
-                        'batch_id' => $batch['id'],
-                        'code' => $requestOrder['docno'],
-                        'owner_id' => $owner['id'],
-                        'wms_status' => $requestOrder['docstatus']??'波次下发',
-                        'status' => '未处理',
-                    ]);
-                    app('LogService')->log(__METHOD__,__FUNCTION__,'创建 Order'.json_encode($order));
-                }else{
-                    $order['batch_id']= $batch['id'] ;
-                    $order['owner_id']=$order['owner_id']??$owner['owner_id'];
-                    $order['wms_status']=$order['wms_status']??$requestOrder['docstatus']??'波次下发';
-                    $order['status']=$order['status']??'未处理';
-                }
-                $order->save();
-                OrderBin::query()->firstOrCreate([
-                    'order_id' => $order['id'],
-                    'number' => $requestOrder['reservedfield01'],
-                ]);
-                foreach($requestOrder['barcode_list'] as $requestBarcode){
-                    $orderCommodity=OrderCommodity::query()
-                        ->where('order_id',$order['id'])->where('wms_ptltaskid',$requestBarcode['ptltaskid'])->first();
-                    if(!$orderCommodity){
-                        /** @var CommodityService $commodityService */
-                        $commodityService=app('CommodityService');
-                        $commodity=$commodityService->syncBarcodes($requestBarcode['alternate_sku1'],$owner['id'],$requestBarcode['sku']);
-                        $orderCommodity=OrderCommodity::query()->firstOrCreate(['order_id'=>$order['id'],'commodity_id'=>$commodity['id']]);
-                        if(!$orderCommodity){
-                            $orderCommodity = new OrderCommodity([
-                                'order_id' => $order['id'],
-                                'commodity_id' => $commodity['id'],
-                                'amount' => $requestBarcode['fmqty_each']??0,
-                                'wms_ptltaskid' => $requestBarcode['ptltaskid'],
-                            ]);
-                        }else{
-                            $orderCommodity['order_id']=$order['id'];
-                            $orderCommodity['commodity_id']=$commodity['id'];
-                            $orderCommodity['amount']=$requestBarcode['fmqty_each']??0;
-                            $orderCommodity['wms_ptltaskid']=$requestBarcode['ptltaskid']??0;
-                        }
-                        $allocation=$oracleAlloactions->where('orderno',$requestOrder['docno'])->where('sku',$commodity['sku'])->where('qty',$requestBarcode['fmqty_each'])->first();
-                        if($allocation)
-                            $orderCommodity['location'] = $allocation['location'];
-                        $orderCommodity->save();
-                    }
-                }
-            }
-        }
-        return response()->json(['Response'=>['return'=>['returnFlag'=>'1','returnCode'=>'0000',
-            'returnDesc'=>'消息处理成功:Success','resultInfo'=>'']]])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
+//        !$requestArr?$requestArr=json_decode($request->getContent(),true):false;
+//        $errors=$this->newBatchValidator($requestArr)->errors();
+//        if(count($errors)>0){
+//            app('LogService')->log(__METHOD__, 'error' . __FUNCTION__, 'fields wrong, see Errors report please.'.'|'.json_encode($request->all()).'|'.json_encode($errors));
+//            return response()->json(['Response'=>['return'=>['returnFlag'=>'0','returnCode'=>'0001',
+//                'returnDesc'=>':Failure','resultInfo'=>'','errors'=>$errors]]])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
+//        }
+//        $requestBatches = $requestArr['request']?? '';
+//
+//        foreach ($requestBatches as $requestBatch){
+//            $requestBatch['edittime']&&strpos(trim($requestBatch['edittime']),' ')?$editTimeFormat='Y-m-d H:i:s':$editTimeFormat='YmdHis';
+//            $batch=Batch::query()->firstOrCreate(['code' => $requestBatch['waveno']]);
+//
+//            if(!$batch)$batch=new Batch();
+//            $batch->fill([
+//                    'code' => $requestBatch['waveno'],
+//                    'wms_type' => $requestBatch['batch_type']??'',
+//                    'wms_status' => $requestBatch['docstatus']??'',
+//                    'status' => '未处理',
+//                    'wms_created_at' => $requestBatch['edittime']?Carbon::createFromFormat($editTimeFormat,$requestBatch['edittime']):'',
+//            ]);
+//            $batch->save();
+//            $oracleAlloactions=OracleActAllocationDetails::query()->where('waveno',$requestBatch['waveno'])->get();
+//            foreach($requestBatch['order_list'] as $requestOrder){
+//                $owner=Owner::query()->where('code',$requestOrder['customerid'])->first();
+//                $order=app("OrderService")->first(['code'=>$requestOrder['docno']]);
+//                if(!$order){
+//                    $order=app("OrderService")->createOrder([
+//                        'batch_id' => $batch['id'],
+//                        'code' => $requestOrder['docno'],
+//                        'owner_id' => $owner['id'],
+//                        'wms_status' => $requestOrder['docstatus']??'波次下发',
+//                        'status' => '未处理',
+//                    ]);
+//                    app('LogService')->log(__METHOD__,__FUNCTION__,'创建 Order'.json_encode($order));
+//                }else{
+//                    $order['batch_id']= $batch['id'] ;
+//                    $order['owner_id']=$order['owner_id']??$owner['owner_id'];
+//                    $order['wms_status']=$order['wms_status']??$requestOrder['docstatus']??'波次下发';
+//                    $order['status']=$order['status']??'未处理';
+//                }
+//                $order->save();
+//                OrderBin::query()->firstOrCreate([
+//                    'order_id' => $order['id'],
+//                    'number' => $requestOrder['reservedfield01'],
+//                ]);
+//                foreach($requestOrder['barcode_list'] as $requestBarcode){
+//                    $orderCommodity=OrderCommodity::query()
+//                        ->where('order_id',$order['id'])->where('wms_ptltaskid',$requestBarcode['ptltaskid'])->first();
+//                    if(!$orderCommodity){
+//                        /** @var CommodityService $commodityService */
+//                        $commodityService=app('CommodityService');
+//                        $commodity=$commodityService->syncBarcodes($requestBarcode['alternate_sku1'],$owner['id'],$requestBarcode['sku']);
+//                        $orderCommodity=OrderCommodity::query()->firstOrCreate(['order_id'=>$order['id'],'commodity_id'=>$commodity['id']]);
+//                        if(!$orderCommodity){
+//                            $orderCommodity = new OrderCommodity([
+//                                'order_id' => $order['id'],
+//                                'commodity_id' => $commodity['id'],
+//                                'amount' => $requestBarcode['fmqty_each']??0,
+//                                'wms_ptltaskid' => $requestBarcode['ptltaskid'],
+//                            ]);
+//                        }else{
+//                            $orderCommodity['order_id']=$order['id'];
+//                            $orderCommodity['commodity_id']=$commodity['id'];
+//                            $orderCommodity['amount']=$requestBarcode['fmqty_each']??0;
+//                            $orderCommodity['wms_ptltaskid']=$requestBarcode['ptltaskid']??0;
+//                        }
+//                        $allocation=$oracleAlloactions->where('orderno',$requestOrder['docno'])->where('sku',$commodity['sku'])->where('qty',$requestBarcode['fmqty_each'])->first();
+//                        if($allocation)
+//                            $orderCommodity['location'] = $allocation['location'];
+//                        $orderCommodity->save();
+//                    }
+//                }
+//            }
+//        }
+//        return response()->json(['Response'=>['return'=>['returnFlag'=>'1','returnCode'=>'0000',
+//            'returnDesc'=>'消息处理成功:Success','resultInfo'=>'']]])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
     }
 
     protected function newBatchValidator(array $data)

+ 1 - 0
app/Imports/RejectedImport.php

@@ -90,6 +90,7 @@ class RejectedImport implements ToCollection, WithHeadingRow
                     'is_loaded'=>0,
                 ]);
                 $bill->save();
+                $bill->joinOrderIssue();
                 $bill->syncOrderIssue();
                 $item=RejectedBillItem::where('id_rejected_bill',$bill['id'])
                     ->where('barcode_goods',trim($barcode))->where('id_quality_label',$id_quality_label)->first();

+ 44 - 0
app/Jobs/OrderPackageReceivedSync.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Services\OrderPackageReceivedSyncService;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+/**
+ * 同步快递路由信息任务 调用时需要延迟1h触发
+ * Class OrderPackageReceivedSync
+ * @package App\Jobs
+ */
+class OrderPackageReceivedSync implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    protected $logisticNumbers;
+    protected $service;
+
+    /**
+     * OrderPackageReceivedSync constructor.
+     * @param $logisticNumbers
+     */
+    public function __construct($logisticNumbers)
+    {
+        $this->logisticNumbers = $logisticNumbers;
+        $this->service =  new OrderPackageReceivedSyncService();
+    }
+
+
+    /**
+     * Execute the job.
+     * @return void
+     * @throws \Exception
+     */
+    public function handle()
+    {
+        $this->service->syncLogisticRouteApi($this->logisticNumbers);
+    }
+}

+ 63 - 0
app/Listeners/SendEmailListener.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace App\Listeners;
+
+use App\Events\SendEmailEvent;
+use App\MailEvent;
+use App\Notifications\SendEmailNotification;
+use Tightenco\Collect\Support\Collection;
+
+/**
+ * 邮件发送监听器
+ * Class SendEmailListener
+ * @package App\Listeners
+ */
+class SendEmailListener
+{
+
+
+    /**
+     * SendEmailListener constructor.
+     */
+    public function __construct()
+    {
+
+    }
+
+
+    /**
+     * Handle the event.
+     *
+     * @param SendEmailEvent $event
+     * @return void
+     */
+    public function handle(SendEmailEvent $event)
+    {
+        //根据SendEmailEvent->className 从数据库中查找,判断状态是否开启
+        $emailEvent = MailEvent::query()
+            ->where('event_name', SendEmailEvent::class)
+            ->where('is_active', true)
+            ->first();
+        if ($emailEvent) {
+            /** @var MailEvent $emailEvent */
+            $users = $this->getUsers($emailEvent);
+            foreach ($users as $user) {//给这些用户发送通知
+                $user->notify(new SendEmailNotification($emailEvent->template));//邮件模板由数据库中定制的模板为准
+            }
+        }
+    }
+
+    /**
+     * 根據事件关联的角色,查询到用户
+     * @param MailEvent $emailEvent
+     * @return \Illuminate\Support\Collection|Collection
+     */
+    private function getUsers(MailEvent $emailEvent)
+    {
+        $users = collect();
+        foreach ($emailEvent->roles as $role) {
+            $users = $users->merge($role->users);
+        }
+        return $users;
+    }
+}

+ 23 - 0
app/MailEvent.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\LogModelChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
+
+class MailEvent extends Model
+{
+    use LogModelChanging;
+
+    protected $fillable = ['name', 'event_name', 'remark', 'is_active', 'template'];
+
+    /**
+     * @return BelongsToMany
+     */
+    public function roles(): BelongsToMany
+    {
+        return $this->belongsToMany(Role::class,'mail_event_role','mail_event_id','role_id');
+    }
+}

+ 63 - 0
app/Notifications/SendEmailNotification.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class SendEmailNotification extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    public $objToJson;
+
+    /**
+     * SendEmailNotification constructor.
+     * @param $objToJson
+     */
+    public function __construct($objToJson)
+    {
+        $this->objToJson = $objToJson;
+    }
+
+
+    /**
+     * Get the notification's delivery channels.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function via($notifiable): array
+    {
+        return ['mail'];
+    }
+
+    /**
+     * Get the mail representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return MailMessage
+     */
+    public function toMail($notifiable): MailMessage
+    {
+        $template = json_decode($this->objToJson);
+        return (new MailMessage)->view(
+            'emails.test', ['objToJson' => $template]
+        )->subject($template->title);
+    }
+
+    /**
+     * Get the array representation of the notification.
+     *
+     * @param  mixed  $notifiable
+     * @return array
+     */
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 17 - 0
app/OracleDOCOrderHeader.php

@@ -2,6 +2,8 @@
 
 namespace App;
 
+use App\Services\LogisticService;
+use App\Services\OwnerService;
 use App\Traits\HasCompositePrimaryKey;
 use App\Traits\ModelTimeFormat;
 use Illuminate\Database\Eloquent\Model;
@@ -63,4 +65,19 @@ class OracleDOCOrderHeader extends Model
     public function orderType(){
         return $this->hasOne('App\OracleBasCode','code','ordertype')->where('codeid','SO_TYP');
     }
+
+    public function getLogistic()
+    {
+        /** @var LogisticService $logistic_service */
+        $logistic_service = app('LogisticService');
+        if(!$this['carrierid'])return null;
+        return $logistic_service->getLogisticByCode($this['carrierid']);
+    }
+
+    public function getOwner()
+    {
+        /** @var OwnerService $owner_service */
+        $owner_service = app('OwnerService');
+        return $owner_service->codeGetOwner($this['customerid']);
+    }
 }

+ 15 - 2
app/Order.php

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

+ 57 - 97
app/OrderIssue.php

@@ -3,11 +3,17 @@
 namespace App;
 
 use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Illuminate\Database\Eloquent\SoftDeletes;
 
 use App\Traits\LogModelChanging;
 
+/**
+ * @method Builder filter
+ */
+
 class OrderIssue extends Model
 {
     use LogModelChanging;
@@ -114,102 +120,6 @@ class OrderIssue extends Model
         return $createLog->user->name ?? '';
     }
 
-    public function 同步退单状态(){
-        $rejectedItems = [];
-        $orderItems = [];
-        $orderIssueId = $this['id'];
-        if ($this->logistic_number_return ?? false) {
-            $rejectedBillItems = RejectedBillItem::query()->with('quality')
-                ->whereHas('rejectedBill.orderIssue', function ($query) use ($orderIssueId) {
-                    $query->where('id',$orderIssueId);
-                })->get();
-            if($rejectedBillItems->where('quality.name','残次')->count() > 0){
-                $this->update(['rejecting_status' => '差异退回']);
-                return;
-            }
-            if (count($rejectedBillItems) == 0) {
-                $this->update(['rejecting_status' => '未退回']);
-                return;
-            }
-            $barcodeGoods = data_get($rejectedBillItems,'*.barcode_goods');
-            $commodityBarcodes = CommodityBarcode::query()->with('commodity')->whereIn('code',$barcodeGoods)->get();
-            $commodities = Commodity::query()->whereIn('sku',$barcodeGoods)->get();
-
-            foreach ($rejectedBillItems as $item) {
-                $barcode_goods = (string)$item->barcode_goods;
-                $commodity = $commodities->where('sku',$barcode_goods)->first();
-                if(!$commodity){
-                    $commodityBarcode = $commodityBarcodes->where('code',$barcode_goods)->first();
-                    $barcode_goods = $commodityBarcode->commodity->sku ?? $barcode_goods;
-                }
-                if (!isset($rejectedItems[$barcode_goods])){
-                    $rejectedItems[$barcode_goods] = 0;
-                }
-                $rejectedItems[(string)$barcode_goods] += $item->amount;
-            }
-        } else {
-            $this->update(['rejecting_status' => '未退回']);
-            return;
-        }
-        if ($this->order_id  ?? false) {
-            $items = OrderPackageCommodities::query()
-                ->with(['commodity','package.order.issue'])
-                ->whereHas('package.order.issue', function ($query) use ($orderIssueId) {
-                    $query->where('id', $orderIssueId);
-                })->get();
-            if (count($items) > 0) {
-                foreach ($items as $item) {
-                    $sku = $item['commodity']['sku'];
-                    if (! isset($orderItems[$sku])  ?? false){
-                        $orderItems[$sku] = 0;
-                    }
-                    $orderItems[$sku] += $item->amount;
-                }
-            } else {
-                $this->update(['rejecting_status' => '无']);
-                return;
-            }
-        }
-        $rejectedExcess = 0;    // 退回差异
-        $rejectedReview = 0;    // 退回复核  $rejectedItems == $orderItems
-        foreach ($rejectedItems as $key => $items) {
-            if ($orderItems[$key] ?? false) {
-                if ($rejectedItems[$key] == $orderItems[$key])
-                    $rejectedReview++;
-            } else
-                $rejectedExcess++;
-        }
-        if ($rejectedExcess > 0) {
-            $this->update(['rejecting_status' => '差异退回']);
-            return;
-        }
-        // 全部退回 部分退回 超量退回 差异退回 未退回 无
-        $isExcess = 0; // 超量 $orderItems < $rejectedItems
-        $isDiff = 0;   // 部分 $orderItems > $rejectedItems
-        $isAccord = 0; // 相同 $orderItems == $rejectedItems
-        $isLack = 0;   // 缺少 $orderItems != $rejectedItems
-        foreach ($orderItems as $key => $item) {
-            if ($rejectedItems[$key] ?? false) {
-                if ($orderItems[$key] < $rejectedItems[$key])
-                    $isExcess++;
-                else if ($orderItems[$key] > $rejectedItems[$key])
-                    $isDiff++;
-                else if ($orderItems[$key] == $rejectedItems[$key])
-                    $isAccord++;
-            } else
-                $isLack++;
-        }
-
-        if($isAccord == $rejectedReview && $isLack == 0 && $isExcess == 0 && $isDiff==0 && $rejectedExcess == 0 )
-            $this->update(['rejecting_status' => '全部退回']);
-        else if($isExcess > 0 && $isAccord ==  $rejectedReview && $isDiff == 0 && $isLack == 0)
-            $this->update(['rejecting_status' => '超量退回']);
-        else if($isDiff >=0 && $isAccord == $rejectedReview && $isLack >=0 && $rejectedExcess ==0 && $isExcess==0)
-            $this->update(['rejecting_status' => '部分退回']);
-        else if($isLack >= 0 && $rejectedExcess>=0 && $isDiff>=0 && $isLack>=0 && $isExcess>=0 && $rejectedReview>=0)
-            $this->update(['rejecting_status' => '差异退回']);
-    }
-
     /**
      * 同步退货状态
      */
@@ -339,13 +249,28 @@ class OrderIssue extends Model
                 if($rejectedBill){
                     if(OrderIssueRejectedBill::isExit($this->id,$logistic_number))continue;
                     $this->joinRejectedBill($logistic_number);
-                    $this->is_new_rejecting = '有';
+                    if(isset($rejectedBill->items))
+                        $this->is_new_rejecting = '有';
                 }
             }
             $this->save();
         }
     }
 
+    public function syncRejected($logistic_number)
+    {
+        $query = RejectedBill::query()->selectRaw('id');
+        if(is_array($logistic_number)){
+            $query->whereIn('logistic_number_return',$logistic_number);
+        }elseif (is_string($logistic_number)){
+            $query->where('logistic_number_return',$logistic_number);
+        }else return;
+        $items = RejectedBillItem::query()->whereIn('id_rejected_bill',$query);
+        if($items->count() > 0) $this->update(['is_new_rejecting'=>'有']);
+        elseif($items->count() == 0) $this->update(['is_new_rejecting'=>'无']);
+    }
+
+
     /**
      * @param array|string $logistic_number
      * @return array|void
@@ -353,6 +278,7 @@ class OrderIssue extends Model
     public function joinRejectedBill($logistic_number)
     {
         if(!$logistic_number)return null;
+        $this->syncRejected($logistic_number);
         if(is_array($logistic_number)){
             return $this->rejectedBills()->sync($logistic_number,false);
         }
@@ -368,4 +294,38 @@ class OrderIssue extends Model
     {
         return $this->rejectedBills()->updateExistingPivot($logistic_number,['logistic_number_return'=>$logistic_number_update]);
     }
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+
+    public function scopeDefaultWith($query)
+    {
+        $this->scopeJsonWith($query);
+        return $query->with(['top'])
+            ->selectRaw('order_issues.* ,order_issue_on_tops.id top_id ,order_issue_on_tops.remark,order_issue_on_tops.updated_at top_update')
+            ->leftJoin('order_issue_on_tops', 'order_issue_on_tops.order_issue_id', '=', 'order_issues.id')
+            ->whereNull('order_issue_on_tops.deleted_at')
+            ->orderBy('order_issue_on_tops.updated_at', 'desc');
+    }
+
+    public function scopeJsonWith($query)
+    {
+        return $query->with(['issueType', 'logs' => function ($query){
+            $query->with('user')->orderByDesc('created_at');
+        },'order'=>function($query){
+            $query->with(['shop', 'logistic', 'owner', 'packages.commodities.commodity.barcodes']);
+        },'secondOrder'=>function($query){
+            $query->with(['shop', 'logistic', 'owner', 'packages.commodities.commodity.barcodes']);
+        },'orderIssueRejectedBills.rejectedBill'=>function($query){
+            $query->with(['owner','logistic','user','items.quality']);
+        },'userWorkgroups'])
+            ->orderBy('order_issues.id', 'desc');
+    }
+
+    public function userWorkgroups(): BelongsToMany
+    {
+        return $this->belongsToMany(UserWorkgroup::class);
+    }
 }

+ 16 - 1
app/OrderPackage.php

@@ -9,6 +9,7 @@ use App\Services\OrderService;
 use App\Traits\ModelTimeFormat;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
@@ -22,12 +23,16 @@ class OrderPackage extends Model
     use ModelTimeFormat;
 
     protected $fillable = ['order_id','logistic_number','batch_number',
-        'batch_rule','bulk','weight','length','width','height','paper_box_id','measuring_machine_id','weighed_at','status'];
+        'batch_rule','bulk','weight','length','width','height','paper_box_id','measuring_machine_id','weighed_at','status','sent_at','received_at','exception','transfer_status','remark','owner_id'];
 
     public function order(){
         return $this->belongsTo('App\Order','order_id','id');
     }
 
+    protected $casts = [
+        'transfer_status' => 'array',
+    ];
+
     public function commodities(){
         return $this->hasMany('App\OrderPackageCommodities','order_package_id','id');
     }
@@ -272,4 +277,14 @@ class OrderPackage extends Model
         if(strpos($val,'null')!==false)return '';
         return $val;
     }
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+
+    public function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
 }

+ 1 - 4
app/Policies/CustomerLogPolice.php

@@ -14,10 +14,7 @@ class CustomerLogPolice
 
     public function update(User $user, CustomerLog $customerLog): bool
     {
-        $lastOne = cache()->remember($this->cache_key . $user->id, 1, function () use ($user) {
-            return CustomerLog::query()->where('user_id', $user->id)->orderByDesc('updated_at')->first();
-        });
-        return (int)$user->id === (int)$customerLog->user_id && $customerLog->id == $lastOne->id;
+        return (int)$user->id === (int)$customerLog->user_id;
     }
 
     public function destroy(User $user, CustomerLog $customerLog)

+ 4 - 0
app/Providers/AppServiceProvider.php

@@ -35,6 +35,7 @@ use App\Services\OracleActAllocationDetailService;
 use App\Services\OrderIssueProcessLogService;
 use App\Services\OrderIssueRejectedBillService;
 use App\Services\OrderIssueService;
+use App\Services\OrderPackageReceivedSyncService;
 use App\Services\OrderPackageService;
 use App\Services\OrderService;
 use App\Services\OrderIssueWorkLoadService;
@@ -203,6 +204,9 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('WarehouseService',WarehouseService::class);
         app()->singleton('WaybillFinancialService',WaybillFinancialService::class);
         app()->singleton('WeighExceptedService',WeighExceptedService::class);
+        app()->singleton('CustomerLogService',CustomerLogService::class);
+        app()->singleton('CustomerLogStatusService',CustomerLogStatusService::class);
+        app()->singleton('OrderPackageReceivedSyncService',OrderPackageReceivedSyncService::class);
     }
 
 

+ 3 - 0
app/Providers/EventServiceProvider.php

@@ -35,6 +35,9 @@ class EventServiceProvider extends ServiceProvider
         ModelChangedEvent::class =>[
             ModelChangedListener::class
         ],
+        'App\Events\SendEmailEvent' => [
+            'App\Listeners\SendEmailListener'
+        ],
     ];
 
     /**

+ 29 - 0
app/Providers/LogisticProvider.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\ServiceProvider;
+use \Illuminate\Contracts\Support\DeferrableProvider;
+
+class LogisticProvider extends ServiceProvider implements DeferrableProvider
+{
+    /**
+     * Register services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        
+    }
+
+    /**
+     * Bootstrap services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        //
+    }
+}

+ 25 - 6
app/RejectedBill.php

@@ -170,14 +170,17 @@ class RejectedBill extends Model
         return parent::delete(); // TODO: Change the autogenerated stub
     }
 
-    public function syncOrderIssue()
+    public function joinOrderIssue()
     {
-        if(isset($this->orderIssue)){
-            $this->orderIssue->syncRejectingStatus();
+        if(isset($this->orderIssueRejectedBill)){
             return;
         }
         /** @var OrderIssue $orderIssue */
-        $orderIssue = null;
+        $orderIssue = $this->orderIssueRejectedBill->orderIssue ?? null;
+        if($orderIssue){
+            $orderIssue->joinRejectedBill($this->logistic_number_return);
+            return;
+        }
         // 原单退回
         if($this->logistic_number === '原单退回'){
             $orderIssue = OrderIssue::query()->where('order_id',function ($query){
@@ -194,8 +197,24 @@ class RejectedBill extends Model
             })->first();
         }
         if(!$orderIssue)return;
-        if(!OrderIssueRejectedBill::isExit($orderIssue->id,$this->logistic_number_return)) $orderIssue->update(['is_new_rejecting' => '有']);
         $orderIssue->joinRejectedBill($this->logistic_number_return);
         $orderIssue->syncRejectingStatus();
-     }
+    }
+
+    public function syncOrderIssue()
+    {
+        if(isset($this->orderIssueRejectedBill)){
+            if(isset($this->orderIssueRejectedBill->orderIssue)){
+                /** @var OrderIssue $orderIssue */
+                $orderIssue = $this->orderIssueRejectedBill->orderIssue;
+                $orderIssue->syncRejectingStatus();
+            }
+        }
+    }
+
+    public function updateIsNewRejecting()
+    {
+        $orderIssue = $this->orderIssueRejectedBill->orderIssue ?? null;
+        if($orderIssue) $orderIssue->update(['is_new_rejecting' => '有']);
+    }
 }

+ 206 - 0
app/Services/LogisticSFService.php

@@ -0,0 +1,206 @@
+<?php
+
+
+namespace App\Services;
+
+
+use App\Exceptions\WarningException;
+use Exception;
+use Illuminate\Http\Client\Response;
+use Illuminate\Support\Facades\Http;
+
+class LogisticSFService
+{
+    /**
+     * 顺丰字段与数据库字段的映射关心
+     * @var string[]
+     */
+    protected $protected_switch = [
+        'logistic_number' => 'mailno',
+        'transfer_status' => 'remark',
+        'received_at' => 'accept_time',
+    ];
+
+    /**
+     * 获取顺丰快递揽收数据
+     * @param array $logisticNums [logisticNums]快递单号数组
+     * @return array 快递揽收信息数组
+     * @throws Exception 未知的丰桥opCode
+     */
+    public function get(array $logisticNums): array
+    {
+        // 将$logisticNums以10个位单位进行分割,返回二维数组
+        $logisticNums_size_10 = array_chunk($logisticNums, config('api_logistic.SF.max_size', 10));
+        // 遍历二维数组批量查询顺丰接口
+        //将查询到的结果整合到一起,更新order_packages.received_at
+        $result = [];
+        foreach ($logisticNums_size_10 as $numbers) {
+            $numbersStr = implode(',', $numbers);
+            $result_10 = $this->getResultFromSF(config('api_logistic.SF.head'), $numbersStr, config('api_logistic.SF.check_word'), config('api_logistic.SF.url'));
+            $result = array_merge($result, $result_10);
+        }
+        return $result;
+    }
+
+    /**
+     * @param string $head 客户号
+     * @param string $numbers 快递单号字符串,多个以','分隔
+     * @param string $checkWord 客户秘钥
+     * @param string $url 顺丰接口地址
+     * @return array
+     * @throws Exception 未知的丰桥opCode
+     */
+    public function getResultFromSF(string $head, string $numbers, string $checkWord, string $url): array
+    {
+        $responseBody = get_object_vars(simplexml_load_string($this->sendHttpToSF($head, $numbers, $checkWord, $url))->Body)['RouteResponse'];
+        $result = [];
+        if (is_array($responseBody)) {//SF返回多个单号的查询结果
+            $result = $this->transformSFMoreToArr($responseBody, $result);
+        } else {
+            $result[] = $this->transformSFOneToArr(get_object_vars($responseBody), []);
+        }
+        return $result;
+    }
+
+    /**
+     * 构建顺丰xml请求体
+     * @param string $head
+     * @param string $number
+     * @return string
+     */
+    private function buildXmlStr(string $head, string $number): string
+    {
+        return <<<xml
+<?xml version="1.0" encoding="utf-8" ?>
+    <Request service='RouteService' lang='zh-CN'>
+    <Head>$head</Head>
+    <Body>
+    <RouteRequest
+    tracking_number="{$number}" tracking_type='1' method_type='1'
+    />
+    </Body>
+    </Request>
+xml;
+    }
+
+    /**
+     * 将单个单号的顺丰数据转换为数组
+     * @param array $routeResponse
+     * @param array $data
+     * @return array
+     * @throws Exception
+     */
+    public function transformSFOneToArr(array $routeResponse, array $data): array
+    {
+        $data['logistic_number'] = $routeResponse['@attributes'][$this->protected_switch['logistic_number']];
+        try {
+            $lastRoute = get_object_vars($routeResponse['Route'][count($routeResponse['Route']) - 1])['@attributes'];//获取最新的路由信息
+            $data = $this->switchOpCodeToStatus($lastRoute, $data);
+            $data['transfer_status'] = $this->transformRoutes($routeResponse['Route']);
+
+        } catch (Exception $e) {
+            throw new WarningException("单号没有查询到快递路由信息','LogisticSFService->transformSFOneToArr->{$data['logistic_number']}");
+        } finally {
+            return $data;
+        }
+    }
+
+    /**
+     * 转换快递路由信息
+     * @param array $routs 快递路由
+     * @return array
+     */
+    public function transformRoutes(array $routs): array
+    {
+        $result = [];
+        foreach ($routs as $route) {
+            $route = get_object_vars($route)['@attributes'];
+            $data['accept_time'] = $route['accept_time'];
+            $data['accept_address'] = $route['accept_address'];
+            $data['remark'] = $route['remark'];
+            $result[] = $data;
+        }
+        return $result;
+    }
+
+    /**
+     * 将最新路由信息转换为数组
+     * @param array $lastRoute
+     * @param array $data
+     * @return array
+     * @throws Exception
+     */
+    public function switchOpCodeToStatus(array $lastRoute, array $data): array
+    {
+        switch ($lastRoute['opcode']) {
+            case 123:
+            case 130:
+            case 3036:
+            case 31:
+            case 30:
+                $data['status'] = '在途';
+                break;
+            case 70:
+            case 33:
+                $data['status'] = '派送异常';
+                $data['exception'] = '是';
+                break;
+            case 204:
+            case 44:
+                $data['status'] = '派送中';
+                break;
+            case 50:
+                $data['status'] = '已揽收';
+                break;
+            case 607:
+            case 8000:
+            case 80:
+                $data['status'] = '已收件';
+                $data['received_at'] = $lastRoute[$this->protected_switch['received_at']];
+                break;
+            case 648:
+            case 99:
+                $data['status'] = '返回中';
+                break;
+            default:
+                throw new WarningException("未知的丰桥状态码: {$lastRoute['opcode']}->{json_encode($lastRoute)}");
+        }
+        return $data;
+    }
+
+    /**
+     * @param string $head
+     * @param string $numbers
+     * @param string $checkWord
+     * @param string $url
+     * @return Response
+     * @throws Exception
+     */
+    public function sendHttpToSF(string $head, string $numbers, string $checkWord, string $url): Response
+    {
+        $xml = $this->buildXmlStr($head, $numbers);
+        $checkingJson = $xml . $checkWord;
+        $verifyCode = base64_encode(md5($checkingJson, true));
+        try {
+            $response = Http::withHeaders(['Content-Type' => 'text/xml'])->get($url, ['xml' => $xml, 'verifyCode' => $verifyCode]);
+        } catch (Exception $e) {
+            throw new WarningException("HTTP请求顺丰接口异常->{$e->getMessage()}");
+        }
+        return $response;
+    }
+
+    /**
+     * 将多个顺丰的单号转换为数组
+     * @param array $responseBody
+     * @param array $result
+     * @return array
+     * @throws Exception
+     */
+    public function transformSFMoreToArr(array $responseBody, array $result): array
+    {
+        foreach ($responseBody as $routeResponse) {
+            $result[] = $this->transformSFOneToArr(get_object_vars($routeResponse), []);
+        }
+        return $result;
+    }
+}

+ 32 - 0
app/Services/LogisticZopService.php

@@ -0,0 +1,32 @@
+<?php
+
+
+namespace App\Services;
+
+
+use App\library\zop\ZopClient;
+use App\library\zop\ZopProperties;
+use App\library\zop\ZopRequest;
+
+class LogisticZopService
+{
+    public function get(array $logisticNums)
+    {
+
+        $url = config('api_logistic.ZTO.url');
+        $xAppKey = config('api_logistic.ZTO.x-appKey');
+        $xDataDigest = config('api_logistic.ZTO.x-dataDigest');
+
+        $properties = new ZopProperties($xAppKey, $xDataDigest);
+        $client = new ZopClient($properties);
+        $request = new ZopRequest();
+
+        $request->setUrl($url);
+        $body = json_encode([
+            'type' => 1,
+            'billCode' => '75424921258500',
+        ]);
+        $request->setBody($body);
+        return json_decode($client->execute($request));
+    }
+}

+ 16 - 2
app/Services/OracleDOCOrderHeaderService.php

@@ -24,7 +24,8 @@ Class OracleDOCOrderHeaderService
         'DOC_Order_Header.CarrierName', 'DOC_Order_Header.LastShipmentTime','DOC_Order_Header.EDISendFlag',
         'DOC_Order_Header.SOReference5', 'DOC_Order_Header.C_Tel2','DOC_Order_Header.Transportation',
         'DOC_Order_Header.WareHouseId','DOC_Order_Header.SOStatus','DOC_Order_Header.C_Tel1','DOC_Order_Header.C_District',
-        'DOC_Order_Header.IssuePartyName','DOC_Order_Header.OrderType','DOC_Order_Header.WaveNo'
+        'DOC_Order_Header.IssuePartyName','DOC_Order_Header.OrderType','DOC_Order_Header.WaveNo',
+        'DOC_Order_Header.ReleaseStatus'
     ];
 
     public function getQuery(){
@@ -106,6 +107,19 @@ Class OracleDOCOrderHeaderService
         return $this->getQuery()->whereIn('DOC_Order_Header.OrderNo',$orderNos)->get();
     }
 
-
+    public function loadMissing($orderHeaders)
+    {
+        return $orderHeaders->loadMissing(['oracleBASCustomer'=>function($query){
+            $query->selectRaw('BAS_CUSTOMER.CustomerID,BAS_CUSTOMER.Customer_Type,BAS_CUSTOMER.Descr_C,BAS_CUSTOMER.Active_Flag');
+        },'oracleDOCOrderDetails'=>function($query){
+            $query->selectRaw('doc_order_details.orderNo,doc_order_details.customerid,doc_order_details.sku,doc_order_details.QtyOrdered,doc_order_details.Location,doc_order_details.OrderLineNo,doc_order_details.d_edi_03');
+        }, 'actAllocationDetails'=>function($query){
+            $query->selectRaw('ACT_Allocation_Details.AllocationDetailsID,ACT_Allocation_Details.OrderNo,ACT_Allocation_Details.Qty_Each,ACT_Allocation_Details.PickToTraceID,ACT_Allocation_Details.CustomerID,ACT_Allocation_Details.Sku,ACT_Allocation_Details.Location,ACT_Allocation_Details.SkuLineNo,ACT_Allocation_Details.OrderLineno');
+        },'oracleBASCode'=>function($query){
+            $query->selectRaw('BAS_Codes.CodeID,BAS_Codes.CodeName_C,BAS_Codes.Code');
+        },'orderType'=>function($query){
+            $query->selectRaw('BAS_Codes.CodeID,BAS_Codes.CodeName_C,BAS_Codes.Code');
+        }]);
+    }
 
 }

+ 6 - 2
app/Services/OracleDocWaveDetailService.php

@@ -17,7 +17,8 @@ class OracleDocWaveDetailService
     {
         if (!$orderHeaders) return;
         $clearOrderNos = data_get($orderHeaders, '*.orderno');
-        OracleDOCWaveDetails::query()->whereIn('OrderNo', $clearOrderNos)->delete();
+        $ownerNos = data_get($orderHeaders, '*.ownerno');
+        OracleDOCWaveDetails::query()->whereIn('OrderNo', $clearOrderNos)->whereIn('OwnerNo',$ownerNos)->delete();
         app('LogService')->log(__CLASS__, __METHOD__, 'Delete OracleDOCWaveDetails' . '  ' . json_encode($clearOrderNos) );
     }
 
@@ -94,7 +95,10 @@ class OracleDocWaveDetailService
         foreach ($orderHeaderList as $items) {
             $this->clearCancelledOrder($items);
             if ($orderHeaders->count() > 0) {
-                OracleDOCOrderHeader::query()->whereIn('orderNo', data_get($items, '*.orderno'))->update(['waveno' => '*']);
+                OracleDOCOrderHeader::query()
+                    ->whereIn('orderNo', data_get($items, '*.orderno'))
+                    ->whereIn('owerno', data_get($items, '*.owerno'))
+                    ->update(['waveno' => '*']);
                 $json = json_encode($items->map(function ($orderHeader) {
                     return ['orderno' => $orderHeader->orderno, 'waveno' => $orderHeader->waveno];
                 }));

+ 0 - 4
app/Services/OrderIssueRejectedBillService.php

@@ -23,7 +23,6 @@ Class OrderIssueRejectedBillService
             ->where('order_issue_id',$orderIssue->id)
             ->where('logistic_number_return',$logistic_number_return)->first();
         if($orderIssueRejectedBill)return null;
-        if(!OrderIssueRejectedBill::isExit($orderIssue->id,$logistic_number_return)) $orderIssue->update(['is_new_rejecting' => '有']);
         $orderIssue->joinRejectedBill($logistic_number_return);
         $orderIssue->syncRejectingStatus();      // 问题件同步订单状态
         return OrderIssueRejectedBill::query()->with('rejectedBill.items')
@@ -118,7 +117,4 @@ Class OrderIssueRejectedBillService
         }
         $order_issues->syncRejectingStatus();
     }
-
-
-
 }

+ 12 - 301
app/Services/OrderIssueService.php

@@ -6,6 +6,7 @@ use App\OracleDOCASNHeader;
 use App\OracleDOCOrderHeader;
 use App\OrderIssue;
 use App\OrderIssueProcessLog;
+use App\OrderIssueRejectedBill;
 use App\OrderIssueType;
 use App\OrderPackage;
 use App\Order;
@@ -23,297 +24,12 @@ use App\Traits\ServiceAppAop;
 class OrderIssueService
 {
     use ServiceAppAop;
-    public function __construct()
-    {
-        app()->bind("orderService", OrderService::class);
-        app()->bind("rejectedService", RejectedService::class);
-        app()->bind("orderPackageCommoditiesService", OrderPackageCommoditiesService::class);
-    }
 
     public function insert($params)
     {
         OrderIssue::query()->insert($params);
     }
 
-    public function getQuery(array $arr, array $condition = null)
-    {
-        if (!isset($condition)) {
-            $condition = $arr;
-        }
-        $user = Auth::user();
-        $owner_ids = $user ? app('UserService')->getPermittingOwnerIds($user) : [];
-        if ($condition['owner_id'] ?? false) {
-            $owner_ids = explode(',', $condition['owner_id']);
-        }
-        $query = OrderIssue::with(['top', 'userWorkGroup', 'issueType', 'logs' => function ($query) use ($arr) {
-            $query->with('user')->orderByDesc('created_at');
-        }, 'order' => function ($query) {
-            $query->with(['shop', 'logistic', 'owner', 'packages.commodities.commodity' => function ($query) {
-                $query->with('barcodes');
-            }]);
-        }, 'orderIssueRejectedBills.rejectedBill' => function ($query) {
-            $query->with(['items.quality']);
-        }, 'secondOrder' => function ($query) {
-            $query->with(['shop', 'logistic', 'owner', 'packages.commodities.commodity' => function ($query) {
-                $query->with('barcodes');
-            }]);
-        }])->whereHas('order.owner', function ($query) use ($owner_ids) {
-            $query->whereIn('id', $owner_ids);
-        });
-        if ($arr['log_content'] ?? false) {
-            $query->whereHas('logs', function ($query) use ($arr) {
-                $query->where('content', 'like', $arr['log_content']);
-                if ($arr['addtime'] ?? false) {
-                    $query->where('created_at', '>=', Carbon::now()->subDays($arr['addtime']));
-                } else {
-                    $query->where('created_at', '>=', Carbon::now()->subDays(31));
-                }
-            });
-        }
-        if (isset($arr['is_imported'])) {
-            $query->where('imported_status', $arr['is_imported']);
-        }
-
-        if (isset($arr['is_new_rejecting'])) {
-            $query->where('is_new_rejecting', '=', $arr['is_new_rejecting']);
-        }
-
-        if (isset($arr['logistic_id'])) {
-            $query->whereHas('order', function ($query) use ($arr) {
-                $query->where('logistic_id', $arr['logistic_id']);
-            });
-        }
-        if (isset($arr['custom_code'])) {
-            $query->where('custom_code', $arr['custom_code']);
-        }
-        if(isset($arr['hiddenTag'])){
-            $query->where('hidden_tag', $arr['hiddenTag']);
-        }else{
-            $query->whereNull('hidden_tag');
-        }
-        $query->selectRaw('order_issues.* ,order_issue_on_tops.id top_id ,order_issue_on_tops.remark,order_issue_on_tops.updated_at top_update')
-            ->leftJoin('order_issue_on_tops', 'order_issue_on_tops.order_issue_id', '=', 'order_issues.id')
-            ->whereNull('order_issue_on_tops.deleted_at')
-            ->orderBy('order_issue_on_tops.updated_at', 'desc');
-        $query->orderBy('order_issues.id', 'desc');
-        return $query;
-    }
-
-    private function getOrderQuery(array $arr, $query)
-    {
-        $query->whereHas('order', function ($query) use ($arr) {
-            if ($arr['client_code'] ?? false) {
-                return $this->searchWay($query, $arr['client_code'], 'client_code');
-            }
-            if ($arr['consignee_name'] ?? false) {
-                return $this->searchWay($query, $arr['consignee_name'], 'consignee_name');
-            }
-            if ($arr['consignee_phone'] ?? false) {
-                return $this->searchWay($query, $arr['consignee_phone'], 'consignee_phone');
-            }
-            if ($arr['logistic_number'] ?? false) {
-                $logistic_number = $arr['logistic_number'];
-                $query->whereHas('packages', function ($query) use ($logistic_number) {
-                    return $this->searchWay($query, $logistic_number, 'logistic_number');
-                });
-            }
-            if (($arr['good_barcode'] ?? false) || ($arr['good_name'] ?? false)) {
-                $query->whereHas('packages.commodities.commodity', function ($query) use ($arr) {
-                    if ($arr['good_barcode'] ?? false) {
-                        return $this->searchWay($query, $arr['good_barcode'], 'sku');
-                    }
-                    if ($arr['good_name'] ?? false) {
-                        $query->where('name', 'like', '%' . $arr['good_name'] . '%');
-                    }
-                });
-            }
-        });
-        if ($arr['send_client_code'] ?? false) {
-            $query->whereHas('secondOrder', function ($query) use ($arr) {
-                return $this->searchWay($query, $arr['send_client_code'], 'client_code');
-            });
-        }
-        return $query;
-    }
-
-    public function getRejectedBillQuery(array $arr, $query)
-    {
-        if (($arr['logistic_number_return'] ?? false) || ($arr['id_quality_label'] ?? false)) {
-            $query->whereHas('rejectedBill', function ($query) use (&$arr) {
-                if ($arr['logistic_number_return'] ?? false) {
-                    return $this->searchWay($query, $arr['logistic_number_return'], 'logistic_number_return');
-                }
-                if ($arr['id_quality_label'] ?? false) {
-                    $query->whereHas('items', function ($query) use ($arr) {
-                        $query->where('id_quality_label', $arr['id_quality_label']);
-                    });
-                }
-            });
-        }
-        return $query;
-    }
-
-    public function getConditionQuery(array $arr, array $condition = null)
-    {
-        /** @var Builder $query */
-        $query = $this->getQuery($arr, $condition);
-        $query = $this->getOrderQuery($condition ?? $arr, $query);
-        $query = $this->getRejectedBillQuery($condition ?? $arr, $query);
-        if (!isset($condition)) {
-            $condition = $arr;
-        }
-        if ($condition['id'] ?? false) {
-            $query->whereIn('order_issues.id', explode(',', $condition['id']));
-        }
-        if (isset($condition['created_at_start'])) {
-            $query->where('order_issues.created_at', '>=', $condition['created_at_start'] . " 00:00:00");
-        }
-        if (isset($condition['created_at_end'])) {
-            $query->where('order_issues.created_at', '<=', $condition['created_at_end'] . " 23:59:59");
-        }
-        if (isset($condition['final_status'])) {
-            if ($condition['final_status'] == 'null') {
-                $query->whereNull('final_status');
-            } else {
-                $query->where('final_status', $condition['final_status']);
-            }
-        }
-        if (isset($condition['order_issue_type_id'])) {
-            $type_ids = explode(',',$condition['order_issue_type_id']);
-            $query->whereIn('order_issue_type_id', $type_ids);
-        }
-        if (!($condition['is_handle'] ?? false) && !($condition['final_status'] ?? false)) {
-            if (!(isset($condition['settlement_at_start']) || isset($condition['settlement_at_end']))) {
-                $query->where(function ($query) {
-                    $query->whereNotIn('final_status',['已解决','已归档'])->orWhereNull('final_status');
-                });
-            }
-        }
-        if (isset($condition['logistic_indemnity_money'])) {
-            if($condition['logistic_indemnity_money']== '是'){
-                $query->whereNotNull('logistic_indemnity_money');
-            }elseif($condition['logistic_indemnity_money']== '否'){
-                $query->whereNull('logistic_indemnity_money');
-            }
-        }
-        if (isset($condition['baoshi_indemnity_money'])) {
-            if($condition['baoshi_indemnity_money']== '是'){
-                $query->whereNotNull('baoshi_indemnity_money');
-            }elseif($condition['baoshi_indemnity_money']== '否'){
-                $query->whereNull('baoshi_indemnity_money');
-            }
-        }
-        if (isset($condition['rejectingStatus'])) {
-            $query->where('rejecting_status',$condition['rejectingStatus']);
-        }
-        if (isset($condition['order_issue_ids'])) {
-            $orderIssuesId = $condition['order_issue_ids'];
-            if (is_string($orderIssuesId)) {
-                $orderIssuesId = explode(',', $orderIssuesId);
-            }
-            $query->whereIn('order_issues.id', $orderIssuesId);
-        }
-        if (isset($condition['settlement_at_start']) || isset($condition['settlement_at_end'])) {
-            $query->whereHas('logs', function ($query) use ($condition) {
-                if (isset($condition['settlement_at_start'])) {
-                    $query->where('created_at', '>=', $condition['settlement_at_start'] . ' 00:00:00')->where('type', '结束');
-                }
-                if (isset($condition['settlement_at_end'])) {
-                    $query->where('created_at', '<=', $condition['settlement_at_end'] . ' 23:59:59')->where('type', '结束');
-                }
-            });
-        }
-        if(isset($condition['sendOrderClientCode'])){
-            $query->whereHas('secondOrder',function($query)use($condition){
-                $this->searchWay($query,$condition['sendOrderClientCode'],'client_code');
-            });
-            $query->orWhere('second_client_no',$condition['sendOrderClientCode']);
-        }
-        if(isset($condition['sendOrderLogisticNumber'])){
-            $query->whereHas('secondOrder.packages',function($query)use($condition){
-                $this->searchWay($query,$condition['sendOrderLogisticNumber'],'logistic_number');
-            });
-            $query->orWhere('second_logistic_number',$condition['sendOrderLogisticNumber']);
-        }
-        return $query;
-    }
-
-    private function isSearchLike($str)
-    {
-        if (substr($str, 0, 1) == "%" || substr($str, strlen($str) - 1, 1) == "%") {
-            return true;
-        }
-        return false;
-    }
-
-    private function searchWay($query, $param, $column)
-    {
-        if ($this->isSearchLike($param)) {
-            $query->where($column, 'like', $param);
-        } else {
-            $query->whereIn($column, array_filter(preg_split('/[,, ]+/is', $param)));
-        }
-        return $query;
-    }
-
-    public function getSqlList(array $params)
-    {
-        $orderPackageSql = OrderPackage::query()->selectRaw('order_packages.logistic_number order_package_logistic_number')
-            ->leftJoin('order_package_commodities','order_packages.id','order_package_commodities.order_package_id')
-            ->selectRaw('order_package_commodities.amount commodity_amount')
-            ->leftJoin('commodities','order_package_commodities.commodity_id','commodities.id')
-            ->selectRaw('commodities.name commodity_name,commodities.sku commodity_sku')
-            ->leftJoin('order_issues','order_packages.order_id','order_issues.order_id')
-            ->selectRaw('order_issues.id order_issue_id')
-            ->sql();
-        $secondOrderPackageSql = Order::query()->from('order_packages','s_o_p')->selectRaw('s_o_p.logistic_number')
-            ->leftJoin("orders as o_d","s_o_p.order_id","o_d.id")
-            ->leftJoin('order_package_commodities as s_o_p_c','s_o_p_c.order_package_id','s_o_p.id')
-            ->selectRaw('s_o_p_c.amount s_o_p_c_amount')
-            ->leftJoin('commodities as s_c','s_o_p_c.commodity_id','s_c.id')
-            ->selectRaw('s_c.sku s_c_sku,s_c.name s_c_name')
-            ->leftJoin('order_issues','o_d.client_code','order_issues.second_client_no')
-            ->selectRaw('order_issues.id order_issue_id')
-            ->sql();
-        $rejectedBillItemSql = RejectedBillItem::query()->selectRaw('rejected_bill_items.remark,rejected_bill_items.amount rejected_bill_amount,rejected_bill_items.name_goods,rejected_bill_items.barcode_goods')
-            ->leftJoin('rejected_bills',"rejected_bill_items.id_rejected_bill","rejected_bills.id")
-            ->leftJoin('order_issues','rejected_bills.logistic_number_return','order_issues.logistic_number_return')
-            ->selectRaw('order_issues.id order_issue_id')
-            ->sql();
-        $logSql = OrderIssueProcessLog::query()->selectRaw('order_issue_process_logs.content log_content,order_issue_process_logs.type log_type')
-            ->leftJoin('users','order_issue_process_logs.user_id','users.id')
-            ->selectRaw('users.name user_name')
-            ->leftJoin('order_issues','order_issue_process_logs.order_issue_id','order_issues.id')
-            ->selectRaw('order_issues.id order_issue_id')
-            ->sql();
-        $column = "order_issues.id,order_issues.rejected_bill_id,order_issues.rejecting_status,order_issues.created_at order_issues_created_at,order_issues.result_explain,order_issues.final_status,";
-        $column .= "order_issues.logistic_indemnity_money,order_issues.logistic_express_remission,order_issues.baoshi_indemnity_money,order_issues.baoshi_express_remission";
-        $orderIssueSql =  $this->getConditionQuery($params)->selectRaw($column)
-            ->leftJoin('order_issue_types','order_issues.order_issue_type_id','order_issue_types.id')
-            ->selectRaw('order_issue_types.`name` order_issue_type_name')
-            ->leftJoin('orders','order_issues.order_id','orders.id')
-            ->selectRaw('orders.id order_id,orders.address,orders.district,orders.city,orders.province,orders.consignee_phone,orders.consignee_name,orders.client_code,orders.created_at order_created_at')
-            ->leftJoin('logistics','logistics.id','orders.logistic_id')
-            ->selectRaw('logistics.name logistic_name')
-            ->leftJoin('owners','owners.id','orders.owner_id')
-            ->selectRaw('owners.name owner_name')
-            ->leftJoin('shops','orders.shop_id','shops.id')
-            ->selectRaw('shops.name shop_name')
-            ->leftJoin('orders as s_o','s_o.client_code','order_issues.second_client_no')
-            ->selectRaw('s_o.id s_o_id,s_o.client_code s_o_client_code')
-            ->leftJoin('logistics as s_logistics','s_o.logistic_id','s_logistics.id')
-            ->selectRaw('s_logistics.name s_logistics_name')
-            ->leftJoin('user_workgroups','user_workgroups.id','order_issues.user_workgroup_id')
-            ->selectRaw('user_workgroups.name user_workgroup_name')
-            ->sql();
-        return compact('orderPackageSql','secondOrderPackageSql','orderIssueSql','rejectedBillItemSql','logSql');
-    }
-
-    public function paginate(array $params)
-    {
-        return $query = $this->getConditionQuery($params)->paginate($params['paginate'] ?? 50);
-    }
-
     public function orderIssueTag(array $params)
     {
         $orderNos = $params['orderNos'];
@@ -529,19 +245,20 @@ class OrderIssueService
                 return ['success' => false,'message' => '二次客户订单号对应的订单已存在,无法更改快递单号'];
             }
         }
-        // 没有填写二次订单号
-        $order = app(OrderService::class)->getOrderByLogisticNumber($logisticNumber);
-        if (is_null($order)) {
-            $orderIssue->update(['second_logistic_number' => $logisticNumber]);
-            return ['success' => true, 'second_logistic_number' => $logisticNumber];
-        }
-        $orderIssue->update(['second_client_no' => $order->client_code]);
+//        // 没有填写二次订单号
+//        $order = app(OrderService::class)->getOrderByLogisticNumber($logisticNumber);
+//        if (is_null($order)) {
+//            $orderIssue->update(['second_logistic_number' => $logisticNumber]);
+//            return ['success' => true, 'second_logistic_number' => $logisticNumber];
+//        }
+//        $orderIssue->update(['second_client_no' => $order->client_code]);
+        $orderIssue->update(['second_logistic_number' => $logisticNumber]);
+        $order_package = OrderPackage::query()->selectRaw('order_id')->where('logistic_number',$logisticNumber);
         $order = Order::query()->with(['packages.commodities.commodity', 'logistic'])
-            ->where('id', $order->id)->first();
+            ->whereIn('id', $order_package)->first();
         return ['success' => true, 'order' => $order];
     }
 
-
     public function createOrderIssue($logisticNumber, $type, $result_explain, $importedStatus = '正常', $custom_code = null,$hiddenTag = null)
     {
         $orderHeaders = OracleDOCOrderHeader::query()->with(['oracleDOCOrderDetails', 'actAllocationDetails', 'oracleBASCode','orderType'])
@@ -604,19 +321,13 @@ class OrderIssueService
         }
     }
 
-    public function getJsonObj(array $params)
-    {
-        return  $this->getConditionQuery($params)->get();
-    }
-
-
     public function getRecycleBinPaginate($params){
         return OrderIssue::query()
             ->with(['order'=>function($query){
                 $query->with(['logistic','shop','owner','packages'=>function($query){
                 $query->with('commodities');
             }]);
-        },'rejectedBill.items','issueType','secondOrder.packages.commodities'])->onlyTrashed()->paginate($params['paginate'] ?? 50);
+        },'orderIssueRejectedBills.rejectedBill.items','issueType','secondOrder.packages.commodities'])->onlyTrashed()->paginate($params['paginate'] ?? 50);
     }
 
     public function recoverOrderIssue($ids)

+ 137 - 0
app/Services/OrderPackageReceivedSyncService.php

@@ -0,0 +1,137 @@
+<?php
+
+
+namespace App\Services;
+
+
+use App\OrderPackage;
+use Carbon\Carbon;
+use Exception;
+use Illuminate\Database\Eloquent\Collection;
+
+class OrderPackageReceivedSyncService
+{
+    protected $logisticSFService;
+    protected $logisticZopService;
+
+    /**
+     * 同步快递信息
+     * 1 如果当前时间大于初始化时间 每日执行一次,更新order_packages中创建时间大于初始化时间,没有异常,用户未收货的全部订单的快递路由状态
+     * 2 如果当前时间小于等于初始化时间,执行初始化脚本,将数据库中全部小于等于初始化时间的数据更新
+     * @throws Exception
+     */
+    public function syncLogisticRoute()
+    {
+        $this->update($this->getLogisticRoutes($this->getLogisticNumbers()));
+    }
+
+    /**
+     * 根据传递的承运商与快递单号更新快递信息
+     * @param array $logisticNumbers 快递单号
+     * example: ['SF' => ['SF1038651915891', 'SF1038651413847', 'SF1038611050071'],'ZT'=>['75424148714142','548464120822', '75424147834290']....]
+     * @throws Exception 快递接口调用或者返回的信息有误,无法更新指定的快递路由信息
+     */
+    public function syncLogisticRouteApi(array $logisticNumbers)
+    {
+        $this->update($this->getLogisticRoutes($logisticNumbers));
+    }
+
+    /**
+     * 获取快件揽收信息
+     * @param array $request [
+     * 'SF' => ['SF1038651915891', 'SF1038651413847', 'SF1038611050071'],
+     * 'ZT'=>['75424148714142','548464120822', '75424147834290']
+     * ]
+     * @return array
+     * @throws Exception
+     */
+    public function getLogisticRoutes(array $request): array
+    {
+        $this->logisticSFService = new LogisticSFService();
+        $this->logisticZopService = new LogisticZopService();
+        $resultSF = [];
+        $resultZT = [];
+        $resultYD = [];
+        $resultYT = [];
+        $resultOther = [];
+        foreach ($request as $key => $logisticNums) {
+            switch ($key) {
+                case "SF":
+                    $resultSF = $this->logisticSFService->get($logisticNums);
+                    break;
+                case "ZTO":
+//                    $resultZT = $this->logisticZopService->get($logisticNums);
+                    $resultZT = [];
+                    break;
+                case "YD":
+                    $resultYD = [];
+                    break;
+                case "YT":
+                    $resultYT = [];
+                    break;
+                default:
+                    $resultOther = [];
+                    break;
+            }
+        }
+        return array_merge($resultSF, $resultYD, $resultYT, $resultZT, $resultOther);
+    }
+
+    public function update(array $orderPackages)
+    {
+        foreach ($orderPackages as $data) {
+            $orderPackage = OrderPackage::query()->where('logistic_number', $data['logistic_number'])->first();
+            if (isset($data['status'])) $orderPackage->status = $data['status'];
+            if (isset($data['received_at'])) $orderPackage->received_at = $data['received_at'];
+            if (isset($data['exception'])) $orderPackage->exception = $data['exception'];
+            if (isset($data['transfer_status'])) $orderPackage->transfer_status = json_encode($data['transfer_status'],JSON_UNESCAPED_UNICODE);
+            $orderPackage->save();
+        }
+    }
+
+    /**
+     * 查询当前日期前的快递单号并按照承运商分类
+     */
+    public function getLogisticNumbers(): array
+    {
+        //初始化时间 2020-12-31 23:59:59
+        $initDate = Carbon::parse(config('api_logistic.init_date'));
+        $data = [];
+        $query = OrderPackage::query()
+            ->with(['order' => function ($query) {
+                return $query->with('logistic');
+            }]);
+        if (Carbon::now()->lte($initDate)) {//当前时间小于等于初始化时间
+            $query = $query->where('created_at', '>=', $initDate->subMonths(1)->toDateTimeString()); //初始化查询一个月的数据
+        } else {//当前时间大于初始化时间
+            $query = $query->where('created_at', '>=', $initDate->toDateTimeString()); //大于等于初始化时间的全部快递单号
+        }
+        $query = $query
+            ->where('exception', '否')
+            ->whereNull('received_at');
+        return $this->buildData($query->get(), $data);
+    }
+
+    /**
+     * 将orderPackage集合分类并摘取指定数据
+     * @param Collection $orderPackages
+     * @param array $data
+     * @return array
+     */
+    private function buildData(Collection $orderPackages, array $data): array
+    {
+        foreach ($orderPackages as $orderPackage) {
+            try {
+                $logisticCode = $orderPackage->order->logistic->code;
+            } catch (Exception $e) {
+                continue;
+            }
+            $key = config('api_logistic.logistic.' . $logisticCode);
+            if (!isset($data[$key])) {
+                $data[$key] = [];
+            }
+            $data[$key][] = $orderPackage->logistic_number;
+        }
+        return $data;
+    }
+}

+ 51 - 2
app/Services/OrderPackageService.php

@@ -118,6 +118,7 @@ class OrderPackageService
         $orders = $orderService->getByWmsOrders($orderHeaders);
         $packages = $this->getByOrderNos(data_get($orderHeaders,'*.orderno'));          // 已有
         $this->createOrderPackage($orderHeaders,$orders,$packages);                     // 创建package
+        $this->updatePackage($orderHeaders,$packages);
         $this->deleteUnnecessaryPackage($orderHeaders,$packages);     // 删除package
         unset($orders,$packages);       // 手动清除
     }
@@ -161,15 +162,26 @@ class OrderPackageService
         $logistic_numbers = array_diff(array_unique(data_get($orderHeader->actAllocationDetails,'*.picktotraceid')),['','*']);
         $inner_params = [];
         $date = Carbon::now()->format('Y-m-d H:i:s');
+        $sentAtMap = [];
+        foreach ($orderHeader->actAllocationDetails as $item){
+            $sentAtMap[$item->picktotraceid] = $item;
+        }
         foreach ($logistic_numbers as $logistic_number){
             $package = $dataHandlerService->getKeyValue(['logistic_number'=>$logistic_number],$packages_maps);
             if(isset($package))continue;
+            try {
+                $data = $sentAtMap[$logistic_number];
+            } catch (\Exception $e) {
+                $data = null;
+            }
             $inner_params[] = [
                 'order_id' => $order->id,
                 'logistic_number' => $logistic_number,
                 'created_at' => $date,
                 'updated_at' => $date,
-                'status' =>'无'
+                'status' => '无',
+                'owner_id' => $order->owner_id,
+                'sent_at' => $data ? $data->checktime:null,
             ];
         }
         return $inner_params;
@@ -198,7 +210,7 @@ class OrderPackageService
         if(count($packages)==0)return $packages;
         try {
             $bool = OrderPackage::query()->whereIn('id', $packages)->delete();
-            $orderPackageCommodities = OrderPackageCommodities::query()->where('order_package_id',$packages)->get();
+            $orderPackageCommodities = OrderPackageCommodities::query()->whereIn('order_package_id',$packages)->get();
             $orderPackageCommoditiesService->deleteOrderCommodities($orderPackageCommodities);
             $bool ? LogService::log(__METHOD__,__FUNCTION__,'删除多余包裹 ids:'.json_encode($packages)) : null;
         } catch (\Exception $e) {
@@ -206,4 +218,41 @@ class OrderPackageService
         }
     }
 
+    private function updatePackage($orderHeaders, $packages)
+    {
+        $map = $this->getSentAtMap($orderHeaders);
+        $update_params = [];
+        $update_params[] = ['id','sent_at'];
+        foreach ($packages as $package) {
+            if ($package->sent_at) continue;
+            try {
+                $data = $map[$package->logistic_number];
+            } catch (\Exception $e) {
+                continue;
+            }
+            $update_params[] = [
+                'id'=>$package->id,
+                'sent_at' => $data->checktime,
+            ];
+        }
+        $this->batchUpdate($update_params);
+    }
+
+    /**
+     * @param $orderHeaders
+     * @return array
+     */
+    private function getSentAtMap($orderHeaders): array
+    {
+        $map = [];
+        foreach ($orderHeaders as $orderHeader) {
+            $actAllocationDetails = $orderHeader->actAllocationDetails;
+            foreach ($actAllocationDetails as $actAllocationDetail) {
+                $logistic_number = $actAllocationDetail->picktotraceid;
+                $map[$logistic_number] = $actAllocationDetail;
+            }
+        }
+        return $map;
+    }
+
 }

+ 23 - 14
app/Services/OrderService.php

@@ -579,11 +579,19 @@ class OrderService
         return $order = Order::query()->with('packages.commodities.commodity')->where('code',$code)->first();
     }
 
-    public function syncOrderInfo($orderHeaders,$sync_order_commodity = true){
+    /**
+     * 同步 Order信息
+     *
+     * @param array $orderHeaders
+     * @param bool $syncOrderCommodity
+     * @param bool $syncOrderPackage
+     * @param bool $syncOrderPackageCommodity
+     */
+    public function syncOrderInfo($orderHeaders,$syncOrderCommodity = true,$syncOrderPackage = true,$syncOrderPackageCommodity = true){
         $this->syncOrderByWMSOrderHeaders($orderHeaders);
-        if($sync_order_commodity)app("OrderCommodityService")->syncOrderCommodity($orderHeaders);
-        app('OrderPackageService')->syncOrderPackage($orderHeaders);
-        app("OrderPackageCommoditiesService")->syncOrderPackageCommodities($orderHeaders);
+        if($syncOrderCommodity)app("OrderCommodityService")->syncOrderCommodity($orderHeaders);
+        if($syncOrderPackage)app('OrderPackageService')->syncOrderPackage($orderHeaders);
+        if($syncOrderPackageCommodity)app("OrderPackageCommoditiesService")->syncOrderPackageCommodities($orderHeaders);
     }
 
     public function syncOrder(&$orderHeaders)
@@ -657,9 +665,8 @@ class OrderService
         }
         unset($created_params);
         $update_params = [
-            ['id','code','warehouse_id','owner_id','batch_id','shop_id','logistic_id','consignee_name','consignee_phone','province','city','district','address','client_code','wms_status','created_at','updated_at','wms_edittime','order_type']
+            ['id','code','warehouse_id','owner_id','batch_id','shop_id','logistic_id','consignee_name','consignee_phone','province','city','district','address','client_code','wms_status','created_at','updated_at','wms_edittime','order_type','frozen']
         ];
-
         $update_order->each(function($item)use(&$update_params){
             $update_params[] = $item->toArray();
         });
@@ -749,6 +756,7 @@ class OrderService
             'wms_edittime' => $orderHeader['edittime'],
             'wms_status' => $orderHeader->oracleBASCode->codename_c??'',
             'order_type' => $orderHeader->orderType->codename_c??'',
+            'frozen' => Order::getFrozen($orderHeader->releasestatus),
             'updated_at' => $date,
             'created_at' => $orderHeader['addtime']
         ];
@@ -944,14 +952,10 @@ class OrderService
         });
     }
 
-    public function syncOrderByWmsOrderNos($orderNos)
-    {
-        if(empty($orderNos))return ;
-        if(count($orderNos)==0)return;
-        $orderHeaders = $this->oracleDOCOrderHeaderService->getOrderByOrderNos($orderNos);
-        $this->syncOrderByWMSOrderHeaders($orderHeaders);
-    }
-
+    /**
+     * 根据 订单号集合 OrderNo 同步订单
+     * @param array $orderNos
+     */
     public function syncOrderInfoByWmsOrderNos($orderNos)
     {
         if(empty($orderNos))return ;
@@ -960,9 +964,14 @@ class OrderService
         $this->syncOrderInfoByWMSOrderHeaders($orderHeaders);
     }
 
+    /**
+     * 根据表头信息 OrderHeader 集合 同步订单
+     * @param array $orderHeaders
+     */
     public function syncOrderInfoByWMSOrderHeaders($orderHeaders){
         if(empty($orderHeaders))return ;
         if(count($orderHeaders)==0)return;
+        $orderHeaders = app('OracleDocOrderHeaderService')->loadMissing($orderHeaders);
         $this->syncOrderByWMSOrderHeaders($orderHeaders);
         app('OrderPackageService')->syncOrderPackage($orderHeaders);
         app("OrderPackageCommoditiesService")->syncOrderPackageCommodities($orderHeaders);

+ 6 - 10
app/Services/PackageService.php

@@ -16,17 +16,13 @@ Class PackageService
 {
     use ServiceAppAop;
     private function conditionQuery($params){
-        $packages = OrderPackage::query()->with(['order','paperBox','measuringMachine'])
-        ->whereHas("order",function ($query){
-            /** @var Builder $query */
-            $ownerIds=app('UserService')->getPermittingOwnerIds(Auth::user());
-            $query->with('owner','logistic')->whereIn("owner_id",$ownerIds ?? []);
-        })->orderBy(TABLE.'id','DESC');
+        $ownerIds=app('UserService')->getPermittingOwnerIds(Auth::user());
+        $packages = OrderPackage::query()->with(['order'=>function($query){
+            return  $query->with(['owner','logistic']);
+        },'paperBox','measuringMachine'])
+        ->whereIn('owner_id',$ownerIds)->orderBy(TABLE.'id','DESC');
         if ($params['owner_id'] ?? false){
-            $owner_id = explode(',',$params['owner_id']);
-            $packages->whereHas('order',function ($query)use($owner_id){
-                $query->whereIn('owner_id',$owner_id);
-            });
+            $packages->whereIn('owner_id', explode(',',$params['owner_id']));
             unset($params['owner_id']);
         }
         if ($params['logistic_number'] ?? false){

+ 104 - 15
app/Services/RejectedBillService.php

@@ -2,14 +2,22 @@
 
 namespace App\Services;
 
+use App\OracleActAllocationDetails;
 use App\OracleDOCASNHeader;
 use App\OracleDOCOrderHeader;
+use App\Order;
 use App\OrderIssue;
+use App\OrderIssueRejectedBill;
+use App\OrderPackage;
 use App\RejectedBill;
 use App\Services\common\BatchUpdateService;
 use App\Services\common\DataHandlerService;
+use App\StoreRejected;
 use Carbon\Carbon;
 use App\Traits\ServiceAppAop;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Query\Builder;
+use function Symfony\Component\String\s;
 
 
 Class RejectedBillService
@@ -34,6 +42,17 @@ Class RejectedBillService
         return RejectedBill::query()->create($params);
     }
 
+    /**
+     * 连接问题件
+     *
+     * @param RejectedBill $rejectedBill
+     */
+    public function joinOrderIssue($rejectedBill)
+    {
+        $rejectedBill->joinOrderIssue();
+    }
+
+
     /**
      * 同步退回单号
      * @param RejectedBill $rejectedBill
@@ -45,24 +64,25 @@ Class RejectedBillService
 
     public function syncLoadedStatusByAsnHerder($asnHerders)
     {
-        $updateParams=$this->getNeedUpdateLoadedStatusByWms($asnHerders);
-        if (!$updateParams)return;
-        if (count($updateParams) > 1) $this->batchUpdate($updateParams);
+        //是否审核
         $updates=$this->getNeedUpdateCheckedStatusByWms($asnHerders);
-        if (!$updates)return;
         if (count($updates) > 1) $this->batchUpdate($updates);
+        //是否入库
+        $updateParams=$this->getNeedUpdateLoadedStatusByWms($asnHerders);
+        if (count($updateParams) > 1) $this->batchUpdate($updateParams);
     }
 
     public function getNeedUpdateLoadedStatusByWms($asnHerders)
     {
-        if ($asnHerders->isEmpty()) return null;
+
+        if (!$asnHerders) return null;
         $updateCollect = $this->getUpdateCollect($asnHerders);
-        if ($updateCollect->isEmpty()) return null;
+        if (!$updateCollect) return null;
         $logisticNumberReturn = $this->getLogisticNumberReturn($updateCollect);
         $rejectedBills = $this->getRejectedBills($logisticNumberReturn);
         if (!$rejectedBills) return null;
         $updateParams = [[
-            'logistic_number_return', 'is_loaded', 'updated_at'
+            'id','logistic_number_return', 'is_loaded', 'updated_at'
         ]];
         $updated_at = Carbon::now()->toDateTimeString();
         /** @var DataHandlerService $dataHandlerService */
@@ -75,6 +95,7 @@ Class RejectedBillService
             if ($data->asnreference3) {
                 $rejectedBill = $dataHandlerService->getKeyValue(['logistic_number_return' => $data->asnreference3], $rejectedBills_map);
                 if ($rejectedBill && $rejectedBill->is_loaded != 1) $updateParams[] = [
+                    'id'=>$rejectedBill->id,
                     'logistic_number_return' => $data->asnreference3,
                     'is_loaded' => 1,
                     'updated_at' => $updated_at,
@@ -85,6 +106,7 @@ Class RejectedBillService
                 if (count($result)<1) continue;
                 $rejectedBill = $dataHandlerService->getKeyValue(['logistic_number_return' => $result[0]], $rejectedBills_map);
                 if ($rejectedBill && $rejectedBill->is_loaded != 1) $updateParams[] = [
+                    'id'=>$rejectedBill->id,
                     'logistic_number_return' => $result[0],
                     'is_loaded' => 1,
                     'updated_at' => $updated_at,
@@ -139,12 +161,12 @@ Class RejectedBillService
 
     public function getNeedUpdateCheckedStatusByWms($asnHerders)
     {
-        if ($asnHerders->isEmpty()) return null;
+        if (!$asnHerders) return null;
         $logisticNumberReturn = $this->getLogisticNumberReturn($asnHerders);
         $rejectedBills = $this->getRejectedBills($logisticNumberReturn);
         if (!$rejectedBills) return null;
         $updateParams = [[
-            'logistic_number_return', 'is_checked','checked_numbers','updated_at'
+            'id','logistic_number_return', 'is_checked','checked_numbers','updated_at'
         ]];
         $updated_at = Carbon::now()->toDateTimeString();
         /** @var DataHandlerService $dataHandlerService */
@@ -155,6 +177,7 @@ Class RejectedBillService
             if ($data->asnreference3) {
                 $rejectedBill = $dataHandlerService->getKeyValue(['logistic_number_return' => $data->asnreference3], $rejectedBills_map);
                 if ($rejectedBill && $rejectedBill->is_checked != 1) $updateParams[] = [
+                    'id'=>$rejectedBill->id,
                     'logistic_number_return' => $data->asnreference3,
                     'is_checked' => 1,
                     'checked_numbers' => $rejectedBill->makeCheckedNumbers(),
@@ -165,12 +188,14 @@ Class RejectedBillService
                 preg_match("/[a-zA-Z]{0,5}\d{6,20}/", $data->notes, $result);
                 if (count($result)<1) continue;
                 $rejectedBill = $dataHandlerService->getKeyValue(['logistic_number_return' => $result[0]], $rejectedBills_map);
-                if ($rejectedBill && $rejectedBill->is_checked != 1) $updateParams[] = [
-                    'logistic_number_return' => $result[0],
-                    'is_checked' => 1,
-                    'checked_numbers' => $rejectedBill->makeCheckedNumbers(),
-                    'updated_at' => $updated_at,
-                ];
+                if ($rejectedBill && $rejectedBill->is_checked != 1)
+                    $updateParams[] = [
+                        'id'=>$rejectedBill->id,
+                        'logistic_number_return' => $result[0],
+                        'is_checked' => 1,
+                        'checked_numbers' => $rejectedBill->makeCheckedNumbers(),
+                        'updated_at' => $updated_at,
+                    ];
                 unset($result);
             }
         }
@@ -195,4 +220,68 @@ Class RejectedBillService
         }
         return null;
     }
+
+    /**
+     * @param string $logisticNumber
+     * @return array|Builder|Model|object|null
+     */
+    public function findOrderByOrderPackage($logisticNumber)
+    {
+        // 本地订单的快递单号 原单退回
+        $order_package_query =  OrderPackage::query()->selectRaw('order_id')->where('logistic_number',$logisticNumber);
+        /** @var Order $order */
+        $order = Order::query()->whereIn('id',$order_package_query )->first();
+        if($order){
+            $order = $order->toArray();
+            $order['logistic_number'] = '原单退回';
+            return $order;
+        }
+        return null;
+    }
+
+    public function findOrderByStoreRejected($logisticNumber)
+    {
+        $store_rejected_query = StoreRejected::query()->selectRaw('order_id')->where('logistic_number_return',$logisticNumber);
+        $order = Order::query()->whereIn('id',$store_rejected_query)->first();
+        if($order){
+            $order_package = OrderPackage::query()->where('order_id',$order->id)->first();
+            $order = $order->toArray();
+            $order['logistic_number'] = $order_package['logistic_number'] ?? '';
+            return $order;
+        }
+        return null;
+    }
+
+
+    public function findOrderByOrderHeader($logisticNumber)
+    {
+        $act_allocation_details_query = OracleActAllocationDetails::query()->selectRaw('OrderNo')->where('pickToTraceId',$logisticNumber);
+        /** @var OracleDOCOrderHeader $order_header */
+        $order_header = OracleDOCOrderHeader::query()->whereIn('OrderNo',$act_allocation_details_query)->first();
+        if($order_header){
+            return [
+                'logistic_id' => $order_header->getLogistic()['id'] ?? '',
+                'owner_id' => $order_header->getOwner()['id'] ?? '',
+                'consignee_name' => $order_header['c_contact'] ?? '' ,
+                'consignee_phone' =>  $order_header['c_tel2'] ?? $order_header['c_tel1'],
+                'client_code'  => $order_header['soreference1'] ?? '',
+                'logistic_number'  => $order_header['soreference5'] ?? '',
+            ];
+        }
+        return null;
+    }
+    public function findOrderByOrderIssue($logisticNumberReturn)
+    {
+        // 问题件关联的退回单
+        $order_issue_rejected_bill_query = OrderIssueRejectedBill::query()->selectRaw('order_issue_id')->where('logistic_number_return',$logisticNumberReturn);
+        $oder_issue_query = OrderIssue::query()->selectRaw('order_id')->whereIn('id',$order_issue_rejected_bill_query);
+        $order = Order::query()->whereIn('id',$oder_issue_query)->first();
+        if($order){
+            $order_package = OrderPackage::query()->where('order_id',$order->id)->first();
+            $order = $order->toArray();
+            $order['logistic_number'] = $order_package['logistic_number'] ?? '';
+            return $order;
+        }
+        return null;
+    }
 }

+ 0 - 1
app/Services/StationTaskCommodityService.php

@@ -52,7 +52,6 @@ class StationTaskCommodityService
             );
         }
         $this->stationTaskService->registerSubTasks($stationTasks_toAttach,$stationTaskCommodities_listByBatch);
-
     }
 
     function createByBatch(Batch $batch): Collection

+ 1 - 0
app/Services/WaybillService.php

@@ -36,6 +36,7 @@ Class WaybillService
             'origination' => ['like' => ''],
             'destination' => ['like' => ''],
             'source_bill' => ['like' => ''],
+            'car_owner_info' => ['like' => ''],
             'created_at_start' => ['alias' => 'created_at' , 'startDate' => ':00'],
             'created_at_end' => ['alias' => 'created_at' , 'endDate' => ':59'],
             'uriType' => ['alias' => 'type'],

+ 6 - 0
app/UserWorkgroup.php

@@ -6,6 +6,7 @@ use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\LogModelChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
 class UserWorkgroup extends Model
 {
@@ -35,4 +36,9 @@ class UserWorkgroup extends Model
             return $this['signs']['mark'] == '是' ? true : false;
         }
     }
+
+    public function orderIssues(): BelongsToMany
+    {
+        return $this->belongsToMany(OrderIssue::class);
+    }
 }

+ 23 - 0
app/library/zop/README.md

@@ -0,0 +1,23 @@
+# 中通开放平台SDK(php版)
+
+## 使用方式
+
+```php
+use App\library\zop\ZopClient;
+use App\library\zop\ZopProperties;
+use App\library\zop\ZopRequest;
+
+// ZopProperties类的构造方法接收两个参数,分别是companyid和key,都需要注册中通开放平台后到个人中心查看
+$properties = new ZopProperties("kfpttestCode", "kfpttestkey==");
+$client = new ZopClient($properties);
+
+$request = new ZopRequest();
+$request->setUrl("http://58.40.16.120:9001/submitOrderCode");
+$request->setData('{"data":{"content":{"branchId":"","buyer":"","collectMoneytype":"CNY","collectSum":"12.00","freight":"10.00","id":"xfs2018031500002222333","orderSum":"0.00","orderType":"1","otherCharges":"0.00","packCharges":"1.00","premium":"0.50","price":"126.50","quantity":"2","receiver":{"address":"育德路XXX号","area":"501022","city":"四川省,XXX,XXXX","company":"XXXX有限公司","email":"yyj@abc.com","id":"130520142097","im":"yangyijia-abc","mobile":"136*****321","name":"XXX","phone":"010-222***89","zipCode":"610012"},"remark":"请勿摔货","seller":"","sender":{"address":"华新镇华志路XXX号","area":"310118","city":"上海,上海市,青浦区","company":"XXXXX有限公司","email":"ll@abc.com","endTime":1369033200000,"id":"131*****010","im":"1924656234","mobile":"1391***5678","name":"XXX","phone":"021-87***321","startTime":1369022400000,"zipCode":"610012"},"size":"12,23,11","tradeId":"2701843","type":"1","typeId":"","weight":"0.753"},"datetime":"2018-3-30 12:00:00","partner":"test","verify":"ZTO123"}}');
+
+echo $client->execute($request);
+```
+
+## 其他
+1. 该项目刚创建,功能还很不完善,如有问题请提issue
+2. 由于中通开放平台各个接口返回值格式没有统一,所以未封装返回值,未来可能会做封装

+ 61 - 0
app/library/zop/ZopClient.php

@@ -0,0 +1,61 @@
+<?php
+
+
+namespace App\library\zop;
+use App\library\zop\ZopHttpUtil;
+
+class ZopClient
+{
+    private $zopProperties;
+
+    private $httpClient;
+    /**
+     * ZopClient constructor.
+     * @param $zopProperties
+     */
+    public function __construct($zopProperties)
+    {
+        $this->zopProperties = $zopProperties;
+        $this->httpClient = new ZopHttpUtil();
+    }
+
+    public function execute($zopRequest)
+    {
+        if($zopRequest->getBody()==null) {
+            $url = $zopRequest->getUrl();
+            $params = $zopRequest->getParams();
+            $fixedParams = array();
+            foreach ($params as $k => $v) {
+                if (gettype($v) != "string") {
+                    $fixedParams += [$k => json_encode($v)];
+                } else {
+                    $fixedParams += [$k => $v];
+                }
+            }
+            $str_to_digest = "";
+            foreach ($fixedParams as $k => $v) {
+                $str_to_digest = $str_to_digest .$k ."=" .$v ."&";
+            }
+            $str_to_digest = substr($str_to_digest, 0, -1) .$this->zopProperties->getKey();
+            $data_digest = base64_encode(md5($str_to_digest, TRUE));
+            $headers = array(
+                "Content-Type: application/x-www-form-urlencoded; charset=UTF-8",
+                "x-companyid: " .$this->zopProperties->getCompanyid(),
+                "x-datadigest: " .$data_digest
+            );
+            return $this->httpClient->post($url, $headers, http_build_query($fixedParams), 2000);
+        } else{
+            $url = $zopRequest->getUrl();
+            $body = $zopRequest->getBody();
+            $str_to_digest = $body.$this->zopProperties->getKey();
+            $data_digest = base64_encode(md5($str_to_digest, TRUE));
+            $headers = array(
+                "Content-Type: application/json; charset=UTF-8",
+                "x-companyid: ".$this->zopProperties->getCompanyid(),
+                "x-datadigest: ".$data_digest
+            );
+            return $this->httpClient->post($url, $headers, $body, 2000);
+
+        }
+    }
+}

+ 20 - 0
app/library/zop/ZopHttpUtil.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\library\zop;
+
+class ZopHttpUtil
+{
+    public function post($url, $headers, $querystring, $timeout)
+    {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);//设置链接
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置是否返回信息
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);//设置HTTP头
+        curl_setopt($ch, CURLOPT_POST, 1);//设置为POST方式
+        curl_setopt($ch, CURLOPT_TIMEOUT_MS, $timeout);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $querystring);
+        $response = curl_exec($ch);
+        return $response;
+    }
+
+}

+ 46 - 0
app/library/zop/ZopProperties.php

@@ -0,0 +1,46 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: choco
+ * Date: 6/13/18
+ * Time: 5:47 PM
+ */
+namespace App\library\zop;
+
+
+class ZopProperties
+{
+    private $companyid;
+    private $key;
+
+    /**
+     * ZopProperties constructor.
+     * @param $companyid
+     * @param $key
+     */
+    public function __construct($companyid, $key)
+    {
+        $this->companyid = $companyid;
+        $this->key = $key;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getCompanyid()
+    {
+        return $this->companyid;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getKey()
+    {
+        return $this->key;
+    }
+
+
+
+
+}

+ 59 - 0
app/library/zop/ZopRequest.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\library\zop;
+
+
+class ZopRequest
+{
+    private $url;
+    private $params = Array();
+    private $body;
+
+    public function addParam($k, $v)
+    {
+        $this->params += [$k => $v];
+    }
+
+    /**
+     * @param mixed $url
+     */
+    public function setUrl($url)
+    {
+        $this->url = $url;
+    }
+
+    public function setData($data)
+    {
+        $this->params = json_decode($data);
+    }
+
+    public function setBody($body)
+    {
+        $this->body = $body;
+    }
+
+    public function getBody()
+    {
+        return $this->body;
+    }
+
+
+
+    /**
+     * @return mixed
+     */
+    public function getUrl()
+    {
+        return $this->url;
+    }
+
+    /**
+     * @return array
+     */
+    public function getParams()
+    {
+        return $this->params;
+    }
+
+
+}

+ 60 - 0
bashupMysql.sh

@@ -0,0 +1,60 @@
+#!/bin/bash
+
+#设置mysql的备份保存目录
+folder=/etc/bashupMysql
+cd $folder
+#当前日期
+time_now=$(date  "+%Y-%m-%d")
+#当前时间的前30天 %H:%M:%S
+time_30day_ago=$(date -d"30 day ago" "+%Y-%m-%d 00:00:00")
+#当前日期的前三天
+time_3day_ago=$(date -d"3 day ago" "+%Y-%m-%d")
+#数据库服务器ip,填写服务器的公网地址即可
+host="was.baoshi56.com"
+test_host="101.133.135.193"
+#用户名
+user="developer"
+test_user="bswas_test"
+#密码
+password="developer"
+test_password="123456"
+#要备份的数据库名
+db="bswas"
+test_db="bswas_test"
+#执行备份语句 --single-transaction 是在导出数据时不锁表
+mysqldump -h$host -u$user -p$password --single-transaction $db --ignore-table=$db.orders --ignore-table=$db.stores --ignore-table=$db.store_items --ignore-table=$db.commodities --ignore-table=$db.commodity_barcodes --ignore-table=$db.logs --ignore-table=$db.order_commodities --ignore-table=$db.order_bins --ignore-table=$db.w_m_s_waybill_orders --ignore-table=$db.rejected_bills --ignore-table=$db.rejected_bill_items --ignore-table=$db.w_m_s_reflect_packages --ignore-table=$db.w_m_s_reflect_receive_skus --ignore-table=$db.w_m_s_reflect_receives --ignore-table=$db.order_counting_records --ignore-table=$db.order_package_commodities --ignore-table=$db.order_packages --ignore-table=$db.packages> $time_nowall.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_nowall.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db orders --where="created_at>='$time_30day_ago'" > $time_noworders.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noworders.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db stores --where="created_at>='$time_30day_ago'" > $time_nowstores.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_nowstores.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db store_items --where="created_at>='$time_30day_ago'" > $time_nowstore_items.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_nowstore_items.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db commodities --where="created_at>='$time_30day_ago'" > $time_nowcommodities.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_nowcommodities.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db commodity_barcodes --where="created_at>='$time_30day_ago'" > $time_nowcommodity_barcodes.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_nowcommodity_barcodes.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db order_counting_records --where="created_at>='$time_30day_ago'" > $time_noworder_counting_records.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noworder_counting_records.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db order_bins --where="created_at>='$time_30day_ago'" > $time_noworder_bins.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noworder_bins.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db order_packages --where="created_at>='$time_30day_ago'" > $time_noworder_packages.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noworder_packages.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db order_package_commodities --where="created_at>='$time_30day_ago'" > $time_noworder_package_commodities.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noworder_package_commodities.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db rejected_bills --where="created_at>='$time_30day_ago'" > $time_nowrejected_bills.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_nowrejected_bills.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db rejected_bill_items --where="created_at>='$time_30day_ago'" > $time_nowrejected_bill_items.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_nowrejected_bill_items.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db w_m_s_reflect_receive_skus --where="created_at>='$time_30day_ago'" > $time_noww_m_s_reflect_receive_skus.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noww_m_s_reflect_receive_skus.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db w_m_s_reflect_packages --where="created_at>='$time_30day_ago'" > $time_noww_m_s_reflect_packages.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noww_m_s_reflect_packages.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db w_m_s_reflect_receives --where="created_at>='$time_30day_ago'" > $time_noww_m_s_reflect_receives.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noww_m_s_reflect_receives.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db w_m_s_waybill_orders --where="created_at>='$time_30day_ago'" > $time_noww_m_s_waybill_orders.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noww_m_s_waybill_orders.sql
+mysqldump -h$host -u$user -p$password --single-transaction -q -e $db order_commodities --where="created_at>='$time_30day_ago'" > $time_noworder_commodities.sql
+mysql  -u$test_user -p$test_password  $test_db< $time_noworder_commodities.sql
+
+sudo rm -rf $time_3day_ago*

+ 5 - 1
composer.json

@@ -59,7 +59,11 @@
             "database/factories"
         ],
         "files": [
-            "app/Utils/helpers.php"
+            "app/Utils/helpers.php",
+            "app/library/zop/ZopClient.php",
+            "app/library/zop/ZopHttpUtil.php",
+            "app/library/zop/ZopProperties.php",
+            "app/library/zop/ZopRequest.php"
         ]
     },
     "autoload-dev": {

File diff suppressed because it is too large
+ 44 - 468
composer.lock


+ 110 - 0
config/api_logistic.php

@@ -0,0 +1,110 @@
+<?php
+return [
+    'logistic'=>[
+        'ZTO' => 'ZTO',
+        'SF' => 'SF',
+        'YUNDA' => 'YUNDA',
+        'STO' => 'STO',
+        'YTO' => 'YTO',
+        'POSTB' => 'OTHER',
+        'EMS' => 'OTHER',
+        'OTHER' => 'OTHER',
+        'DFZPS' => 'OTHER',
+        'DBKD' => 'OTHER',
+        'DBWL' => 'OTHER',
+        'ANWL' => 'OTHER',
+        'ANWLDF' => 'OTHER',
+        'BSZFC' => 'OTHER',
+        'BSZFCDF' => 'OTHER',
+        'BSZX' => 'OTHER',
+        'BSZXDF' => 'OTHER',
+        'DBKDDF' => 'OTHER',
+        'DBWLDF' => 'OTHER',
+        'ECJG' => 'OTHER',
+        'GYZT' => 'OTHER',
+        'KCTZ' => 'OTHER',
+        'KHZT' => 'OTHER',
+        'KNDB' => 'OTHER',
+        'KYSY' => 'OTHER',
+        'KYSYLY' => 'OTHER',
+        'KYSYLYDF' => 'OTHER',
+        'SFCC' => 'SF',
+        'SFCCDF' => 'SF',
+        'SFGJBK' => 'SF',
+        'SFGJTH' => 'SF',
+        'SFJR' => 'SF',
+        'SFJRDF' => 'SF',
+        'SFLD' => 'SF',
+        'SFSX' => 'SF',
+        'SFSY' => 'SF',
+        'SFSYDF' => 'SF',
+        'SFSYQHD' => 'SF',
+        'SFTH' => 'SF',
+        'SFTHBJ' => 'SF',
+        'SFTHDF' => 'SF',
+        'SFTHDFBJ' => 'SF',
+        'SFTHQHD' => 'SF',
+        'SFTHZMJ' => 'SF',
+        'SFTHZMJDF' => 'SF',
+        'SHUNFENG' => 'OTHER',
+        'WPSFSY' => 'SF',
+        'WPZTO' => 'ZTO',
+        'WXWL' => 'OTHER',
+        'XJWL' => 'OTHER',
+        'XJWLDF' => 'OTHER',
+        'ZT' => 'OTHER',
+        'YCT' => 'OTHER',
+        'ZHUANGXIAN' => 'OTHER',
+        'CHANGTONG' => 'OTHER',
+        'YMDD' => 'OTHER',
+        'GUONENG' => 'OTHER',
+        'DUMMY' => 'OTHER',
+        'SANGSONG' => 'OTHER',
+        'JITU' => 'OTHER',
+        'JDKD' => 'OTHER',
+        'SXJD' => 'OTHER',
+        'EMS标准快递' => 'OTHER',
+        '圆通速递' => 'OTHER',
+        '京东快递' => 'OTHER',
+        '邮政快递包裹' => 'OTHER',
+        'SFGJBKDF' => 'SF',
+        '飞扬' => 'OTHER',
+        '测试承运商' => 'OTHER',
+        '货拉拉' => 'OTHER',
+        '运满满' => 'OTHER',
+        '马玉亮' => 'OTHER',
+        '其他' => 'OTHER',
+    ],
+    //丰桥
+    'SF' => [
+        'url' =>  'https://bspsw.sf-express.com/sfexpressService',
+        'head' =>  'BSGYLGL',
+        'check_word' =>  'DcauTQEavq5qqpFaYmltzR7gzVCTjvtz',
+        'max_size' => 10,
+        'op_code_map' => [
+            30 => '快件在【XXX营业点】已装车,准备发往 【XXX集散中心】',
+            31 => '快件到达 【XXX集散中心】',
+            33 => '派件异常原因',
+            3036 => '快件在XXX ,准备送往下一站',
+            44 => '正在派送途中,请您准备签收(派件人:XXX,电话:XXX)',
+            50 => '顺丰已收件',
+            70 => '由于XXX原因 派件不成功',
+            80 => '已签收,感谢使用顺丰,期待再次为您服务',
+            8000 => '在官网"运单资料&签收图",可查看签收人信',
+            130 => '快件到达顺丰店/站',
+            123 => '快件正送往顺丰店/站',
+            607 => '代理收件',
+            99 => '应客户要求,快件正在转寄中',
+            648 => '快件已退回/转寄,新单号为: XXX,快件正在转寄中',
+        ],
+        'received_code' => 80,
+        'error_code' => 33,
+    ],
+    //中通 https://op.zto.cn/#/Console?type=API
+    'ZTO' => [
+        'url' =>  'https://japi.zto.com/zto.open.getOrderInfo',
+        'x-appKey' => 'c51c718eb899e9f706979',
+        'x-dataDigest' => '9f664e3ab08049874aa417720840161a',
+    ],
+    'init_date' => '2021-01-17 23:59:59',
+];

+ 2 - 1
database/factories/OracleActAllocationDetailsFactory.php

@@ -13,6 +13,7 @@ $factory->define(OracleActAllocationDetails::class, function (Faker $faker) {
         'qtyordered' => $faker->numberBetween(1,50),
         'qty_each' => $faker->numberBetween(1,50),
         'location' => $faker->md5,
-        'picktotraceid'  => $faker->uuid
+        'picktotraceid' => $faker->uuid,
+        'checktime' => now(),
     ];
 });

+ 16 - 16
database/factories/OrcaleDOCOrderHeaderFactory.php

@@ -7,22 +7,22 @@ use Faker\Generator as Faker;
 
 $factory->define(OracleDOCOrderHeader::class, function (Faker $faker) {
     return [
-        'ORDERNO' =>  \Illuminate\Support\Str::random(5).'_test',
-        'CUSTOMERID' => 'test',
-        'WAVENO' => 'test'.(string)rand(0,1000),
-        'ORDERTIME' =>\Carbon\Carbon::now()->subSeconds(10),
-        'CONSIGNEEID' => 'test',
-        'ADDTIME' =>\Carbon\Carbon::now()->subSeconds(5),
-        'EDITTIME' => \Carbon\Carbon::now()->subSeconds(1),
-        'EDISENDFLAG' => 'Y',
-        'SOSTATUS' => '99',
-        'ISSUEPARTYNAME'=> 'test_issuepartyname',
-        'RELEASESTATUS' => 'N',
-        'ARCHIVEFLAG' => 'Y',
-        'CHANNEL' =>'test_CHANNEL',
-        'ALLOWSHIP' =>  'N' , //允许发运
-        'YW_EDISENDFLAG' => 'N',
-        'NOTES' => 'xx',
+        'orderno' =>  \Illuminate\Support\Str::random(5).'_test',
+        'customerid' => 'test',
+        'waveno' => 'test'.(string)rand(0,1000),
+        'ordertime' =>\Carbon\Carbon::now()->subSeconds(10),
+        'consigneeid' => 'test',
+        'addtime' =>\Carbon\Carbon::now()->subSeconds(5),
+        'edittime' => \Carbon\Carbon::now()->subSeconds(1),
+        'edisendflag' => 'Y',
+        'sostatus' => '99',
+        'issuepartyname'=> 'test_issuepartyname',
+        'releasestatus' => 'N',
+        'archiveflag' => 'Y',
+        'channel' =>'test_CHANNEL',
+        'allowship' =>  'N' , //允许发运
+        'yw_edisendflag' => 'N',
+        'notes' => 'xx',
     ];
 });
 

+ 13 - 0
database/factories/OrderIssueRejectedBillFactory.php

@@ -0,0 +1,13 @@
+<?php
+
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
+
+use App\Model;
+use Faker\Generator as Faker;
+
+$factory->define(\App\OrderIssueRejectedBill::class, function (Faker $faker) {
+    return [
+        'order_issue_id' => rand(0,10000),
+        'logistic_number_return' => $faker->phoneNumber
+    ];
+});

+ 32 - 0
database/migrations/2020_12_16_114152_delete_status_to_order_package.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class DeleteStatusToOrderPackage extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->dropColumn('status');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->enum('status',['无','未上传','已上传','未测量','未下发','上传异常','下发异常','记录异常','已上传异常','测量异常'])->default('无')->comment('包裹信息状态');
+        });
+    }
+}

+ 45 - 0
database/migrations/2020_12_16_114253_add_status_and_sent_and_at_and_received_at_and_execption_and_tarnsfer_status_and_remark_to_order_package.php

@@ -0,0 +1,45 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddStatusAndSentAndAtAndReceivedAtAndExecptionAndTarnsferStatusAndRemarkToOrderPackage extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            //
+            $table->enum('status', ['无', '已称重', '已揽收', '在途', '在途异常', '派送中', '派送异常', '返回中', '返回异常', '返回派件', '其他异常', '已收件'])->default('无')->comment('包裹信息状态');
+            $table->dateTime('sent_at')->nullable()->comment('发出时间');
+            $table->dateTime('received_at')->nullable()->comment('揽收时间');
+            $table->enum('exception', ['是', '否'])->default('否')->comment('异常状态');
+            $table->text('transfer_status')->nullable()->comment('更新信息');
+            $table->string('remark')->nullable()->comment('备注');
+            $table->index(['sent_at', 'exception']);
+            $table->index(['received_at', 'exception']);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            $table->dropColumn('status');
+            $table->dropColumn('sent_at');
+            $table->dropColumn('received_at');
+            $table->dropColumn('exception');
+            $table->dropColumn('transfer_status');
+            $table->dropColumn('remark');
+        });
+    }
+}

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

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateNotificationsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('notifications', function (Blueprint $table) {
+            $table->uuid('id')->primary();
+            $table->string('type');
+            $table->morphs('notifiable');
+            $table->text('data');
+            $table->timestamp('read_at')->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('notifications');
+    }
+}

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

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateMailEventsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('mail_events', function (Blueprint $table) {
+            $table->id();
+            $table->string('name');
+            $table->string('event_name');
+            $table->string('remark')->nullable();
+            $table->boolean('is_active')->default(true);
+            $table->text('template')->nullable()->comment('邮件模板,json格式');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('mail_events');
+    }
+}

+ 33 - 0
database/migrations/2021_01_08_110329_create_mail_event_role_table.php

@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateMailEventRoleTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('mail_event_role', function (Blueprint $table) {
+            $table->id();
+            $table->integer('mail_event_id');
+            $table->integer('role_id');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('mail_event_role');
+    }
+}

+ 43 - 0
database/migrations/2021_01_08_110607_add_default_email.php

@@ -0,0 +1,43 @@
+<?php
+
+use App\Events\SendEmailEvent;
+use App\MailEvent;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddDefaultEmail extends Migration
+{
+    protected $mailEvent;
+
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        //
+        $this->mailEvent = (new MailEvent([
+            'name' => '发送默认邮件',
+            'event_name' => SendEmailEvent::class,
+            'remark' => null,
+            'is_active' => true,
+            'template' => json_encode([
+                'title' => '邮件测试',
+                'description' => '这是一封测试邮件,收到不用回复'
+            ]),
+        ]))->save();
+
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        $this->mailEvent->delete();
+    }
+}

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

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

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateOrderIssueUserWorkgroupTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('order_issue_user_workgroup', function (Blueprint $table) {
+            $table->bigInteger('order_issue_id');
+            $table->bigInteger('user_workgroup_id')->index();
+            $table->unique(['order_issue_id', 'user_workgroup_id'],'order_issue_user_workgroup_unique');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('order_issue_user_workgroup');
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use App\OrderIssue;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class SyncOrderIssueUserWorkgroup extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        $orderIssues = OrderIssue::query()->whereNotNull('user_workgroup_id')->get();
+        foreach ($orderIssues as $orderIssue) {
+            $orderIssue->userWorkgroups()->attach($orderIssue->user_workgroup_id);
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 29 - 0
database/migrations/2021_01_19_151928_fix_order_package_status.php

@@ -0,0 +1,29 @@
+<?php
+
+use App\OrderPackage;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class FixOrderPackageStatus extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        OrderPackage::query()->whereNotNull('weighed_at')->update(['status'=>'已称重']);
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+
+    }
+}

+ 61 - 0
database/migrations/2021_01_20_145822_add_owner_id_to_order_packages.php

@@ -0,0 +1,61 @@
+<?php
+
+use App\OrderPackage;
+use App\Services\OrderPackageService;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddOwnerIdToOrderPackages extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            //
+            $table->bigInteger('owner_id')->nullable()->index();
+
+        });
+
+        $this->changeOwnerId();
+
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('order_packages', function (Blueprint $table) {
+            //
+            $table->dropColumn('owner_id');
+        });
+    }
+
+    public function changeOwnerId()
+    {
+        /**
+         * @var OrderPackageService  $order_packages_service
+         */
+        $order_packages_service = app(OrderPackageService::class);
+        OrderPackage::query()->with('order')->chunkById(200,function($order_packages)use($order_packages_service){
+            $update_params = [];
+            $update_params[] = ['id','owner_id'];
+            foreach ($order_packages as $order_package) {
+                if($order_package->order && $order_package->order->owner_id){
+                    $update_params[] = [
+                        'id'=>$order_package->id,
+                        'owner_id'=>$order_package->order->owner_id
+                    ];
+                }
+            }
+            $order_packages_service->batchUpdate($update_params);
+        });
+    }
+}

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

@@ -0,0 +1,36 @@
+<?php
+
+use App\Authority;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddAuthorityToLevel3Page extends Migration
+{
+    protected $authorityNames = [
+        '客户管理-财务',
+        '客户管理-客户',
+        '客户管理-相关设置',
+        '称重管理-快递',
+        '人事管理-相关设置',
+        '二次加工管理-相关设置',
+        '入库管理-Excel下载',
+        '入库管理-手持入口',
+    ];
+
+    public function up()
+    {
+        foreach ($this->authorityNames as $authorityName) {
+            if(!Authority::query()->where('name',$authorityName)->exists())
+                Authority::query()->create(['name' => $authorityName,'alias_name' => $authorityName]);
+        }
+
+    }
+    public function down()
+    {
+        foreach ($this->authorityNames as $authorityName) {
+            $authority  = Authority::query()->where('name' ,$authorityName )->first();
+            $authority->delete();
+        }
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddOrdersUniqueToColumnCode extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->unique('code','order_code_unique');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('orders', function (Blueprint $table) {
+            $table->dropUnique('order_code_unique');
+        });
+    }
+}

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

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

+ 7 - 19
public/.htaccess

@@ -1,21 +1,9 @@
-<IfModule mod_rewrite.c>
-    <IfModule mod_negotiation.c>
-        Options -MultiViews -Indexes
-    </IfModule>
+Options +FollowSymLinks -Indexes
+RewriteEngine On
 
-    RewriteEngine On
+RewriteCond %{HTTP:Authorization} .
+RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
 
-    # Handle Authorization Header
-    RewriteCond %{HTTP:Authorization} .
-    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
-
-    # Redirect Trailing Slashes If Not A Folder...
-    RewriteCond %{REQUEST_FILENAME} !-d
-    RewriteCond %{REQUEST_URI} (.+)/$
-    RewriteRule ^ %1 [L,R=301]
-
-    # Handle Front Controller...
-    RewriteCond %{REQUEST_FILENAME} !-d
-    RewriteCond %{REQUEST_FILENAME} !-f
-    RewriteRule ^ index.php [L]
-</IfModule>
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^ index.php [L]

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

@@ -6,15 +6,19 @@
             <li class="nav-item">
                 <a class="nav-link" href="{{url('customer/project/report')}}" :class="{active:isActive('project',2)}">项目</a>
             </li>@endcan
+            @can('客户管理-财务')
             <li class="nav-item">
                 <a class="nav-link" href="{{url('customer/finance/instantBill')}}" :class="{active:isActive('finance',2)}">财务</a>
-            </li>
+            </li>@endcan
+            @can('客户管理-客户')
             <li class="nav-item">
                 <a class="nav-link" href="{{url('customer/customer')}}" :class="{active:isActive('customer',2)}">客户</a>
-            </li>
+            </li>@endcan
+            @can('客户管理-相关设置')
             <li class="nav-item">
                 <a class="nav-link" href="{{url('customer/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
             </li>
+                @endcan
         </ul>
     </div>
 </div>

+ 5 - 5
resources/views/customer/project/menu.blade.php

@@ -8,6 +8,10 @@
                 <li class="nav-item">
                     <a class="nav-link" href="{{url('customer/project/report')}}" :class="{active:isActive('report',3)}">报表</a>
                 </li> @endcan
+                @can('客户管理-项目-面积')
+                    <li class="nav-item">
+                        <a class="nav-link" href="{{url('customer/project/area')}}" :class="{active:isActive('area',3)}">面积</a>
+                    </li> @endcan
                 @can('客户管理-项目-查询')
                 <li class="nav-item">
                     <a class="nav-link" href="{{url('customer/project/index')}}" :class="{active:isActive('index',3)}">查询</a>
@@ -16,12 +20,8 @@
                 <li class="nav-item">
                     <a class="nav-link" href="{{url('customer/project/create')}}" :class="{active:isActive('create',3)}">录入</a>
                 </li> @endcan
-                @can('客户管理-项目-面积')
-                <li class="nav-item">
-                    <a class="nav-link" href="{{url('customer/project/area')}}" :class="{active:isActive('area',3)}">面积</a>
-                </li> @endcan
                 {{ $slot }}
             </ul>
         </div>
     </div>
-</div>
+</div>

+ 2 - 0
resources/views/emails/test.blade.php

@@ -0,0 +1,2 @@
+{{  $objToJson->title }}
+{{  $objToJson->description }}

+ 3 - 3
resources/views/layouts/menu.blade.php

@@ -23,10 +23,10 @@
                     <span class="fa fa-truck" style="color: #4c2584"></span>
                     运输管理</a></li> @endcan
         @can('称重管理')
-            <li class="nav-item"><a href="{{url("package")}}" class="nav-link"
+            <li class="nav-item"><a href="{{url("package/weigh/index")}}" class="nav-link"
                                     :class="{active:isActive('package',1)}">
-                    <span class="fa fa-balance-scale" style="color: #1b7234"></span>
-                    称重管理</a></li> @endcan
+                    <span class="fa fa-suitcase" style="color: #1b7234"></span>
+                    包裹管理</a></li> @endcan
         @can('库存管理')
             <li class="nav-item"><a href="{{url('inventory/statement/allInventory')}}" class="nav-link"
                                     :class="{active:isActive('inventory',1)}">

+ 243 - 0
resources/views/maintenance/emails/index.blade.php

@@ -0,0 +1,243 @@
+@extends('layouts.app')
+@section('title')邮件@endsection
+@section('content')
+    <div id="nav2">
+        @component('maintenance.menu')@endcomponent
+        @component('maintenance.log.menu')@endcomponent
+    </div>
+    <div class="container-fluid" id="container">
+        <div class="card">
+            <div id="form_div"></div>
+            <div class="card-body">
+                @if(Session::has('successTip'))
+                    <div class="alert alert-success h1">{{Session::get('successTip')}}</div>
+                @endif
+                <table class="table table-sm table-hover table-condensed">
+                    <tr>
+                        <th>序号</th>
+                        <th>事件名</th>
+                        <th>通知角色</th>
+                        <th>事件描述</th>
+                        <th>邮件模板</th>
+                        <th>操作</th>
+                    </tr>
+                    <tr v-for="(emailEvent,i) in emailEvents">
+                        <td width="50">@{{ i+1 }}</td>
+                        <td width="50">@{{ emailEvent.name }}</td>
+                        <td width="100">
+                            <table class="table table-sm">
+                                <tr colspan="2">
+                                    <td>
+                                        <select class="form-control form-control-sm" v-model="emailEvent.role_selected">
+                                            <option v-for="role in roles" :value="role.id"> @{{ role.name }}</option>
+                                        </select>
+                                    </td>
+                                    <td>
+                                        <button class="btn btn-sm btn-primary" @click="addRole(emailEvent)">添加</button>
+                                    </td>
+                                </tr>
+                                <tr v-for="(role,j) in emailEvent.roles" v-if="j<2 || emailEvent.isShowRole">
+                                    <td>@{{ role.name }}</td>
+                                    <td>
+                                        <button class="btn btn-sm btn-outline-danger"
+                                                @click="deleteRole(role,j,emailEvent)">
+                                            删除
+                                        </button>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td>
+                                        <div class="row" @click="showRole(i)" v-if="emailEvent.roles.length > 2">
+                                            <label class="text-center mt-0 p-0 cursor-pointer offset-5">
+                                        <span class="fa"
+                                              :class="emailEvent.isShowRole ? 'fa-angle-double-down' : 'fa-angle-double-right'"></span>
+                                                &nbsp;<span v-if="emailEvent.isShowRole">收起</span><span
+                                                    v-if="!emailEvent.isShowRole">展开</span>共@{{ emailEvent.roles.length
+                                                }} 条角色
+                                            </label>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </table>
+                        </td>
+                        <td width="150">
+                            <span class="w-auto" v-show="emailEvents[i].remark_show&&emailEvent.remark"
+                                  @click="remarkShow(i,$event)">@{{ emailEvent.remark }}</span>
+                            <span v-show="emailEvents[i].remark_edit||!emailEvent.remark">
+                                <textarea width="150" class="form-control" rows="5" type="text"
+                                          @blur="remarkShow(i,$event)">@{{ emailEvent.remark }}</textarea>
+                                <button class="btn btn-sm btn-primary"
+                                        @click="updateRemark(emailEvent,$event)">修改</button>
+                            </span>
+                        </td>
+                        <td width="150">
+                        <span v-show="emailEvents[i].template_show&&emailEvent.template" @click="templateShow(i,$event)"
+                              class="w-auto">@{{ emailEvent.template }}</span>
+                            <span v-show="emailEvents[i].template_edit||!emailEvent.template">
+                            <textarea width="150" class="form-control" rows="5" type="text"
+                                      @blur="templateShow(i,$event)">@{{ emailEvent.template }}</textarea>
+                            <button class="btn btn-sm btn-primary"
+                                    @click="updateTemplate(emailEvent,$event)">修改</button>
+                        </span>
+                        </td>
+                        <td width="50">
+                            <button class="btn btn-success" v-if="emailEvent.is_active===0" @click="active(emailEvent)">
+                                启用
+                            </button>
+                            <button class="btn btn-secondary" v-if="emailEvent.is_active===1"
+                                    @click="active(emailEvent)">
+                                禁用
+                            </button>
+                        </td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+    </div>
+@stop
+@section('lastScript')
+    <script>
+        new Vue({
+            el: "#container",
+            data: {
+                emailEvents: {!!  $emailEvents->toJson() !!}['data'],
+                roles: {!!  $roles->toJson() !!},
+                addRolesFlag: false,
+            },
+            methods: {
+                /**
+                 * 添加角色,并将添加的角色添加到当前时间角色列表的顶部
+                 * @param emailEvent
+                 */
+                addRole(emailEvent) {
+                    window.tempTip.postBasicRequest("{{url('maintenance/mail/addRole')}}", {
+                        roleId: emailEvent.role_selected,
+                        eventMailId: emailEvent.id
+                    }, res => {
+                        let role = res.role;
+                        if (role) {
+                            emailEvent.roles.unshift(role);
+                            return "添加关联角色:" + role.name + " 成功!";
+                        }
+                    });
+                },
+                /**
+                 * 删除角色,当前事件的指定角色删除
+                 * @param role 要删除的角色
+                 * @param index 删除角色的索引
+                 * @param emailEvent 事件
+                 */
+                deleteRole(role, index, emailEvent) {
+                    window.tempTip.postBasicRequest("{{url('maintenance/mail/deleteRole')}}", {
+                        roleId: role.id,
+                        eventMailId: emailEvent.id
+                    }, res => {
+                        emailEvent.roles.splice(index, 1);
+                        return "取消关联角色:" + role.name + " 成功!";
+                    });
+                },
+                /**
+                 * 更新模板
+                 * 隐藏模板编辑,显示模板展示,更新前端显示
+                 * @param emailEvent
+                 * @param e
+                 */
+                updateTemplate(emailEvent, e) {
+                    let textarre = $(e.target).prev().val();
+                    window.tempTip.postBasicRequest("{{url('maintenance/mail/updateTemplate')}}", {
+                        id: emailEvent.id,
+                        template: textarre,
+                    }, res => {
+                        emailEvent.template = textarre;
+                        emailEvent.template_show = true;
+                        emailEvent.template_edit = false;
+                        return "修改模板成功!";
+                    });
+
+                },
+                /**
+                 * 更新备注
+                 * 隐藏备注编辑,显示备注展示,更新备注显示
+                 * @param emailEvent
+                 * @param e
+                 */
+                updateRemark(emailEvent, e) {
+                    let textarre = $(e.target).prev().val();
+                    window.tempTip.postBasicRequest("{{url('maintenance/mail/updateRemark')}}", {
+                        id: emailEvent.id,
+                        remark: textarre,
+                    }, res => {
+                        emailEvent.remark = textarre;
+                        emailEvent.remark_show = true;
+                        emailEvent.remark_edit = false;
+                        return "修改备注成功!";
+                    });
+
+                },
+                /**
+                 * 启用/禁用指定模板
+                 * @param emailEvent
+                 */
+                active(emailEvent) {
+                    window.tempTip.postBasicRequest("{{url('maintenance/mail/active')}}", {
+                        id: emailEvent.id,
+                    }, res => {
+                        if (res) {
+                            emailEvent.is_active = 0;
+                            return "模板启用禁用!";
+                        } else {
+                            emailEvent.is_active = 1;
+                            return "模板启用成功!";
+                        }
+                    });
+                },
+                /**
+                 * 展开折叠指定模板的角色列表
+                 * @param index
+                 */
+                showRole(index) {
+                    if (this.emailEvents[index].isShowRole) {
+                        this.emailEvents[index].isShowRole = false;
+                    } else {
+                        this.emailEvents[index].isShowRole = true;
+                    }
+                    this.$forceUpdate();
+                },
+                /**
+                 * 备注编辑/显示切换
+                 * 切换为编辑时,自动聚焦到textarea
+                 * @param index
+                 * @param $event
+                 */
+                remarkShow(index, $event) {
+                    let _this = this;
+                    setTimeout(function () {
+                        _this.emailEvents[index].remark_show = !_this.emailEvents[index].remark_show;
+                        _this.emailEvents[index].remark_edit = !_this.emailEvents[index].remark_edit;
+                        setTimeout(function () {
+                            let find = $($event.target).parent().find('textarea');
+                            find.focus();
+                        }, 100)
+                    }, 100);
+                },
+                /**
+                 * 模板编辑/显示切换
+                 * 切换为编辑时,自动聚焦到textarea
+                 * @param index
+                 * @param $event
+                 */
+                templateShow(index,$event) {
+                    let _this = this;
+                    setTimeout(function () {
+                        _this.emailEvents[index].template_show = !_this.emailEvents[index].template_show;
+                        _this.emailEvents[index].template_edit = !_this.emailEvents[index].template_edit;
+                        setTimeout(function () {
+                            let find = $($event.target).parent().find('textarea');
+                            find.focus();
+                        }, 100)
+                    }, 100);
+                },
+            }
+        })
+    </script>
+@stop

+ 12 - 0
resources/views/maintenance/emails/menu.blade.php

@@ -0,0 +1,12 @@
+
+<div class="container-fluid nav3">
+    <div class="card" >
+        <ul class="nav nav-pills">
+            @can('邮件-查询')
+            <li class="nav-item">
+                <a class="nav-link" href="{{url('maintenance/mail')}}" :class="{active:isActive('',3)}">查询</a>
+            </li> @endcan
+            {{$slot}}
+        </ul>
+    </div>
+</div>

+ 4 - 0
resources/views/maintenance/menu.blade.php

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

+ 192 - 21
resources/views/order/issue/index.blade.php

@@ -38,6 +38,10 @@
                         <button type="button" class="btn btn-outline-dark btn-sm form-control-sm  tooltipTarget" @click="batchStoreLogsModel">
                             批量处理说明
                         </button>
+                        <span class="ml-1">
+                        <button type="button" class="btn btn-outline-dark btn-sm form-control-sm  tooltipTarget" @click="batchOthersModel">
+                            批量处理赔偿金额与事故责任方
+                        </button>
                     </span>
                     @endcan
                     <span class="ml-1">
@@ -54,9 +58,14 @@
                     @cannot('订单管理-问题件-客户不可见')
                         @can('订单管理-问题件-财务确认')
                         <span class="ml-1">
-                            <button type="button" class="btn btn-outline-dark btn-sm form-control-sm  tooltipTarget" @click="financeConfirm">
+                            <button type="button" class="btn btn-outline-dark btn-sm form-control-sm  tooltipTarget" @click="financeConfirm('是')">
                                 批量财务确认
                             </button>
+                        </span>
+                            <span class="ml-1">
+                            <button type="button" class="btn btn-outline-dark btn-sm form-control-sm  tooltipTarget" @click="financeConfirm('否')">
+                                批量财务确认取消
+                            </button>
                         </span>
                         @endcan
                         @can('订单管理-问题件-批量归档')
@@ -71,13 +80,13 @@
                 <table class="table table-sm table-striped table-bordered table-hover card-body p-0 m-0" style="background: #fff;@cannot('订单管理-问题件-客户不可见')min-width: 3000px;@else min-width: 1990px; @endcannot">
                     <tr class="tr-yellow align-center">
                         <th class=" font-weight-bolder header-1" ></th>
-                        <th class="td-yellow  font-weight-bolder original-class table-head-warning  header-2">
+                        <th class="td-yellow  font-weight-bolder original-class table-head-warning  header-2 text-center">
                             <span>原始运单</span>
                             <button class="btn btn-sm btn-outline-secondary float-right" v-if="isShowOrderInfo" @click="hideOrderInfo">
                                 隐藏运单列
                             </button>
                         </th>
-                        <th class="font-weight-bolder header-3">
+                        <th class="font-weight-bolder header-3 text-center">
                             <button class="btn btn-sm btn-outline-secondary float-left" v-if="isShowRejectedBill" @click="hideRejectedBill">
                                 隐藏退单列
                             </button>
@@ -151,7 +160,7 @@
                         <th class="three-layer  align-middle" rowspan="2" style="min-width: 120px">宝时赔偿金额</th>
                         <th class="three-layer  align-middle" rowspan="2" style="min-width: 120px">宝时快递减免</th>
                         @cannot('订单管理-问题件-客户不可见')
-                        <th class="three-layer  align-middle" rowspan="2" style="min-width: 120px">事故责任方</th>
+                        <th class="three-layer  align-middle" rowspan="2" style="min-width: 200px">事故责任方</th>
                         <th class="align-middle" rowspan="2" style="min-width: 120px">操作</th>
                         @endcannot
                     </tr>
@@ -267,7 +276,7 @@
                             <span v-if='orderIssue.order.logistic'>@{{ orderIssue.order.logistic.name }}</span>
                         </td>
                         <td class=" hide-content p-0 td-yellow child-layer-2 align-center" valign="middle">
-                            <div v-if="orderIssue.order">
+                            <template v-if="orderIssue.order">
                                 <span  :class="orderIssue.order.packages.length > 1 ?'collapse ':''" :id="'logisticNumbers'+orderIssue.id" >
                                     <span class="m-0 p-0 d-inline-block" v-for="package in orderIssue.order.packages" >@{{ package.logistic_number }}&nbsp;&nbsp;</span>
                                 </span>
@@ -276,7 +285,7 @@
                                         @click="toggleLogisticNumbers(orderIssue.id,orderIssue.order.packages.length)">
                                     分箱@{{ orderIssue.order.packages.length }}件,点击展开
                                 </button>
-                            </div>
+                            </template>
                         </td>
                         {{--商品明细 开始--}}
                         <td class="td-yellow p-0 m-0 child-layer-2 w-50" v-if="!isShowOrderInfo && index===0" :rowspan="orderIssues.length">
@@ -382,7 +391,7 @@
                             @endcan
                         </td>
 
-                        <td class=" m-0 p-0 log-td child-layer-3  valign-middle align-center" v-on:mouseover="showAddBtn($event)" v-on:mouseleave="hideAddBtn($event)" colspan="4">
+                        <td class=" m-0 p-0 log-td child-layer-3  align-center" v-on:mouseover="showAddBtn($event)" v-on:mouseleave="hideAddBtn($event)" colspan="4">
                             @can('订单管理-问题件-处理结果添加')
                             <div class="addLogDiv row m-0 p-0 form-group" :id="'AddLog_'+orderIssue.id" style="display: none;">
                                 <input type="hidden" name="id" :value="orderIssue.id">
@@ -406,7 +415,7 @@
                                             <td class="text-muted" style="min-width: 170px">@{{ log.created_at }}</td>
                                             @can('订单管理-问题件-处理结果删除')
                                                 <td style="" class="m-0 p-0 border-0">
-                                                    <button type="button" class="btn btn-sm btn-outline-danger m-0 del-btn invisible" @click="deleteOrderIssueLog(log.id,orderIssue.id)">删</button>
+                                                    <button type="button" class="btn btn-sm btn-outline-danger m-0 del-btn invisible" @click="deleteOrderIssueLog(log,orderIssue.id)">删</button>
                                                 </td>
                                             @endcan
                                         </template>
@@ -533,10 +542,38 @@
                         </td>
                         @cannot('订单管理-问题件-客户不可见')
                             <td class="child-layer-3">
-                                <select class="form-control form-control-sm" :value="orderIssue.user_workgroup_id" @change="updateOrderIssue(orderIssue,'user_workgroup_id',$event)">
-                                    <option value></option>
-                                    <option v-for="item in userWorkGroup" :value="item.name">@{{ item.value }}</option>
-                                </select>
+                                <table class="table table-sm">
+                                    <tr colspan="2">
+                                        <td colspan="2">
+                                            <select class="form-control form-control-sm" @change="addUserWorkgroup(orderIssue,'user_workgroup_id',$event)">
+                                                <option value></option>
+                                                <option v-for="item in userWorkGroup" :value="item.name">@{{ item.value }}</option>
+                                            </select>
+                                        </td>
+                                    </tr>
+                                    <tr v-for="(user_workgroup,j) in orderIssue.user_workgroups" v-if="j<2 || orderIssue.is_show_user_workgroup">
+                                        <td>@{{ user_workgroup.name }}</td>
+                                        <td>
+                                            <button class="btn btn-sm btn-outline-danger"
+                                                    @click="deleteUserWorkgroup(user_workgroup,j,orderIssue)">
+                                                删除
+                                            </button>
+                                        </td>
+                                    </tr>
+                                    <tr>
+                                        <td colspan="2" v-if="orderIssue.user_workgroups.length > 2">
+                                            <div class="row" @click="showUserWorkgroup(orderIssue)" v-if="orderIssue.user_workgroups.length > 2">
+                                                <label class="text-center mt-0 p-0 cursor-pointer offset-5">
+                                        <span class="fa"
+                                              :class="orderIssue.is_show_user_workgroup ? 'fa-angle-double-down' : 'fa-angle-double-right'"></span>
+                                                    &nbsp;<span v-if="orderIssue.is_show_user_workgroup">收起</span><span
+                                                        v-if="!orderIssue.is_show_user_workgroup">展开</span>共@{{ orderIssue.user_workgroups.length }} 条
+                                                </label>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                </table>
+
                             </td>
                             <td>
                                 @can('订单管理-问题件-编辑')
@@ -574,6 +611,46 @@
                 </div>
             </div>
         </div>
+        <div class="modal fade" id="batchOthersModel" tabindex="-1" role="dialog" aria-labelledby="othersLabel" aria-hidden="true">
+            <div class="modal-dialog  modal-dialog-centered">
+                <div class="modal-content">
+                    <div class="modal-body">
+                        <h5 class="modal-title" id="othersLabel">承运商赔偿金额</h5>
+                        <input type="number" v-model="edit.batchOthers.logistic_indemnity_money" class="form-control form-control-sm">
+                    </div>
+                    <div class="modal-body">
+                        <h5 class="modal-title" id="othersLabel">承运商快递减免</h5>
+                        <select class="form-control form-control-sm" v-model="edit.batchOthers.logistic_express_remission">
+                            <option disabled value="">请选择</option>
+                            <option v-for="item in expressRemission" :value="item">@{{ item }}</option>
+                        </select>
+                    </div>
+                    <div class="modal-body">
+                        <h5 class="modal-title" id="othersLabel">宝时赔偿金额</h5>
+                        <input type="number" v-model="edit.batchOthers.baoshi_indemnity_money" class="form-control form-control-sm">
+                    </div>
+                    <div class="modal-body">
+                        <h5 class="modal-title" id="othersLabel">宝时快递减免</h5>
+                        <select class="form-control form-control-sm" v-model="edit.batchOthers.baoshi_express_remission">
+                            <option disabled value="">请选择</option>
+                            <option v-for="item in expressRemission" :value="item">@{{ item }}</option>
+                        </select>
+                    </div>
+
+                    <div class="modal-body" >
+                        <h5 class="modal-title" id="logsLabel">事故责任方</h5>
+                        <span v-for="item in userWorkGroup">
+                             <input v-model="edit.batchOthers.userWorkGroupIds" type="checkbox" name="vehicle" :value="item.name" /> @{{ item.value }}
+                        </span>
+                    </div>
+
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                        <button type="button" class="btn btn-primary" data-dismiss="modal" @click="batchOthers()">确认</button>
+                    </div>
+                </div>
+            </div>
+        </div>
 
         {{--delete OrderIssue--}}
         <div class="modal fade" id="alertModal" tabindex="-1" role="dialog" aria-labelledby="alertModalLabel"
@@ -723,6 +800,13 @@
                 message:{},
                 edit:{
                     batchStoreLogs:'',
+                    batchOthers:{
+                        logistic_indemnity_money: null ,
+                        logistic_express_remission: null,
+                        baoshi_indemnity_money: null,
+                        baoshi_express_remission: null,
+                        userWorkGroupIds: []
+                    },
                     isShow:[],
                     addSendOrderIssueID:'',
                     orderIssue: {id: null,showId:''},
@@ -735,6 +819,7 @@
                     _this.regroupOrder(orderIssue.second_order);
                     _this.regroupRejectedBill(orderIssue);
                     _this.regroupLogs(orderIssue);
+                    _this.regroupUserGroup(orderIssue);
                 });
             },
             mounted: function () {
@@ -777,6 +862,9 @@
                     },
                     {name: 'logistic_number_return', type: 'input', tip: '退回单号:前或后加百分号为单个模糊搜索,否则为多条件精确搜索', placeholder: '退回单号'},
                     {name: 'send_client_code', type: 'input', tip: '二次订单号:前或后加百分号为单个模糊搜索,否则为多条件精确搜索', placeholder: '二次订单号'},
+                    {name: ['shop_name','shop_name_limit_time'], type: 'input_select', tip: ['商铺:前或后加 百分号为单个模糊搜索,默认添加后%,否则为多条件精确搜索','查询范围越短,搜索速度越快'], placeholder: ['店铺',''],
+                        data:log_content_range,
+                        rules:[{son:{shop_name_limit_time:{default:'15',required_without_all_if:['created_at_start','created_at_end']}}}]},
                 ], [
                     {name: 'created_at_end', type: 'dateTime', tip: '登记结束日期'},
                     {name: 'consignee_name', type: 'input', tip: '收货人名称:前或后加百分号为单个模糊搜索,否则为多条件精确搜索', placeholder: '收货人名称'},
@@ -785,6 +873,7 @@
                     {name: 'good_name', type: 'input', tip: '商品名:前或后加 百分号为单个模糊搜索,否则为多条件精确搜索', placeholder: '商品名'},
                     {name: 'id_quality_label', type: 'select', tip: '是否正品', placeholder: '是否正品', data: this.qualityLabel},
                     {name: 'is_imported', type: 'select', tip: '是否导入处理', placeholder: '是否导入处理', data: imported_status},
+                    {name: 'user_workgroups', type: 'select_multiple_select', tip: ['事故责任方',''], placeholder: ['事故责任方',''], data: this.userWorkGroup},
                 ],[
                     @cannot('订单管理-问题件-客户不可见')
                     {name: 'logistic_indemnity_money', type: 'select', tip: '承运商赔偿金额', placeholder: '承运商赔偿金额',data:[{name: '是',value:'是'},{name: '否',value:'否'}]},
@@ -800,6 +889,7 @@
                     // {date_relevance:{date:['orderdate_start','orderdate_end'],relevance:'addtime',killing:'date',default:[31,92,183,366]}}]},
                     {name: 'custom_code', type: 'input', tip: '自定义订单号:自定义订单号', placeholder: '自定义订单号'},
                     {name: 'is_handle', type: 'checkbox', tip: '是否已处理', data: [{name: 'ture', value: '已解决'}]},
+                    {name: 'finance_confirm', type: 'select', tip: '财务确认', placeholder: '财务确认是/否', data:[{name: '是',value:'是'},{name: '否',value:'否'}]},
                 ],[
                     {name: 'settlement_at_start', type: 'dateTime', tip: '完结起始日期'},
                     {name: 'settlement_at_end', type: 'dateTime', tip: '完结结束日期' },
@@ -893,6 +983,9 @@
                         orderIssue.log_is_show = false;
                     }
                 },
+                regroupUserGroup(orderIssue){
+                    orderIssue.is_show_user_workgroup = false;
+                },
                 displayDelBtn(bool,e){
                     if(bool)$(e.target).next().removeClass('d-none');
                     else {
@@ -1134,15 +1227,19 @@
                         tempTip.show('网络异常:' + err);
                     });
                 },
-                deleteOrderIssueLog(id, OrderIssueId) {
+                deleteOrderIssueLog(log, OrderIssueId) {
                     let _this = this;
                     if(!confirm('是否删除当前记录'))return;
-                    axios.post("{{url('apiLocal/order/issue/log/destroy')}}", {id: id}).then(function (res) {
+                    if(log.type === '创建'){
+                        tempTip.show('创建记录不能删除');
+                        return;
+                    }
+                    axios.post("{{url('apiLocal/order/issue/log/destroy')}}", {id: log.id}).then(function (res) {
                         if (res.data.success) {
                             _this.orderIssues.forEach(function (orderIssue) {
                                 if (orderIssue.id == OrderIssueId) {
                                     orderIssue.logs.forEach(function (item, index) {
-                                        if (item.id == id)orderIssue.logs.splice(index, 1);
+                                        if (item.id == log.id)orderIssue.logs.splice(index, 1);
                                     });
                                 }
                             })
@@ -1184,7 +1281,13 @@
                     let domObj = $(e.target).parents('.log-td');
                     if (domObj.hasClass('log-td')) {
                         domObj.find('.add-btn').show();
+                    }else{
+                        let obj = $(e.target);
+                        if(obj.hasClass('log-td')){
+                            obj.find('.add-btn').show();
+                        }
                     }
+
                 },
                 hideAddBtn(e) {
                     let domObj = $(e.target);
@@ -1332,6 +1435,14 @@
                     }
                     $("#batchStoreLogsModel").modal('show');
                 },
+                batchOthersModel(){
+                    if(this.checkData.length === 0){
+                        tempTip.setDuration(2000)
+                        tempTip.show('没有勾选内容')
+                        return;
+                    }
+                    $("#batchOthersModel").modal('show');
+                },
                 batchStoreLogs(){
                     let _this = this;
                     let data = {orderIssueIds:this.checkData,content:this.edit.batchStoreLogs};
@@ -1358,6 +1469,32 @@
                         tempTip.show('处理结果添加异常:'+error)
                     })
                 },
+                batchOthers(){
+                    let _this = this;
+                    let data = {
+                        orderIssueIds:this.checkData,
+                        logistic_indemnity_money: this.edit.batchOthers.logistic_indemnity_money,
+                        logistic_express_remission: this.edit.batchOthers.logistic_express_remission,
+                        baoshi_indemnity_money: this.edit.batchOthers.baoshi_indemnity_money,
+                        baoshi_express_remission: this.edit.batchOthers.baoshi_express_remission,
+                        userWorkGroupIds: this.edit.batchOthers.userWorkGroupIds,
+                    };
+                    window.tempTip.postBasicRequest('{{url("apiLocal/order/issue/batchOthers")}}', data, res => {
+                        if (_this.edit.batchOthers.logistic_indemnity_money) {
+                            _this.orderIssuesEdit(_this.checkData, "logistic_indemnity_money", _this.edit.batchOthers.logistic_indemnity_money);
+                        }
+                        if (_this.edit.batchOthers.logistic_express_remission) {
+                            _this.orderIssuesEdit(_this.checkData, "logistic_express_remission", _this.edit.batchOthers.logistic_express_remission);
+                        }
+                        if (_this.edit.batchOthers.baoshi_indemnity_money) {
+                            _this.orderIssuesEdit(_this.checkData, "baoshi_indemnity_money", _this.edit.batchOthers.baoshi_indemnity_money);
+                        }
+                        if (_this.edit.batchOthers.baoshi_express_remission) {
+                            _this.orderIssuesEdit(_this.checkData, "baoshi_express_remission", _this.edit.batchOthers.baoshi_express_remission);
+                        }
+                        return "批量修改完成";
+                    });
+                },
                 editSecondClientNo(orderIssue,e){
                     let value = $(e.target).val()
                     let data = {id:orderIssue.id,secondClientNo:value}
@@ -1418,7 +1555,7 @@
                                 _this.regroupOrder(response.data.order);
                                 orderIssue.second_order = response.data.order
                                 orderIssue.second_client_no = response.data.order.client_code
-                            }
+                            }else orderIssue.second_logistic_number = logisticNumber;
                             if(response.data.second_logistic_number != null ){
                                 orderIssue.second_logistic_number = response.data.second_logistic_number
                             }
@@ -1464,23 +1601,32 @@
                         tempTip.show('处理导入出现异常'+error)
                     })
                 },
-                financeConfirm(){
+                financeConfirm(flag){
                     let _this= this
                     if(this.checkData.length === 0){
                         tempTip.setDuration(2000)
                         tempTip.show('没有勾选内容')
                         return;
                     }
-                    if(!confirm('是否进行财务确认'))return;
+                    if (flag=='是') {
+                        if (!confirm('是否进行财务确认')) return;
+                    }else{
+                        if (!confirm('是否取消财务确认')) return;
+                    }
                     let data = {ids:this.checkData};
                     tempTip.setDuration(9999);
                     tempTip.waitingTip('处理中.......');
+                    data.flag = flag;
                     axios.post('{{url('apiLocal/order/issue/financeConfirm')}}',data)
                         .then(function(response){
                             tempTip.cancelWaitingTip();
                             if(response.data.success){
                                 tempTip.setDuration(2000);
-                                tempTip.showSuccess('确认成功');
+                                if (flag=='是') {
+                                    tempTip.showSuccess('确认成功');
+                                }else{
+                                    tempTip.showSuccess('取消成功');
+                                }
                                 _this.orderIssuesEdit(data.ids,'finance_confirm','是');
                                 return;
                             }
@@ -1553,6 +1699,7 @@
                                     orderIssue.rejecting_status = response.data.data.orderIssue.rejecting_status;
                                 }
                                 _this.regroupRejectedBill(orderIssue);
+                                _this.$forceUpdate();
                                 return;
                             }
                             tempTip.setDuration(2000);
@@ -1571,9 +1718,9 @@
                             if(response.data.success){
                                 tempTip.setDuration(2000);
                                 tempTip.showSuccess('退回单号取消关联成功');
-                                if(orderIssue.rejected_bills===null)return;
+                                if(orderIssue.order_issue_rejected_bills===null)return;
                                 $.each(orderIssue.order_issue_rejected_bills,function(i,item){
-                                    if(item.logistic_number_return === logistic_number){
+                                    if(item && item.logistic_number_return === logistic_number){
                                         orderIssue.order_issue_rejected_bills.splice(i,1);
                                         _this.regroupRejectedBill(orderIssue);
                                     }
@@ -1626,6 +1773,30 @@
                             tempTip.setDuration(2000);
                             tempTip.show(error);
                         });
+                },
+                addUserWorkgroup(orderIssue,user_workgroup_id,e) {
+                    let value = $(e.target).val()
+                    window.tempTip.postBasicRequest("{{url('apiLocal/order/issue/userWorkgroups/add')}}", {
+                        orderIssueId: orderIssue.id,
+                        userWorkgroupId: value
+                    }, res => {
+                        orderIssue.user_workgroups.unshift(res);
+                        return "添加事故责任方成功!";
+                    });
+                },
+                deleteUserWorkgroup(user_workgroup,index,orderIssue) {
+                    window.tempTip.postBasicRequest("{{url('apiLocal/order/issue/userWorkgroups/delete')}}", {
+                        orderIssueId: orderIssue.id,
+                        userWorkgroupId: user_workgroup.id
+                    }, res => {
+                        orderIssue.user_workgroups.splice(index, 1);
+                        this.$forceUpdate();
+                        return "删除事故责任方成功!";
+                    });
+                },
+                showUserWorkgroup(orderIssue) {
+                    orderIssue.is_show_user_workgroup = !orderIssue.is_show_user_workgroup;
+                    this.$forceUpdate();
                 }
             }
         })

+ 5 - 6
resources/views/order/issue/recycle.blade.php

@@ -79,9 +79,9 @@
                                 </div>
                             </td>
                             <td>
-                                <div v-if="orderIssue.secondOrder">
-                                    <div v-if="orderIssue.secondOrder.packages">
-                                        <p v-for="package in orderIssue.secondOrder.packages">@{{ package.logistic_number }}</p>
+                                <div v-if="orderIssue.order_issue_rejected_bills">
+                                    <div v-for="orderIssueRejectedBill in orderIssue.order_issue_rejected_bills">
+                                        <p>@{{ orderIssueRejectedBill.logistic_number_return }}</p>
                                     </div>
                                 </div>
                             </td>
@@ -159,10 +159,9 @@
                             tempTip.setDuration(2000);
                             if (response.data.success) {
                                 tempTip.showSuccess('恢复成功');
-                                for (let i = 0; i < _this.orderIssues.length; i++) {
-                                    if(data.ids.includes(orderIssue.id))
+                                for (let i = _this.orderIssues.length -1;i >= 0;i--){
+                                    if(_this.checkData.includes(_this.orderIssues[i].id))
                                         _this.orderIssues.splice(i,1);
-
                                 }
                             } else {
                                 tempTip.show(response.data.error);

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

@@ -0,0 +1,187 @@
+@extends('layouts.app')
+@section('title')快递@endsection
+
+@section('content')
+    <span id="nav2">
+        @component('package.menu')@endcomponent
+    </span>
+    <div id="list">
+        <div class="container-fluid">
+            <div id="form_div"></div>
+            <table class="table table-striped table-sm text-nowrap table-hover">
+                <tr>
+                    <th>单号</th>
+                    <th>状态</th>
+                    <th>快递公司</th>
+                    <th>货主</th>
+                    <th>发出日期</th>
+                    <th>揽收日期</th>
+                    <th>称重日期</th>
+                    <th>异常标记</th>
+                    <th>快递路由</th>
+                    <th>客服备注</th>
+                </tr>
+                <tr v-for="(package,i) in packages">
+                    <td>@{{ package.logistic_number }}</td>
+                    <td>@{{ package.status }}</td>
+                    <td>@{{ package.order != null  ? package.order.logistic.name : '#' }}</td>
+                    <td>@{{ package.order != null  ? package.order.owner.name : '#' }}</td>
+                    <td>@{{ package.sent_at }}</td>
+                    <td>@{{ package.received_at }}</td>
+                    <td>@{{ package.weighed_at }}</td>
+                    <td>@{{ package.exception }}</td>
+                    <td>
+                        <div v-if="package.transfer_status && package.transfer_status.length>0" class="text-overflow-warp-200 up" :id="'route-'+i">
+                            <p v-for="route in package.transfer_status">
+                                @{{ route.accept_address+" "+ route.remark+" "+route.accept_time}}
+                            </p>
+                        </div>
+                        <div class="text-overflow-warp-200 " v-if=" package.transfer_status && !showList[i] && package.transfer_status.length > 0">
+                            @{{ package.transfer_status[0].accept_address+" "+ package.transfer_status[0].remark+" "+package.transfer_status[0].accept_time}}
+                        </div>
+                        <div @click="showRoute(i)" v-if="package.transfer_status && package.transfer_status.length > 1">
+                            <label class="text-center mt-0 p-0 cursor-pointer pull-left">
+                                <span class="fa" :class="package.isShowRoute ? 'fa-angle-double-down' : 'fa-angle-double-right'"></span>
+                                &nbsp;<span v-if="package.transfer_status && showList[i]">收起</span><span v-else>展开</span>&nbsp;@{{ package.transfer_status.length }} 条
+                            </label>
+                        </div>
+                    </td>
+                    <td>@{{ package.remark }}</td>
+                </tr>
+            </table>
+            <div class="text-info h5 btn btn">{{$orderPackages->count()}}/{{$orderPackages->total()}}</div>
+            {{$orderPackages->appends($paginateParams)->links()}}
+        </div>
+    </div>
+@endsection
+
+@section('lastScript')
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>
+    <script>
+        let vue = new Vue({
+            el: "#list",
+            data: {
+                packages: [
+                    @foreach($orderPackages as $package)
+                    {!! $package !!},
+                    @endforeach
+                ],
+                logistics: [
+                        @foreach($logistics as $logistic)
+                    {
+                        name: '{{$logistic->id}}', value: '{{$logistic->name}}'
+                    },
+                    @endforeach
+                ],
+                owners: [
+                        @foreach($owners as $owner)
+                    {
+                        name: '{{$owner->id}}', value: '{{$owner->name}}'
+                    },
+                    @endforeach
+                ],
+                showList:{},
+            },
+            created(){
+                $.each(this.packages,function (index,item){
+                    if (item.transfer_status!=null&&item.transfer_status.length>1) {
+                        item.transfer_status.sort(function (item1, item2) {
+                            let date1 = new Date(item1.accept_time);
+                            let date2 = new Date(item2.accept_time);
+                            if (date1 - date2 > 0) return -1;
+                            if (date1 - date2 < 0) return 1;
+                            return 0;
+                        });
+                    }
+                });
+            },
+            mounted() {
+                let _this = this;
+                $(".up").slideUp();
+                let data = [
+                    [
+                        /*"","","","","","","","","","",""*/
+                        {name: 'logistic_number', type: 'input', tip: '可支持多快递单号,糊模查找需要在左边打上%符号', placeholder: '快递单号'},
+                        {
+                            name: 'status',
+                            type: 'select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的状态'],
+                            placeholder: '状态',
+                            data: [{name: '无', value: '无'}, {name: '已称重', value: '已称重'}, {
+                                name: '已揽收',
+                                value: '已揽收'
+                            }, {name: '在途', value: '在途'}, {name: '在途异常', value: '在途异常'}, {
+                                name: '派送中',
+                                value: '派送中'
+                            }, {name: '派送异常', value: '派送异常'}, {name: '返回中', value: '返回中'}, {
+                                name: '返回异常',
+                                value: '返回异常'
+                            }, {name: '返回派件', value: '返回派件'}, {name: '其他异常', value: '其他异常'},]
+                        },
+
+
+                        {name: 'received_at_start', type: 'dateTime', tip: '选择显示揽收时间的起始时间'},
+                        {name: 'received_at_end', type: 'dateTime', tip: '选择显示揽收时间的截止时间'},
+
+                        {
+                            name: 'is_weighed',
+                            type: 'select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的状态'],
+                            placeholder: '是否称重',
+                            data: [{name: false, value: '无'}, {name: true, value: '已称重'}]
+                        },
+
+                    ], [
+                        {
+                            name: 'logistic_id',
+                            type: 'select_multiple_select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的快递'],
+                            placeholder: ['快递', '定位或多选快递'],
+                            data: _this.logistics
+                        },
+                        {
+                            name: 'owner_id',
+                            type: 'select_multiple_select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的货主'],
+                            placeholder: ['货主', '定位或多选货主'],
+                            data: _this.owners
+                        },
+                        {name: 'sent_at_start', type: 'dateTime', tip: '选择显示发出时间的起始时间'},
+                        {name: 'sent_at_end', type: 'dateTime', tip: '选择显示发出时间的截止时间'},
+                        {
+                            name: 'is_exception',
+                            type: 'select',
+                            tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的状态'],
+                            placeholder: '是否有异常',
+                            data: [{name: '是', value: '是'}, {name: '否', value: '否'}]
+                        },
+                    ]
+                ];
+                _this.form = new query({
+                    el: '#form_div',
+                    condition: data,
+                });
+                _this.form.init();
+            },
+            methods:{
+                showRoute(id){
+                    if (this.showList[id]){
+                        this.$set(this.showList,id,false);
+                        $("#route-"+id).slideUp();
+                    }else{
+                        this.$set(this.showList,id,true);
+                        $("#route-"+id).slideDown();
+                    }
+                    this.$forceUpdate();
+                },
+            },
+            filters:{
+                toObjected:function(value){
+                    return JSON.parse(value);
+                }
+            },
+        });
+    </script>
+@endsection

+ 4 - 1
resources/views/weight/measureMonitor/index.blade.php → resources/views/package/measureMonitor/index.blade.php

@@ -2,7 +2,10 @@
 @section('title')设备@endsection
 
 @section('content')
-    @component('weight.menu')@endcomponent
+    <span id="nav2">
+        @component('package.menu')@endcomponent
+        @component('package.weigh.menu')@endcomponent
+    </span>
     <div class="page-holder w-100 d-flex flex-wrap" id="list">
         <div class="container-fluid px-xl-5">
             <section class="py-5">

+ 1 - 1
resources/views/weight/menuWeight.blade.php → resources/views/package/measureMonitor/menu.blade.php

@@ -3,7 +3,7 @@
 
 @section('content')
     <div id="nav2">
-        @component('weight.menu')
+        @component('package.menu')
         @endcomponent
         <div class="container-fluid nav3">
             <div class="card menu-third" >

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

@@ -0,0 +1,20 @@
+
+<div class="container-fluid nav2" id="nav2">
+    <div class="card">
+        <ul class="nav nav-pills">
+            @can('称重管理-查询')
+                <li class="nav-item">
+                    <a class="nav-link" href="{{url('package/weigh/index')}}" :class="{active:isActive('weigh',2)}">称重管理</a>
+                </li>@endcan
+                {{--TODO 权限修改--}}
+            @can('称重管理-快递')
+                <li class="nav-item">
+                    <a class="nav-link" href="{{url('package/logistic')}}" :class="{active:isActive('logistic',2)}">快递</a>
+                </li>@endcan
+            @can('称重管理-查看异常')
+            <li class="nav-item">
+                <a class="nav-link text-dark" href="{{url('package/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
+            </li>@endcan
+        </ul>
+    </div>
+</div>

+ 4 - 3
resources/views/weight/package/create.blade.php → resources/views/package/weigh/create.blade.php

@@ -2,9 +2,10 @@
 @section('title')手动录入@endsection
 
 @section('content')
-    <div id="nav2">
-        @component('weight.menu')@endcomponent
-    </div>
+    <span id="nav2">
+        @component('package.menu')@endcomponent
+        @component('package.weigh.menu')@endcomponent
+    </span>
     <div class="container-fluid" id="package">
         <div class="card col-md-8 offset-md-2">
             <div class="card-body">

+ 3 - 2
resources/views/weight/package/index.blade.php → resources/views/package/weigh/index.blade.php

@@ -4,8 +4,9 @@
 
 @section('content')
     <span id="nav2">
-        @component('weight.menu')@endcomponent
-        @component('weight.package.menu')@endcomponent
+        @component('package.menu')@endcomponent
+        @component('package.weigh.menu')@endcomponent
+        @component('package.weigh.record.menu')@endcomponent
     </span>
     <div class="d-none" id="list">
         <div class="container-fluid">

+ 20 - 0
resources/views/package/weigh/menu.blade.php

@@ -0,0 +1,20 @@
+<div class="container-fluid nav3">
+    <div class="card menu-third" >
+        <ul class="nav nav-pills">
+                @can('称重管理-查询')
+                    <li class="nav-item">
+                        <a class="nav-link" href="{{url('package/weigh/index')}}" :class="{active:isActive('index',3)}">记录</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="{{url('package/weigh/measureMonitor')}}" :class="{active:isActive('measureMonitor',3)}">设备</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="{{url('package/weigh/statistics')}}" :class="{active:isActive('statistics',3)}">统计</a>
+                    </li>@endcan
+                @can('称重管理-录入')
+                    <li class="nav-item">
+                        <a class="nav-link text-dark" href="{{url('package/weigh/create')}}" :class="{active:isActive('create',3)}">手动录入</a>
+                    </li>@endcan
+        </ul>
+    </div>
+</div>

+ 1 - 1
resources/views/weight/package/menu.blade.php → resources/views/package/weigh/record/menu.blade.php

@@ -3,7 +3,7 @@
         <ul class="nav nav-pills">
             @can('称重管理-查询')
                 <li class="nav-item">
-                    <a class="nav-link" href="{{url('package/')}}" :class="{active:isActive('',2)}">查询</a>
+                    <a class="nav-link" href="{{url('package/weigh/index')}}" :class="{active:isActive('',4)}">查询</a>
                 </li> @endcan
         </ul>
     </div>

+ 2 - 1
resources/views/weight/package/statistics.blade.php → resources/views/package/weigh/statistics.blade.php

@@ -4,7 +4,8 @@
 
 @section('content')
     <span id="nav2">
-        @component('weight.menu')@endcomponent
+        @component('package.menu')@endcomponent
+        @component('package.weigh.menu')@endcomponent
     </span>
     <div class="d-none" id="statistics">
         <div class="container-fluid">

+ 0 - 0
resources/views/weight/weightExcepted/index.blade.php → resources/views/package/weightExcepted/index.blade.php


+ 0 - 0
resources/views/weight/weightExcepted/menu.blade.php → resources/views/package/weightExcepted/menu.blade.php


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

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

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

@@ -19,9 +19,10 @@
             <li class="nav-item">
                 <a class="nav-link" href="{{url('process/recycle')}}" :class="{active:isActive('recycle',2)}">回收站</a>
             </li>@endcan
+            @can('二次加工管理-相关设置')
             <li class="nav-item">
                 <a class="nav-link text-dark" href="{{url('process/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
-            </li>
+            </li>@endcan
         </ul>
     </div>
 </div>

+ 23 - 29
resources/views/rejected/create.blade.php

@@ -143,7 +143,7 @@
                                 <td>
                                     <div class="form-group mb-0">
                                         <label for="logistic_number" class="col-form-label text-right">原单号</label>
-                                        <button class="btn btn-outline-primary btn-sm" @click="seek_order();billInputting.logistic_number='原单退回'" style="transform: scale(0.9)">原单退回</button>
+                                        <button class="btn btn-outline-primary btn-sm" @click="billInputting.logistic_number='原单退回'" style="transform: scale(0.9)">原单退回</button>
                                         <input type="text" class="form-control" :class="[errors.logistic_number?'is-invalid':'']"
                                                data-focusOrder="7"
                                                name="logistic_number" id="logistic_number" autocomplete="off"
@@ -288,7 +288,7 @@
                                     <div class="form-group mb-0">
                                         <label for="amount" class="col-form-label text-right">数量</label>
                                         <input type="" class="form-control" :class="[errors.amount?'is-invalid':'']"
-                                               data-focusOrder="13"
+                                               data-focusOrder="12"
                                                name="amount" id="amount" autocomplete="off" v-model="itemInputting.amount" required>
                                         <span class="invalid-feedback" v-if="errors.amount"><strong>@{{errors.amount[0] }}</strong></span>
                                     </div>
@@ -298,10 +298,10 @@
                                         <label for="qualityLabel.name" class="col-form-label text-right">是否正品</label>
                                         <div class="form-control" :class="[errors.id_quality_label?'is-invalid':'']">
                                             <span><input id="id_quality_label_space" type="radio" name="id_quality_label"
-                                                         data-focusOrder="12" required="required" checked><label
+                                                         data-focusOrder="13" required="required" checked><label
                                                     for="id_quality_label_space">留空</label>&nbsp;</span>
                                             <span v-for="qualityLabel in qualityLabels">
-                                                <input type="radio" name="id_quality_label" :value="qualityLabel.id" data-focusOrder="12"
+                                                <input type="radio" name="id_quality_label" :value="qualityLabel.id" data-focusOrder="13"
                                                        :id="'id_quality_label_'+qualityLabel.id"
                                                        v-model="itemInputting.id_quality_label" required><label
                                                     for="'id_quality_label_'+qualityLabel.id">@{{qualityLabel.name}}</label>&nbsp;</span>
@@ -469,11 +469,12 @@
                         if(response.data.success==='true'){
                             if(response.data.result==='true'){
                                 tempTip.okWindow('该退回单号"'+number+'"已有录入其他单','知道了')
-                            }
+                            }else _this.seek_order();
                         }
                     }).catch(function (response) {
                         console.log(response);
                     });
+
                 },
                 barcode_goodsChange:function(e){
                     let _this=this;
@@ -973,33 +974,26 @@
                 //根据退回单寻找WMS订单填充已有字段
                 seek_order(){
                     let _this=this;
-                    let soreference5=this.billInputting.logistic_number_return;
-                    if (!soreference5) return;
-                    axios.post('{{url('apiLocal/rejectedBill/seekOrder')}}',{soreference5:soreference5})
+                    let logistic_number_return=this.billInputting.logistic_number_return;
+                    if (!logistic_number_return) return;
+                    axios.post('{{url('apiLocal/rejectedBill/seekOrder')}}',{logistic_number_return:logistic_number_return})
                         .then(function (response) {
                             if (response.data.success){
-                                let id_owner='';
-                                let id_logistic_return='';
-                                _this.owners.every(function (owner) {
-                                    if (owner.code===response.data.data.customerid){
-                                        id_owner=owner.id;return false;
-                                    }
-                                    return  true;
-                                });
-                                _this.logistics.every(function (logistic) {
-                                    if (logistic.code===response.data.data.carrierid){
-                                        id_logistic_return=logistic.id;return false;
-                                    }
-                                    return  true;
-                                });
-                                if (id_owner) _this.billInputting.id_owner=id_owner;
-                                _this.billInputting.sender=response.data.data.c_contact;
-                                if (id_logistic_return) _this.billInputting.id_logistic_return=id_logistic_return;
-                                _this.billInputting.order_number=response.data.data.soreference1;
-                                _this.billInputting.mobile_sender=response.data.data.c_tel2;
+                                if(response.data.data.owner_id)_this.billInputting.id_owner=response.data.data.owner_id;
+                                if(response.data.data.logistic_id)_this.billInputting.id_logistic_return = response.data.data.logistic_id;
+                                if(response.data.data.consignee_name)_this.billInputting.sender = response.data.data.consignee_name;
+                                if(response.data.data.consignee_phone)_this.billInputting.mobile_sender = response.data.data.consignee_phone;
+                                if(response.data.data.client_code)_this.billInputting.order_number = response.data.data.client_code;
+                                if(response.data.data.logistic_number)_this.billInputting.logistic_number = response.data.data.logistic_number;
+                                tempTip.setDuration(2000);
+                                tempTip.showSuccess('原单信息已填充');
+                                return;
                             }
-                        })
-                }
+                            tempTip.setDuration(2000);
+                            tempTip.show('没有找到对应的数据,可手动填写 ');
+                        });
+                },
+
             },
             filters:{
                 isLoaded:function (value) {

+ 4 - 2
resources/views/store/blindReceive/menu.blade.php

@@ -3,12 +3,14 @@
     <div class="container-fluid nav3">
         <div class="card menu-third" >
             <ul class="nav nav-pills">
+                @can('入库管理-Excel下载')
                     <li class="nav-item">
                         <a class="nav-link" href="{{url('store/blindReceive/excels')}}" :class="{active:isActive('excels',3)}">Excel下载</a>
-                    </li>
+                    </li>@endcan
+                @can('入库管理-手持入口')
                     <li class="nav-item">
                         <a class="nav-link" href="{{url('store/blindReceive')}}" :class="{active:isActive('',3)}">手持入口</a>
-                    </li>
+                    </li>@endcan
             </ul>
         </div>
     </div>

+ 19 - 4
resources/views/waybill/index.blade.php

@@ -54,7 +54,7 @@
                 <tr>
                     <th class="table-header-layer-1" colspan="4"></th>
                     <th class="table-header-layer-1" colspan="11"><span class="fa fa-file-text-o"></span> 运单信息</th>
-                    <th class="table-header-layer-1" colspan="12"><span class="fa fa-truck"></span> 运输信息</th>
+                    <th class="table-header-layer-1" colspan="13"><span class="fa fa-truck"></span> 运输信息</th>
                     <th class="table-header-layer-1" colspan="5"><span class="fa fa-rmb"></span> 费用信息
                     @can('运输管理-删除')
                         <th class="table-header-layer-1" colspan="1"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
@@ -140,9 +140,22 @@
                     <td class="td-cool text-muted">@{{waybill.district}}</td>
                     <td class="td-cool text-muted">@{{waybill.destination}}</td>
                     <td class="td-cool">@{{waybill.carrier}}</td>
-                    <td class="td-cool"><span v-if="waybill.type==='专线'">@{{waybill.carrier_bill}}</span>
-                        <span v-if="waybill.type==='直发车'">
-                            <span v-if="waybill.carType">@{{ waybill.carType.name }}<i v-if="waybill.carType.length">(@{{waybill.carType.length}}米)</i></span></span></td>
+                    <td class="td-cool">
+                        <span v-if="waybill.carrier_bill">
+                            @{{waybill.carrier_bill}}<span v-if="waybill.carType">/@{{ waybill.carType.name }}<i v-if="waybill.carType.length">(@{{waybill.carType.length}}米)</i></span>
+                        </span>
+{{--                        <span v-if="waybill.type==='专线'">@{{waybill.carrier_bill}}</span>--}}
+{{--                        <span v-if="waybill.type==='直发车'">--}}
+{{--                            <span v-if="waybill.carType">--}}
+{{--                                @{{ waybill.carType.name }}<i v-if="waybill.carType.length">(@{{waybill.carType.length}}米)</i>--}}
+{{--                            </span>--}}
+{{--                        </span>--}}
+                    </td>
+                    <td class="td-cool">
+                        <span v-if="waybill.type === '直发车'">
+                            @{{ waybill.car_owner_info }}
+                        </span>
+                    </td>
                     <td class="td-cool"><span v-if="waybill.warehouse_weight">@{{waybill.warehouse_weight|filterZero}}  @{{waybill.warehouse_weight_unit}}</span></td>
                     <td class="td-cool"><span v-if="waybill.carrier_weight">@{{waybill.carrier_weight|filterZero}}  @{{waybill.carrier_weight_unit}}</span></td>
                     <td class="td-cool text-center" style="position: relative" @mouseenter="btnRefreshWeightZoomOut(waybill)" @mouseleave="btnRefreshWeightZoomIn(waybill)">
@@ -390,6 +403,7 @@
                         {name:'status',type:'select',placeholder: '运单状态',data:this.status},
                         {name:'source_bill',type:'input',tip: '上游单号:可在左侧增加百分号(%)进行模糊搜索',placeholder: '上游单号'},
                         {name:'recipient',type:'input',tip: '收货人姓名:可在左侧增加百分号(%)进行模糊搜索',placeholder: '收货人姓名'},
+                        {name:'car_owner_info',type:'input',tip: '车辆信息:可在左侧增加百分号(%)进行模糊搜索',placeholder: '车辆信息'},
                     ],
                     [
                         {name:'wms_bill_number',type:'input',tip:'WMS单号:可在两侧增加百分号(%)进行模糊搜索',placeholder: 'WMS单号'},
@@ -435,6 +449,7 @@
                     {name:'destination',value: '目的地', class:"td-cool"},
                     {name:'carrier',value: '承运商', class:"td-cool"},
                     {name:'carrier_bill',value: '单号/车型', neglect: true, class:"td-cool"},
+                    {name:'car_owner_info',value: '车辆信息', neglect: true, class:"td-cool"}, // 车辆信息
                     {name:'warehouse_weight',value: '仓库计抛', neglect: true, class:"td-cool"},
                     {name:'carrier_weight',value: '承运商计抛', neglect: true, class:"td-cool"},
                     {name:'warehouse_weight_other',value: '仓库计重', neglect: true, class:"td-cool"},

+ 0 - 31
resources/views/weight/menu.blade.php

@@ -1,31 +0,0 @@
-
-<div class="container-fluid nav2" id="nav2">
-    <div class="card">
-        <ul class="nav nav-pills">
-                @can('称重管理-查询')
-                <li class="nav-item">
-                    <a class="nav-link" href="{{url('package/')}}" :class="{active:isActive('',2)}">记录</a>
-                </li>
-                <li class="nav-item">
-                    <a class="nav-link" href="{{url('package/measureMonitor')}}" :class="{active:isActive('measureMonitor',2)}">设备</a>
-                </li>
-                <li class="nav-item">
-                    <a class="nav-link" href="{{url('package/statistics')}}" :class="{active:isActive('statistics',2)}">统计</a>
-                </li>@endcan
-                @can('称重管理-录入')
-                <li class="nav-item">
-                    <a class="nav-link text-dark" href="{{url('package/create')}}" :class="{active:isActive('create',2)}">手动录入</a>
-                </li>@endcan
-                @can('称重管理-查询')
-                <li class="nav-item">
-                    <a class="nav-link text-dark" href="{{url('package/weightExcepted/indexCreate')}}" :class="{active:isActive('weightExcepted',2)}">异常记录</a>
-                </li>@endcan
-                @can('称重管理-查看异常')
-                <li class="nav-item">
-                    <a class="nav-link text-dark" href="{{url('package/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
-                </li>@endcan
-
-
-        </ul>
-    </div>
-</div>

+ 3 - 1
routes/apiLocal.php

@@ -48,7 +48,6 @@ Route::group(['prefix' => 'order'], function () {
         Route::post('endOrderIssue', 'OrderIssueController@apiEndOrderIssue');
         Route::post('getOrderInfoByClientNo', 'OrderIssueController@apiGetOrderInfoByClientNo');
         Route::post('isExistByOrderNo','OrderIssueController@isExistByOrderNoApi');
-        Route::post('updateLogisticNumberReturn','OrderIssueController@updateLogisticNumberReturnApi');
         Route::post('editSecondClientNo','OrderIssueController@editSecondClientNoApi');
         Route::post('endOrderIssues','OrderIssueController@endOrderIssuesApi');
         Route::post('editSecondLogisticNumber','OrderIssueController@editSecondLogisticNumberApi');
@@ -76,6 +75,9 @@ Route::group(['prefix' => 'order'], function () {
         Route::group(['prefix'=>'recycle'],function(){
             Route::post('recover','OrderIssueController@recoverOrderIssueApi');
         });
+        Route::post('userWorkgroups/add','OrderIssueController@addUserWorkgroup');
+        Route::post('userWorkgroups/delete','OrderIssueController@destroyUserWorkgroup');
+        Route::post('batchOthers','OrderIssueController@batchOthers');
     });
 
     Route::group(['prefix'=>'tracking'],function (){

+ 28 - 5
routes/web.php

@@ -223,6 +223,12 @@ Route::group(['prefix'=>'maintenance'],function(){
     Route::resource('userOwnerGroup', 'UserOwnerGroupController');
     Route::resource('processMethod', 'ProcessMethodController');
     Route::resource('feature', 'FeatureController');
+    Route::resource('mail', 'SendEmailsController');
+    Route::post('mail/addRole', 'SendEmailsController@addRole')->name('mail.addRole');
+    Route::post('mail/deleteRole', 'SendEmailsController@deleteRole')->name('mail.deleteRole');
+    Route::post('mail/updateTemplate', 'SendEmailsController@updateTemplate')->name('mail.updateTemplate');
+    Route::post('mail/updateRemark', 'SendEmailsController@updateRemark')->name('mail.updateRemark');
+    Route::post('mail/active', 'SendEmailsController@active')->name('mail.active');
 });
 Route::get('maintenance', function () {return view('maintenance.index');});
 
@@ -320,7 +326,7 @@ Route::group(['prefix'=>'package'],function(){
     });
     /** 统计 */
     Route::group(['prefix'=>'statistics'],function(){
-        Route::any('export','PackageController@statisticsExport');
+        Route::any('export','WeighController@statisticsExport');
     });
     /** 异常 */
     Route::group(['prefix'=>'weightExcepted'],function(){
@@ -329,13 +335,30 @@ Route::group(['prefix'=>'package'],function(){
         Route::any('export/{type}','WeighExceptedController@export');
     });
 
-    Route::any('export','PackageController@export');
-    Route::get('statistics','PackageController@statistics');
-    Route::get('relating', function () {return view('weight.menuWeight');});
+    Route::any('export','WeighController@export');
+    Route::get('statistics','WeighController@statistics');
+    Route::get('relating', function () {return view('package.measureMonitor.menu');});
 
     Route::resource('measureMonitor','MeasureMonitorController');
+
+    Route::group(['prefix' => 'weigh'], function () {
+        Route::get('statistics','WeighController@statistics');
+        /** 设备 */
+        Route::group(['prefix'=>'measureMonitor'],function(){
+            Route::any('speech','MeasureMonitorController@speech');
+            Route::post('data','MeasureMonitorController@data');
+        });
+        /** 统计 */
+        Route::group(['prefix'=>'statistics'],function(){
+            Route::any('export','WeighController@statisticsExport');
+        });
+        Route::resource('measureMonitor','MeasureMonitorController');
+    });
+    Route::get('weigh/index','WeighController@index');
+    Route::resource('weigh','WeighController');
+    Route::resource('logistic','PackageLogisticController');
 });
-Route::resource('package','PackageController');
+Route::resource('package','WeighController');
 
 /** 入库 */
 Route::group(['prefix'=>'store'],function(){

+ 25 - 0
syncProject.sh

@@ -0,0 +1,25 @@
+#!/bin/bash
+
+cd $src
+Ip="was.baoshi56.com"
+username="haozi"
+password="haozi"
+files=("app" "config" "database" "public" "resources" "routes" "webpack.mix.js" "composer.json" "tests")
+src=/var/www/bswas_test
+dsc=/var/www/was
+
+for i in ${files[*]}
+do
+expect -c "
+spawn scp -P 10022 -r $username@$Ip:$dsc/$i $src/$i
+expect {
+\"*assword\" {set timeout 120; send \"$password\r\";}
+\"yes/no\" {send \"yes\r\"; exp_continue;}
+}
+expect eof"
+done
+
+sudo php artisan migrate
+sudo composer update
+sudo npm run dev
+

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