Parcourir la source

Merge branch 'master' into yang

yuang il y a 4 ans
Parent
commit
b4813a8b2f
45 fichiers modifiés avec 1662 ajouts et 376 suppressions
  1. 3 0
      app/DeliveryAppointment.php
  2. 2 2
      app/Filters/OrderIssueFilters.php
  3. 114 47
      app/Filters/WorkOrderFilters.php
  4. 20 3
      app/Http/Controllers/DeliveryAppointmentController.php
  5. 3 3
      app/Http/Controllers/OrderIssueController.php
  6. 8 8
      app/Http/Controllers/ReceivingTaskController.php
  7. 4 68
      app/Http/Controllers/TestController.php
  8. 18 0
      app/Http/Controllers/WorkOrderCommoditiesController.php
  9. 143 1
      app/Http/Controllers/WorkOrderController.php
  10. 31 1
      app/Http/Controllers/api/thirdPart/weixin/ProcurementController.php
  11. 1 1
      app/RejectedBill.php
  12. 36 0
      app/Services/DeliveryAppointmentService.php
  13. 1 1
      app/Services/LogisticService.php
  14. 9 4
      app/Services/OrderRejectingStatusService.php
  15. 1 0
      app/Services/OwnerBillReportService.php
  16. 1 0
      app/Services/OwnerFeeDetailService.php
  17. 10 2
      app/Services/RejectedService.php
  18. 1 1
      app/Services/StorageService.php
  19. 105 0
      app/Services/WorkOrderCommoditiesService.php
  20. 5 0
      app/Services/WorkOrderExpressAbnormalService.php
  21. 37 9
      app/Services/WorkOrderInformationChangeService.php
  22. 41 27
      app/Services/WorkOrderInterceptService.php
  23. 1 1
      app/Services/WorkOrderMistakeService.php
  24. 17 0
      app/Services/WorkOrderService.php
  25. 38 8
      app/WorkOrder.php
  26. 15 4
      app/WorkOrderDetail.php
  27. 1 1
      config/users.php
  28. 41 0
      database/migrations/2022_01_19_172151_work_order_details_add_indemnity_money.php
  29. 32 0
      database/migrations/2022_01_21_111254_work_orders_add_work_order_detail_id.php
  30. 32 0
      database/migrations/2022_01_21_132626_create_work_order_user_workgroup_table.php
  31. 2 2
      resources/views/equipment/_detailInfo.blade.php
  32. 21 0
      resources/views/equipment/_failTipList.blade.php
  33. 76 24
      resources/views/equipment/_location.blade.php
  34. 38 0
      resources/views/equipment/_locationAttr.blade.php
  35. 245 16
      resources/views/equipment/index.blade.php
  36. 1 1
      resources/views/order/issue/index.blade.php
  37. 50 45
      resources/views/order/workOrder/_issue_logs.blade.php
  38. 1 1
      resources/views/order/workOrder/_order_commodity_info.blade.php
  39. 32 26
      resources/views/order/workOrder/_process_logs.blade.php
  40. 40 0
      resources/views/order/workOrder/_rejected_item_equals_order_commodity.blade.php
  41. 373 66
      resources/views/order/workOrder/index.blade.php
  42. 1 1
      resources/views/store/deliveryAppointment/appointment.blade.php
  43. 3 2
      resources/views/transport/waybill/index.blade.php
  44. 7 0
      routes/apiLocal.php
  45. 1 0
      routes/web.php

+ 3 - 0
app/DeliveryAppointment.php

@@ -55,6 +55,9 @@ class DeliveryAppointment extends Model
     const TYPE = [
         0 => "质检",
     ];
+    //禁止送货日期列表 REDIS key
+    const BAN = "DELIVERY_BAN_ON_DATE";
+
     protected $appends=[
         "period"
     ];

+ 2 - 2
app/Filters/OrderIssueFilters.php

@@ -277,7 +277,7 @@ class OrderIssueFilters
 
     public function is_new_rejecting($is_new_rejecting)
     {
-        $this->queryBuilder->where('order_issues.is_new_rejecting', $is_new_rejecting);
+        $this->getOrderDetailQuery()->where('order_details.is_new_rejecting',$is_new_rejecting);
     }
 
     public function logistic($logistic_id)
@@ -383,7 +383,7 @@ class OrderIssueFilters
 
     public function rejectingStatus($rejectingStatus)
     {
-        $this->queryBuilder->where('order_issues.rejecting_status', $rejectingStatus);
+        $this->getOrderDetailQuery()->where('order_details.rejecting_status',$rejectingStatus);
     }
 
     public function order_issue_ids($order_issue_ids)

+ 114 - 47
app/Filters/WorkOrderFilters.php

@@ -4,6 +4,7 @@
 namespace App\Filters;
 
 use App\Order;
+use App\OrderDetail;
 use App\OrderIssue;
 use App\OrderIssueProcessLog;
 use App\OrderIssueType;
@@ -17,6 +18,7 @@ use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Gate;
 
 class WorkOrderFilters
@@ -50,6 +52,14 @@ class WorkOrderFilters
         'tags',
         'shop_name',
         'work_order_process_log',
+        'rejectingStatus',
+        'logistic_indemnity_money',
+        'logistic_express_remission',
+        'bao_shi_indemnity_money',
+        'bao_shi_express_remission',
+        'user_owner_group_id',
+        'user_work_group_id',
+        'rejecting_status',
     ];
     protected $array_filter;
     protected $params = [];
@@ -62,6 +72,7 @@ class WorkOrderFilters
     protected $orderIssueQuery;
     protected $shopQuery;
     protected $workOrderProcessLogQuery;
+    protected $orderDetailQuery;
 
     public function __construct(Request $request)
     {
@@ -118,23 +129,23 @@ class WorkOrderFilters
     {
         $status = [];
 
-        if (Gate::allows('订单管理-工单处理-宝时编辑')){
-            array_push($status,1,4);
+        if (Gate::allows('订单管理-工单处理-宝时编辑')) {
+            array_push($status, 1, 4);
         }
-        if (Gate::allows('订单管理-工单处理-货主编辑')){
-            array_push($status,1,2,3,4,6);
+        if (Gate::allows('订单管理-工单处理-货主编辑')) {
+            array_push($status, 1, 2, 3, 4, 6);
         }
-        if (Gate::allows('订单管理-工单处理-承运商编辑')){
-            array_push($status,1,2,3,4,6);
+        if (Gate::allows('订单管理-工单处理-承运商编辑')) {
+            array_push($status, 1, 2, 3, 4, 6);
         }
 
         if (!isset($this->params['is_end'])) {
             $this->queryBuilder->where('status', '!=', 5);      // 过滤已完成
         } else {
-            array_push($status,5);
+            array_push($status, 5);
         }
 
-        $this->queryBuilder->whereIn('status',$status);
+        $this->queryBuilder->whereIn('status', $status);
     }
 
     private function afterFilterOwner($owner_ids)
@@ -154,23 +165,27 @@ class WorkOrderFilters
     public function afterFileIssueType()
     {
         if (Gate::allows('订单管理-工单处理-客服编辑') || Gate::allows('订单管理-工单处理-货主编辑')) {
-            $this->getOrderIssueTypeQuery()->whereIn('name', ['拦截','取消拦截', '信息更改', '其他', '快递异常', '错漏发', '破损', '快递丢件']);
+            $this->getOrderIssueTypeQuery()->whereIn('name', ['拦截', '取消拦截', '信息更改', '其他', '快递异常', '错漏发', '破损', '快递丢件']);
         } else if (Gate::allows('订单管理-工单处理-承运商编辑')) {
-            $this->getOrderIssueTypeQuery()->whereIn('name', ['拦截','取消拦截', '信息更改', '破损', '快递丢件', '快递异常']);
+            $this->getOrderIssueTypeQuery()->whereIn('name', ['拦截', '取消拦截', '信息更改', '破损', '快递丢件', '快递异常']);
         }
     }
 
     public function beforeApply()
     {
 
-        if ($this->shopQuery){
-            $this->getOrderQuery()->whereIn('orders.shop_id',$this->shopQuery);
+        if ($this->shopQuery) {
+            $this->getOrderQuery()->whereIn('orders.shop_id', $this->shopQuery);
         }
 
         if ($this->orderPackageQuery) {
             $this->queryBuilder->whereIn('order_id', $this->orderPackageQuery);
         }
 
+        if($this->orderDetailQuery){
+            $this->queryBuilder->whereIn('order_id',$this->orderDetailQuery);
+        }
+
         if ($this->orderQuery) {
             $this->queryBuilder->whereIn('order_id', $this->orderQuery);
         }
@@ -179,11 +194,11 @@ class WorkOrderFilters
             $this->queryBuilder->whereIn('order_issue_type_id', $this->issueTypeQuery);
         }
 
-        if ($this->orderIssueQuery){
+        if ($this->orderIssueQuery) {
             $this->queryBuilder->whereIn('work_orders.order_id', $this->orderIssueQuery);
         }
 
-        if($this->workOrderProcessLogQuery){
+        if ($this->workOrderProcessLogQuery) {
             $this->queryBuilder->whereIn('work_orders.id', $this->workOrderProcessLogQuery);
         }
 
@@ -193,11 +208,11 @@ class WorkOrderFilters
     public function orderByTag()
     {
         $this->queryBuilder->orderByDesc('work_order_status');
-        if (Gate::allows('订单管理-工单处理-客服编辑')){
+        if (Gate::allows('订单管理-工单处理-客服编辑')) {
             $this->queryBuilder->orderByDesc("bao_shi_tag");
-        } else if (Gate::allows('订单管理-工单处理-货主编辑')){
+        } else if (Gate::allows('订单管理-工单处理-货主编辑')) {
             $this->queryBuilder->orderByDesc("owner_tag");
-        } else if (Gate::allows('订单管理-工单处理-承运商编辑')){
+        } else if (Gate::allows('订单管理-工单处理-承运商编辑')) {
             $this->queryBuilder->orderByDesc("logistic_tag");
         }
         $this->queryBuilder->orderBy('created_at');
@@ -227,7 +242,6 @@ class WorkOrderFilters
         return $this->issueTypeQuery;
     }
 
-
     public function getOrderIssueQuery(): Builder
     {
         if (!$this->orderIssueQuery) {
@@ -254,11 +268,18 @@ class WorkOrderFilters
 
     public function getWorkOrderProcessLogQuery(): Builder
     {
-        if (!$this->workOrderProcessLogQuery){
+        if (!$this->workOrderProcessLogQuery) {
             $this->workOrderProcessLogQuery = WorkOrderProcessLog::query()->select('work_order_id');
         }
         return $this->workOrderProcessLogQuery;
     }
+    public function getOrderDetailQuery(): Builder
+    {
+        if (!$this->orderDetailQuery){
+            $this->orderDetailQuery = OrderDetail::query()->select('order_id');
+        }
+        return $this->orderDetailQuery;
+    }
 
     public function id($id)
     {
@@ -357,70 +378,116 @@ class WorkOrderFilters
 
     public function process_progress($process_progress)
     {
-        $this->searchWay($this->queryBuilder,$process_progress,'work_orders.process_progress');
+        $this->searchWay($this->queryBuilder, $process_progress, 'work_orders.process_progress');
     }
 
-    public function order_issue_log($log_content){
+    public function order_issue_log($log_content)
+    {
         $order_issue_process_log_query = OrderIssueProcessLog::query()->select('order_issue_id')->where('content', 'like', $log_content);
-        $order_issue_query = OrderIssue::query()->select('order_id')->whereIn('id',$order_issue_process_log_query);
-        $this->queryBuilder->whereIn('order_id',$order_issue_query);
+        $order_issue_query = OrderIssue::query()->select('order_id')->whereIn('id', $order_issue_process_log_query);
+        $this->queryBuilder->whereIn('order_id', $order_issue_query);
     }
 
     public function log_content($log_content)
     {
         $order_issue_process_log_query = OrderIssueProcessLog::query()->selectRaw('order_issue_id')->where('content', 'like', $log_content);
-        if (!array_key_exists('addtime',$this->params) ) {
+        if (!array_key_exists('addtime', $this->params)) {
             $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->getOrderIssueQuery()->whereIn('id',$order_issue_process_log_query);
+        $this->getOrderIssueQuery()->whereIn('id', $order_issue_process_log_query);
     }
 
-    public function status($status){
+    public function status($status)
+    {
         $status_list = [];
-        if ($status == '承运商处理'){
-            array_push($status_list,3);
+        if ($status == '承运商处理') {
+            array_push($status_list, 3);
         } elseif ($status == '宝时处理') {
-            array_push($status_list,4,1);
-        } elseif ($status == '货主处理'){
-            array_push($status_list,2,6);
+            array_push($status_list, 4, 1);
+        } elseif ($status == '货主处理') {
+            array_push($status_list, 2, 6);
         }
-        $this->queryBuilder->whereIn('status',$status_list);
+        $this->queryBuilder->whereIn('status', $status_list);
     }
 
-    public function tags($tag){
+    public function tags($tag)
+    {
         $status = $this->array_filter['status'] ?? null;
-        if ($status){
-            switch ($status){
+        if ($status) {
+            switch ($status) {
                 case '宝时处理':
-                    $this->queryBuilder->where('bao_shi_tag',$tag);
+                    $this->queryBuilder->where('bao_shi_tag', $tag);
                     break;
                 case '货主处理':
-                    $this->queryBuilder->where('owner_tag',$tag);
+                    $this->queryBuilder->where('owner_tag', $tag);
                     break;
                 case '承运商处理':
-                    $this->queryBuilder->where('logistic_tag',$tag);
+                    $this->queryBuilder->where('logistic_tag', $tag);
                     break;
             }
-            return ;
+            return;
         }
-        if (Gate::allows('订单管理-工单处理-宝时编辑')){
-            $this->queryBuilder->where('bao_shi_tag',$tag);
-        } else if (Gate::allows('订单管理-工单处理-货主编辑')){
-            $this->queryBuilder->where('owner_tag',$tag);
-        } else if (Gate::allows('订单管理-工单处理-承运商编辑')){
-            $this->queryBuilder->where('logistic_tag',$tag);
+        if (Gate::allows('订单管理-工单处理-宝时编辑')) {
+            $this->queryBuilder->where('bao_shi_tag', $tag);
+        } else if (Gate::allows('订单管理-工单处理-货主编辑')) {
+            $this->queryBuilder->where('owner_tag', $tag);
+        } else if (Gate::allows('订单管理-工单处理-承运商编辑')) {
+            $this->queryBuilder->where('logistic_tag', $tag);
         }
     }
 
     public function shop_name($shop_name)
     {
-        $this->searchWay($this->getShopQuery(),$shop_name,'shops.name');
+        $this->searchWay($this->getShopQuery(), $shop_name, 'shops.name');
     }
 
     public function work_order_process_log($work_order_process_log)
     {
-        $this->searchWay($this->getWorkOrderProcessLogQuery(),$work_order_process_log,'work_order_process_logs.content');
+        $this->searchWay($this->getWorkOrderProcessLogQuery(), $work_order_process_log, 'work_order_process_logs.content');
+    }
+
+    public function logistic_indemnity_money($logistic_indemnity_money)
+    {
+        $this->queryBuilder->where('logistic_indemnity_money',$logistic_indemnity_money);
+    }
+
+    public function logistic_express_remission($logistic_express_remission)
+    {
+        $this->queryBuilder->where('logistic_express_remission',$logistic_express_remission);
+    }
+
+    public function bao_shi_indemnity_money($bao_shi_indemnity_money)
+    {
+        $this->queryBuilder->where('bao_shi_indemnity_money',$bao_shi_indemnity_money);
+    }
+
+    public function bao_shi_express_remission($logistic_indemnity_money)
+    {
+        $this->queryBuilder->where('bao_shi_express_remission',$logistic_indemnity_money);
+    }
+
+    public function user_owner_group_id($user_owner_group_id)
+    {
+        $this->queryBuilder->where('user_owner_group_id',$user_owner_group_id);
+    }
+
+    public function user_work_group_id($user_work_group_id)
+    {
+        $this->queryBuilder->whereHas('userWorkGroups',function($query)use($user_work_group_id){
+            $this->searchWay($query,$user_work_group_id,'user_workgroup_id');
+        });
+    }
+
+    public function rejecting_status($rejecting_status)
+    {
+        $query = OrderDetail::query()->select('order_id')->where('rejecting_status',$rejecting_status);
+        $this->queryBuilder->whereIn('order_id',$query);
+    }
+
+    public function rejectingStatus($rejectingStatus)
+    {
+        $this->getOrderDetailQuery()->where('rejecting_status',$rejectingStatus);
     }
 }

+ 20 - 3
app/Http/Controllers/DeliveryAppointmentController.php

@@ -98,8 +98,15 @@ class DeliveryAppointmentController extends Controller
                         $available = $total-$used; //可用产能
                         if ($available > $need)$periodArr["isAvailable"] = true;
                     }
+
+                    if (app("DeliveryAppointmentService")->isBanOnDeliveryDate($date)){
+                        $periodArr["isAvailable"] = false;
+                    }
+
                     $periods[] = $periodArr;
                 }
+
+
             }else{
                 foreach (DeliveryAppointment::PERIOD as $key=>$period){
                     $period = explode("-",$period);
@@ -109,6 +116,11 @@ class DeliveryAppointmentController extends Controller
                     $used = $map[$date."-".$key] ?? 0; //已使用产能
                     $available = $total-$used; //可用产能
                     if ($available > $need)$periodArr["isAvailable"] = true;
+
+                    if (app("DeliveryAppointmentService")->isBanOnDeliveryDate($date)){
+                        $periodArr["isAvailable"] = false;
+                    }
+
                     $periods[] = $periodArr;
                 }
             }
@@ -121,7 +133,7 @@ class DeliveryAppointmentController extends Controller
         if ($codes){
             $codes = array_filter(array_unique(preg_split('/[,, ]+/u', $codes)));
             if (count($codes)>0){
-                $asnCount = Store::query()->where("asn_code",$codes)->count();
+                $asnCount = Store::query()->whereIn("asn_code",$codes)->count();
                 $codes = count($codes)===$asnCount ? implode(",",$codes) : null;
             }else{
                 $codes = null;
@@ -165,7 +177,9 @@ class DeliveryAppointmentController extends Controller
             if ($result){
                 $total = $warehouse->production_capacity*DeliveryAppointment::HOUR[$selectDate["time"]];
                 $available = $total-$result->capacity;
-                if ($available < $need)$this->success(["isFail"=>true]);
+                if ($available < $need || app("DeliveryAppointmentService")->isBanOnDeliveryDate($selectDate["date"])){
+                    $this->success(["isFail"=>true]);
+                }
             }
             /** @var \stdClass $appointment */
             $appointment = DeliveryAppointment::query()->create([
@@ -248,7 +262,10 @@ class DeliveryAppointmentController extends Controller
             if ($result){
                 $total = $warehouse->production_capacity*DeliveryAppointment::HOUR[$selectDate["time"]];
                 $available = $total-$result->capacity;
-                if ($available < $appointment->capacity)$this->success(["isFail"=>true]);
+                if ($available < $appointment->capacity ||
+                    app("DeliveryAppointmentService")->isBanOnDeliveryDate($selectDate["date"])){
+                    $this->success(["isFail"=>true]);
+                }
             }
             $update = [
                 "appointment_date"      => $selectDate["date"],

+ 3 - 3
app/Http/Controllers/OrderIssueController.php

@@ -24,7 +24,6 @@ use App\Services\OrderRejectedBillRelationService;
 use App\Services\OrderService;
 use App\Services\OwnerService;
 use App\Services\OrderRejectingStatusService;
-use App\Services\RejectedService;
 use App\Shop;
 use App\UserOwnerGroup;
 use App\UserWorkgroup;
@@ -580,7 +579,7 @@ class OrderIssueController extends Controller
     {
         $json = [];
         $row = [
-            '登记日期', '创建日期', '客户', '客户订单号', '原始承运商', '收货人', '收货电话', '省', '市', '区', '收货人地址',
+            '登记日期', '创建日期', '客户','商铺' ,'客户订单号', '原始承运商', '收货人', '收货电话', '省', '市', '区', '收货人地址',
             '原始运单号', '原始商品', '原始商品名称', '原始商品数量',
             '退回单号', '退单商品名', '退单商品条码', '退单商品数量', '是否正品', '退单状态', '退单备注',
             '操作类型', '说明', '操作者', '情况说明', '问题类别',
@@ -660,7 +659,8 @@ class OrderIssueController extends Controller
                 isset($order_issue->created_at) ? str_split($order_issue->created_at, 10)[0] : '',       // 登记日期
                 isset($order->created_at) ? str_split($order->created_at, 10)[0] : '',             // 创建日期
                 $order->owner->name ?? '',      // 客户
-                $order->client_code,              // 客户订单号
+                $order->shop->name ?? '',       // 商铺
+                $order->client_code,            // 客户订单号
                 $order->logistic->name ?? '',   // 原始承运商
                 $order->consignee_name,         // 收货人
                 $order->consignee_phone,        // 收货电话

+ 8 - 8
app/Http/Controllers/ReceivingTaskController.php

@@ -73,14 +73,14 @@ class ReceivingTaskController extends Controller
             return ['success' => false, 'errors' => ['appointment_number' => ['预约号没有对应的Asn号']]];
         }
 
-        $receiving_task_items = ReceivingTaskItem::query()->whereIn('asn_no',$request->input('asn_nos') ?? [])->get()->map(function($item){
-            return $item->asn_no;
-        })->toArray();
-        if (count($receiving_task_items) >0 ){
-            return [
-                'success' => false,'errors' => ['appointment_number' => '勾选的asn号'.json_encode($receiving_task_items).'已再其他开单入库中有关联']
-            ];
-        }
+//        $receiving_task_items = ReceivingTaskItem::query()->whereIn('asn_no',$request->input('asn_nos') ?? [])->get()->map(function($item){
+//            return $item->asn_no;
+//        })->toArray();
+//        if (count($receiving_task_items) >0 ){
+//            return [
+//                'success' => false,'errors' => ['appointment_number' => ['勾选的asn号'.json_encode($receiving_task_items).'已再其他开单入库中有关联']]
+//            ];
+//        }
 
         if ($delivery_appointment_car->deliveryAppointment->owner_id != $request->input('owner_id')) {
             return ['success' => false, 'errors' => ['appointment_number' => ['预约号与货主未必填项']]];

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

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use App\Components\AsyncResponse;
 use App\Components\Database;
 use App\Components\ErrorPush;
+use App\DeliveryAppointment;
 use App\MaterialBox;
 use App\MaterialBoxModel;
 use App\Order;
@@ -13,6 +14,8 @@ use App\OrderIssue;
 use App\OrderIssueRejectedBill;
 use App\RejectedBill;
 use App\Services\common\BatchUpdateService;
+use App\Services\DeliveryAppointmentService;
+use App\Services\OracleDocAsnHerderService;
 use App\Services\OrderRejectedBillRelationService;
 use App\Services\OrderRejectingStatusService;
 use App\Services\RejectedService;
@@ -51,74 +54,7 @@ class TestController extends Controller
         }
     }
     public function test(Request $request){
-        dd(array_filter(array_unique(preg_split('/[,, ]+/u', "125,456,888, 6 ,  ,"))));
-    }
-
-    public function testOrder()
-    {
-        /** @var OrderRejectedBillRelationService $service */
-        $service = app('OrderRejectedBillRelationService');
-        $service->orderSyncRejectedBill(Order::query()->find(12));
-    }
-
-    public function testRejectedBill()
-    {
-        /** @var OrderRejectedBillRelationService $service */
-        $service = app(OrderRejectedBillRelationService::class);
-        /** @var RejectedBill $item */
-        $item = RejectedBill::query()->find(2);
-        $service->rejectedBillSyncOrder($item);
-    }
-
-    public function getOrder()
-    {
-
-        $query = Order::query()->select('id')->where('client_code','22011700000161');
-        dd(OrderDetail::query()->whereIn('order_id',$query)->get());
-    }
-
-    public function sync_order_issue()
-    {
-        $items = OrderIssueRejectedBill::query()->with('orderIssue')->get();
-        $item_array = $items->chunk(500);
-        foreach ($item_array as $items){
-            $insert_params = [];
-            $update_params = [['logistic_number_return','order_id']];
-            foreach ($items as $item){
-                if (!$item->orderIssue) continue;
-                $insert_params[$item->orderIssue->order_id] = [
-                    'order_id' => $item->orderIssue->order_id,
-                    'is_new_rejecting' => $item->orderIssue->is_new_rejecting,
-                    'rejecting_status' => $item->orderIssue->rejecting_status
-                ];
-                $update_params[] = ['logistic_number_return' => $item->logistic_number_return,'order_id' => $item->orderIssue->order_id];
-            }
-            $this->batchOrderIssueRejectedBIll($update_params);
-            $items = OrderDetail::query()->whereIn('order_id',array_keys($insert_params))->get()->map(function($item){
-                return  $item->order_id;
-            })->toArray();
-            $insert_params = array_filter($insert_params,function($item)use($items){
-                return !in_array($item['order_id'],$items) && !is_null($item['order_id']);
-            });
-            if (count($insert_params) == 0) continue;
-            OrderDetail::query()->insert(array_values($insert_params));
-        }
-    }
-
-
-    public function batchOrderIssueRejectedBIll($array)
-    {
-        /** @var BatchUpdateService $service */
-        $service = app(BatchUpdateService::class);
-        $service->batchUpdate('order_issue_rejected_bill',$array);
-    }
-
-    public function testQuery()
-    {
-        /** @var WorkOrder $item */
-        $item = WorkOrder::query()->with('orderIssueRejectedBills')->find(9);
-        $item->orderIssueRejectedBills()->where('logistic_number_return','75810638245215')->delete();
-        dd($item);
+        dd(Cache::get(DeliveryAppointment::BAN,[]));
     }
 }
 

+ 18 - 0
app/Http/Controllers/WorkOrderCommoditiesController.php

@@ -7,7 +7,9 @@ use App\Services\WorkOrderDetailService;
 use App\Services\WorkOrderLogService;
 use App\Services\WorkOrderService;
 use App\WorkOrder;
+use App\WorkOrderDetail;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Gate;
 
 class WorkOrderCommoditiesController extends Controller
@@ -119,4 +121,20 @@ class WorkOrderCommoditiesController extends Controller
         $workOrder->loadDefaultWith();
         return ['success' => true, 'data' => $workOrder];
     }
+
+    /**
+     * 获取
+     * @param Request $request
+     * @return array
+     */
+    public function getCommodityEqualsMapApi(Request $request): array
+    {
+        if(!Auth::check()){
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        /** @var WorkOrderDetail $work_order_detail */
+        $work_order_detail = WorkOrderDetail::query()->find($request->input('id'));
+        $data = $this->service->getOrderCommoditiesEqualWorkOrderDetailCommoditiesMap($work_order_detail);
+        return ['success' => true,'data' => $data];
+    }
 }

+ 143 - 1
app/Http/Controllers/WorkOrderController.php

@@ -12,10 +12,13 @@ use App\Services\WorkOrderCommoditiesService;
 use App\Services\WorkOrderDetailService;
 use App\Services\WorkOrderLogService;
 use App\Services\WorkOrderService;
+use App\UserOwnerGroup;
+use App\UserWorkgroup;
 use App\WorkOrder;
 use App\WorkOrderDetail;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Gate;
+use Oursdreams\Export\Export;
 
 class WorkOrderController extends Controller
 {
@@ -74,9 +77,11 @@ class WorkOrderController extends Controller
 
         $owners = $this->ownerService->getAuthorizedOwners();
 
+        $userWorkgroup = UserWorkgroup::query()->select('id', 'name')->get();
+        $userOwnerGroup = UserOwnerGroup::query()->select('id', 'name')->get();
 
         $this->service->tags($workOrders);
-        return view('order.workOrder.index', compact('workOrders', 'logistics', 'orderIssueTypes', 'owners'));
+        return view('order.workOrder.index', compact('workOrders', 'logistics', 'orderIssueTypes', 'owners', 'userWorkgroup', 'userOwnerGroup'));
     }
 
     /**
@@ -193,4 +198,141 @@ class WorkOrderController extends Controller
         }
     }
 
+    public function updateRemissionApi(Request $request): array
+    {
+        if (Gate::denies('订单管理-工单处理-宝时编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        if (!$request->has(['id', 'column'])) {
+            return ['success' => false, 'message' => '参数异常'];
+        }
+        /** @var WorkOrder $workOrder */
+        $workOrder = WorkOrder::query()->find($request->input('id'));
+        if (!$workOrder) {
+            return ['success' => false, 'message' => '未找到对应的工单'];
+        }
+        $column = $request->input('column');
+        $workOrder->update(["{$column}" => $request->input('value') ?? null]);
+        return ['success' => true];
+    }
+
+    public function updateUserOwnerGroupApi(Request $request): array
+    {
+        if (Gate::denies('订单管理-工单处理-宝时编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        if (!$request->has(['id', 'user_owner_group_id'])) {
+            return ['success' => false, 'message' => '参数异常'];
+        }
+        /** @var WorkOrder $workOrder */
+        $workOrder = WorkOrder::query()->find($request->input('id'));
+        if (!$workOrder) {
+            return ['success' => false, 'message' => '未找到对应的工单'];
+        }
+        $workOrder->update(['user_owner_group_id' => $request->input('user_owner_group_id')]);
+        return ['success' => true];
+    }
+
+    public function storeUserWorkGroupApi(Request $request): array
+    {
+        if (Gate::denies('订单管理-工单处理-宝时编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        if (!$request->has(['id', 'user_workgroup_id'])) {
+            return ['success' => false, 'message' => '参数异常'];
+        }
+        /** @var WorkOrder $workOrder */
+        $workOrder = WorkOrder::query()->find($request->input('id'));
+        if (!$workOrder) {
+            return ['success' => false, 'message' => '未找到对应的工单'];
+        }
+        $hasExists = $workOrder->userWorkGroups()->where('user_workgroup_id', $request->input('user_workgroup_id'))->exists();
+        if ($hasExists) return ['success' => false, 'message' => '已有对应的关系'];
+        $workOrder->userWorkGroups()->attach($request->input('user_workgroup_id'));
+        return ['success' => true, 'data' => $workOrder->userWorkGroups];
+    }
+
+    public function destroyUserWorkGroupApi(Request $request): array
+    {
+        if (Gate::denies('订单管理-工单处理-宝时编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        if (!$request->has(['id', 'user_workgroup_id'])) {
+            return ['success' => false, 'message' => '参数异常'];
+        }
+        /** @var WorkOrder $workOrder */
+        $workOrder = WorkOrder::query()->find($request->input('id'));
+        if (!$workOrder) {
+            return ['success' => false, 'message' => '未找到对应的工单'];
+        }
+        $workOrder->userWorkGroups()->detach($request->input('user_workgroup_id'));
+        return ['success' => true];
+    }
+
+    public function exportJsonExcel(Request $request, WorkOrderFilters $filters)
+    {
+        $work_orders = WorkOrder::query()->filter($filters)->defaultWith()->get();
+        return $this->exportJson($work_orders);
+    }
+
+    public function exportJson($workOrders)
+    {
+        $json = [];
+        $row = [
+            '工单类型', '当前进度', '客户', '店铺名称', '客户订单号', '快递单号', '创建时间', '当前处理人', '创建人', '情况说明', '退回单号', '退回商品', '退回商品名称', '退回商品数量', '是否正品', '操作类型', '操作人', '内容'
+        ];
+        $workOrders->each(function ($item) use (&$json) {
+            $logistic_numbers = $item->order->packages->implode('logistic_number', ",\r\n");
+            $logistic_numbers_return = $item->orderIssueRejectedBills->implode('logistic_number_return',",\r\n");
+            $rejected_item_name = '';
+            $rejected_item_sku = '';
+            $rejected_item_label = '';
+            $rejected_item_amount = '';
+            $item->orderIssueRejectedBills->each(function ($item) use (&$rejected_item_name, &$rejected_item_sku, &$rejected_item_label, &$rejected_item_amount) {
+                if($item->rejectedBill)
+                    $item->rejectedBill->items->each(function ($item) use (&$rejected_item_name, &$rejected_item_sku, &$rejected_item_label, &$rejected_item_amount) {
+                        $rejected_item_name = $rejected_item_name . $item->name_goods . ",\r\n";
+                        $rejected_item_sku = $rejected_item_sku . $item->barcode_goods . ",\r\n";
+                        $rejected_item_label = $rejected_item_label . $item->quality_label . ",\r\n";
+                        $rejected_item_amount = $rejected_item_amount . $item->amount . ",\r\n";
+                    });
+            });
+            $work_order_process_logs_type = '';
+            $work_order_process_logs_user = '';
+            $work_order_process_logs = '';
+
+            $work_order_details = $item->details->filter(function ($detail) use ($item) {
+                return $detail->order_issue_type_id == $item->order_issue_type_id;
+            });
+            if(count($work_order_details) > 0){
+                $work_order_details->first()->processLogs->each(function ($log) use (&$work_order_process_logs_type,&$work_order_process_logs_user,&$work_order_process_logs) {
+                    $work_order_process_logs_type .= $log->type. ",\r\n";
+                    $work_order_process_logs_user .= ($log->user->name ?? ''). ",\r\n";
+                    $work_order_process_logs .= $log->content. ",\r\n";
+                });
+            }
+
+            $json[] = [
+                $item->issueType->name ?? '',
+                $item->process_progress,
+                $item->owner->name ?? '',
+                $item->order->shop->name ?? '',
+                $item->order->client_code ?? '',
+                rtrim($logistic_numbers, ",\r\n"),
+                isset($item->created_at) ? str_split($item->created_at, 10)[0] : '',
+                $item->status,
+                $item->creator->name ?? '',
+                $item->remark,
+                rtrim($logistic_numbers_return, ",\r\n"),
+                rtrim($rejected_item_sku, ",\r\n"),
+                rtrim($rejected_item_name, ",\r\n"),
+                rtrim($rejected_item_amount, ",\r\n"),
+                rtrim($rejected_item_label, ",\r\n"),
+                rtrim($work_order_process_logs_type, ",\r\n"),
+                rtrim($work_order_process_logs_user, ",\r\n"),
+                rtrim($work_order_process_logs, ",\r\n"),
+            ];
+        });
+        return Export::make($row, $json, "工单");
+    }
 }

+ 31 - 1
app/Http/Controllers/api/thirdPart/weixin/ProcurementController.php

@@ -214,7 +214,37 @@ class ProcurementController extends Controller
     public function updateProcurementDeliveryAmount(Request $request): \Illuminate\Http\JsonResponse
     {
         $param=$request->all(['id','delivernum']);
-        $procurementDelivery=ProcurementDeliverie::query()->where('id',$param['id'])->update(['amount'=>$param['delivernum']]);
+        $procurementDelivery=ProcurementDeliverie::query()->where('id',$param['id'])->first();
+        if (!$procurementDelivery){
+            response()->json(['status'=>0,'message' => '未指定送货单','data'=>null], 401);
+        }
+        $procurement_id=$procurementDelivery->procurement_id;
+        $procurement=Procurement::query()->find($procurement_id);
+        $initial_amount=$procurementDelivery->amount;
+
+        if ($procurement){
+            if ($param['delivernum']>$procurement->quantity){
+                response()->json(['status'=>0,'message' => '送货数量大于采购数量','data'=>null], 401);
+            }
+            if ($param['delivernum']==0){
+                response()->json(['status'=>0,'message' => '送货数量不能为零','data'=>null], 401);
+            }
+            if ($procurement->status==5 && (int)$initial_amount!=(int)$param['delivernum']){
+                $procurementDelivery->update(['amount'=>$param['delivernum']]);
+                $procurementDeliver=new ProcurementDeliverie();
+                $procurementDeliver['procurement_id']=$procurement->id;
+                $procurementDeliver['amount']=((int)$initial_amount-(int)$param['delivernum']);
+                $procurementDeliver['initiator']=Auth::user()['id'];
+                $procurementDeliver['signer']=$procurement->initiator ?? 0;
+                $procurementDeliver['created_at']=Carbon::now()->toDateTimeString();
+                $procurementDeliver['updated_at']=Carbon::now()->toDateTimeString();
+                $procurementDeliver->save();
+                ProcurementCheckSheet::query()->create(['procurement_delivery_id'=>$procurementDeliver->id,'account_payable'=>$procurementDeliver->receipt_amount*$procurement->cost_price,'auditor'=>0]);
+            }else{
+                $procurementDelivery=ProcurementDeliverie::query()->where('id',$param['id'])->update(['amount'=>$param['delivernum']]);
+            }
+        }
+
         if ($procurementDelivery)return $this->success($procurementDelivery);
     }
 

+ 1 - 1
app/RejectedBill.php

@@ -166,7 +166,7 @@ class RejectedBill extends Model
         $order_issue_rejected_bill = OrderIssueRejectedBill::query()->select('logistic_number_return')
             ->where('logistic_number_return',$this->logistic_number_return)->first();
         if ($order_issue_rejected_bill){
-            $order_issue_rejected_bill->delete();
+            OrderIssueRejectedBill::query()->where('logistic_number_return',$this->logistic_number_return)->delete();
             SyncOrderRejectingStatusJob::dispatch($this);
         }
         return parent::delete();

+ 36 - 0
app/Services/DeliveryAppointmentService.php

@@ -12,6 +12,7 @@ use App\Warehouse;
 use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
 use phpDocumentor\Reflection\Types\Integer;
 
 class DeliveryAppointmentService
@@ -229,4 +230,39 @@ class DeliveryAppointmentService
             ->where("appointment_date",date("Y-m-d"))
             ->where("asn_number",'like',"%{$asn}%")->first();
     }
+
+    /**
+     * 是否为送货禁止日期
+     */
+    public function isBanOnDeliveryDate($date):bool
+    {
+        if (!$date || strlen($date)<10){
+            return false;
+        }
+        $date = substr($date,0,10);
+        $list = Cache::get(DeliveryAppointment::BAN,[]);
+        foreach ($list as $index=>$val){
+            if ($date==$val){
+                return true;
+            }
+            if (strtotime($date." 00:00:00") > strtotime($val." 00:00:00")){
+                unset($list[$index]);
+            }
+        }
+        Cache::forever(DeliveryAppointment::BAN,array_values($list));
+        return false;
+    }
+
+    /**
+     * 添加送货禁止日期
+     *
+     * @param $date
+     * @return bool
+     */
+    public function addBanOnDeliveryDate($date):bool
+    {
+        $list = Cache::get(DeliveryAppointment::BAN,[]);
+        array_push($list,$date);
+        return Cache::forever(DeliveryAppointment::BAN,$list);
+    }
 }

+ 1 - 1
app/Services/LogisticService.php

@@ -129,7 +129,7 @@ class LogisticService implements UserFilter
         $query = Logistic::query()->select("id");
         if (!app("UserService")->checkAdminIdentity($userId)){
             $query->whereHas("users",function ($query)use($userId){
-                $query->where("id",$userId);
+                $query->where("users.id",$userId);
             });
         }
         return $query;

+ 9 - 4
app/Services/OrderRejectingStatusService.php

@@ -29,16 +29,21 @@ class OrderRejectingStatusService
         $rejecting_status = $this->getOrderRejectingStatus($order);
         $query = OrderDetail::query()->where('order_id', $order->id);
         $order_detail = $query->first();
+        $is_new_rejecting = in_array($rejecting_status,['无','未退回']) ? '无':'有';
         if (!$order_detail) {
-            OrderDetail::query()->create(
-                ['order_id' => $order->id, 'is_new_rejecting' =>$rejecting_status === '无' ? '无' : '有', 'rejecting_status' => $rejecting_status ]
-            );
+            try {
+                OrderDetail::query()->create(
+                    ['order_id' => $order->id, 'is_new_rejecting' => $is_new_rejecting, 'rejecting_status' => $rejecting_status]
+                );
+            } catch (\Exception $e) {
+                LogService::log(__CLASS__,__METHOD__,$e->getMessage());
+            }
             return;
         }
         if (in_array($order_detail->is_new_rejecting, ['有', '已处理']) && $rejecting_status != '无') {
             $query->update(['rejecting_status' => $rejecting_status]);
         } else {
-            $query->update(['rejecting_status' => $rejecting_status, 'is_new_rejecting' =>$rejecting_status === '无' ? '无' : '有']);
+            $query->update(['rejecting_status' => $rejecting_status, 'is_new_rejecting' =>$is_new_rejecting]);
         }
     }
 

+ 1 - 0
app/Services/OwnerBillReportService.php

@@ -20,6 +20,7 @@ class OwnerBillReportService
      */
     private function query(Builder $builder, array $params)
     {
+        $builder->whereIn("owner_id",app("OwnerService")->getQuery());
         $columnQueryRules = [
             'counting_month_start' => ['alias' => 'counting_month', 'startDate' => '-01'],
             'counting_month_end' => ['alias' => 'counting_month', 'endDate' => '-31'],

+ 1 - 0
app/Services/OwnerFeeDetailService.php

@@ -19,6 +19,7 @@ class OwnerFeeDetailService
      */
     private function query(Builder $builder, array $params)
     {
+        $builder->whereIn("owner_id",app("OwnerService")->getQuery());
         $columnQueryRules = [
             'worked_at_start' => ['alias' => 'worked_at', 'startDate' => ''],
             'worked_at_end' => ['alias' => 'worked_at', 'endDate' => ''],

+ 10 - 2
app/Services/RejectedService.php

@@ -8,6 +8,7 @@ use App\OracleDOCOrderHeader;
 use App\OrderIssue;
 use App\RejectedBill;
 use App\Services\common\QueryService;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use App\Traits\ServiceAppAop;
@@ -28,11 +29,18 @@ class RejectedService
     }
     private function  conditionQuery(array $param)
     {
-        $owners = Auth::user() ? (app('UserService')->getPermittingOwnerIds(Auth::user()) ?? []) : [];
+        $owners =  app("OwnerService")->getQuery()->select("id")->pluck("id")->toArray();
+        if (count($owners)==0){
+            $owners[] = [''];
+        }
         $rejectedBills = RejectedBill::query()->with('user','owner', 'logistic', 'items.quality',
             'items.packageImages','items.commodityImages','items.uploadFiles','orderIssueRejectedBill:logistic_number_return')
             ->orderBy('rejected_bills.id', 'desc')
-            ->whereIn('rejected_bills.id_owner', $owners);
+            ->where(function ($query)use ($owners){
+                /** @var Builder $query */
+                $query->whereIn('rejected_bills.id_owner', $owners)
+                    ->orWhereIn("rejected_bills.id_logistic_return",app("LogisticService")->getQuery());
+            });
         if (array_search("397",$owners)!==false){
             $rejectedBills->with(["items.barcode.commodity"=>function($query){
                 $query->where("owner_id",397)->select("id","sku");

+ 1 - 1
app/Services/StorageService.php

@@ -311,7 +311,7 @@ SQL;
             $sum += (int)$task->fmqty;
             if ((int)$task->fmqty>$amount)$maxIndex = $i;
         }
-        if ($sum<$amount)return []; //上架数大于入库数
+            if ($sum<$amount)return []; //上架数大于入库数
         $result = $this->getMatch($nums,$amount);
         if (!$result)return $this->splitTask($tasks,$maxIndex,$amount);
         $arr = [];

+ 105 - 0
app/Services/WorkOrderCommoditiesService.php

@@ -2,9 +2,14 @@
 
 namespace App\Services;
 
+use App\OrderPackage;
+use App\OrderPackageCommodities;
+use App\RejectedBill;
+use App\RejectedBillItem;
 use App\Traits\ServiceAppAop;
 use App\WorkOrderCommodities;
 use App\WorkOrderDetail;
+use Illuminate\Support\Facades\DB;
 
 class WorkOrderCommoditiesService
 {
@@ -106,4 +111,104 @@ class WorkOrderCommoditiesService
     {
         $detail->commodities()->update(['tag' => 1]);
     }
+
+    public function getOrderCommoditiesEqualWorkOrderDetailCommoditiesMap(WorkOrderDetail $workOrderDetail): array
+    {
+        $query = OrderPackage::query()->select('id')->where('order_id', $workOrderDetail->workOrder->order_id);
+        $order_commodities = OrderPackageCommodities::query()->with('commodity.barcodes')->whereIn('order_package_id', $query)->get();
+        $query = DB::table('order_issue_rejected_bill')->select('logistic_number_return')->where('order_id', $workOrderDetail->workOrder->order_id);
+        $query = RejectedBill::query()->select('id')->whereIn('logistic_number_return',$query->get()->map(function ($item){
+            return $item->logistic_number_return;
+        })->toArray());
+        $rejected_items = RejectedBillItem::query()->with('barcode','quality')->whereIn('id_rejected_bill',$query)->get();
+        return $this->getEqualMapByRejectedBillAndWorkOrderCommodity($order_commodities,$rejected_items);
+    }
+
+    private function getEqualMapByRejectedBillAndWorkOrderCommodity($order_commodities,$rejectedBillItems): array
+    {
+        $rejected_bill_items_map = $this->getRejectedBillItemMap($rejectedBillItems);
+        $order_commodities_map = $this->getOrderCommoditiesMap($order_commodities,$rejected_bill_items_map);
+        return $this->getEqualMap($order_commodities_map,$rejected_bill_items_map);
+    }
+
+    public function getRejectedBillItemMap($rejectedBillItems): array
+    {
+        $map = [];
+        $rejectedBillItems->each(function($item)use(&$map){
+            $key = $item->barcode_goods;
+            $quality_label = $item->quality_label;
+            if(!array_key_exists($key,$map)){
+                $map[$key] = [
+                    'sku' => $key,
+                    'quality_label' => [
+                        "${quality_label}"=> [
+                            "quality_label" => $quality_label, "amount" => $item->amount,
+                        ],
+                    ],
+                    'name' => $item->name_goods,
+                ];
+            }
+            if(!array_key_exists($quality_label,$map[$key]['quality_label'])){
+                $map[$key]['quality_label'][$quality_label]['amount'] = 0;
+                $map[$key]['quality_label'][$quality_label]['quality_label'] = $quality_label;
+            }
+            $map[$key]['quality_label'][$quality_label]['amount'] += $item->amount;
+        });
+        return $map;
+    }
+
+    public function getOrderCommoditiesMap($orderCommodities,$rejectedBillMap): array
+    {
+        $map = [];
+        if (!$orderCommodities) return $map;
+        $barcodes = array_keys($rejectedBillMap);
+        foreach ($orderCommodities as $order_commodity) {
+            $commodity_barcodes = $order_commodity->commodity->barcodes->map(function($item){
+                return $item->code;
+            })->toArray();
+            $key = $order_commodity->commodity->sku;
+            if($commodity_barcodes){
+                $codes = array_intersect($barcodes,$commodity_barcodes);
+                $key = array_shift($codes);
+            }
+            if (!array_key_exists($key,$map)){
+                $map[$key] = [
+                    'sku' => $key,
+                    'amount' => 0,
+                    'name' => $order_commodity->commodity->name,
+                ];
+                $map[$key]['amount'] += (int) $order_commodity->amount;
+            }
+        }
+        return $map;
+    }
+
+    public function getEqualMap($orderCommodityMap,$rejectedBillMap): array
+    {
+        $map = [];
+        foreach ($orderCommodityMap as $key=>$item){
+            $map[$key] = [
+                'order_commodity_sku' => $key,
+                'order_commodity_name' => $item['name'],
+                'order_commodity_amount' => $item['amount'],
+                'rejected_item_sku' => isset($rejectedBillMap[$key]) ? $key : '',
+                'rejected_item_quality_label' => $rejectedBillMap[$key]['quality_label'] ?? [],
+                'rejected_item_name' => $rejectedBillMap[$key]['name'] ?? '',
+            ];
+        }
+        foreach ($rejectedBillMap as $key=>$item){
+            if(!array_key_exists($key,$orderCommodityMap)){
+                $map[$key] = [
+                    'order_commodity_sku' => isset($orderCommodityMap[$key])  ? $key : '',
+                    'order_commodity_name' => $orderCommodityMap['name'] ?? null,
+                    'order_commodity_amount' => $orderCommodityMap['amount'] ?? null,
+                    'rejected_item_sku' => $key,
+                    'rejected_item_quality_label' => $item['quality_label'] ?? [],
+                    'rejected_item_name' => $item['name'] ?? '',
+                ];
+            }
+        }
+        return $map;
+    }
+
 }

+ 5 - 0
app/Services/WorkOrderExpressAbnormalService.php

@@ -194,4 +194,9 @@ class WorkOrderExpressAbnormalService extends WorkOrderService
         $this->logService->createLog($detail, '终审', $process_progress . '-宝时终审');
     }
 
+    public function autoReview(WorkOrderDetail $detail, $process_progress,$endContext = null)
+    {
+
+    }
+
 }

+ 37 - 9
app/Services/WorkOrderInformationChangeService.php

@@ -144,6 +144,12 @@ class WorkOrderInformationChangeService extends WorkOrderService
             'type' => '处理',
         ]);
         $this->logService->createLog($detail, '处理', '承运商处理-'.$process_progress);
+
+        if($process_progress == '已签收'){
+            $this->autoReview($detail,'更改成功','更改成功-自动终审');
+//            $this->logService->createLog($detail, '完结', '承运商更改成功,自动终审');
+//            $this->review($detail,'更改成功','更改成功-自动终审');
+        }
     }
 
     /**
@@ -166,6 +172,29 @@ class WorkOrderInformationChangeService extends WorkOrderService
     public function baoShiReview(WorkOrderDetail $detail, $params)
     {
         $process_progress = $params['process_progress'];
+        $this->review($detail, $process_progress);
+        $this->logService->createLog($detail, '终审', '宝时终审-' . $process_progress);
+    }
+
+    /**
+     * 宝时批量终审
+     * @param $details
+     * @param $params
+     */
+    public function baoShiBatchReview($details, $params)
+    {
+        foreach ($details as $detail) {
+            $this->baoShiReview($detail, $params);
+        }
+    }
+
+    /**
+     * @param WorkOrderDetail $detail
+     * @param $process_progress
+     * @param null $endContext
+     */
+    public function review(WorkOrderDetail $detail, $process_progress,$endContext = null): void
+    {
         $detail->update([
             'status' => WorkOrder::$TO_BO_OWNER_END_STATUS,
             'process_progress' => $process_progress,
@@ -185,23 +214,22 @@ class WorkOrderInformationChangeService extends WorkOrderService
             'work_order_id' => $detail->work_order_id,
             'work_order_detail_id' => $detail->id,
             'user_id' => Auth::id(),
-            'content' => $process_progress.'-完结',
+            'content' => $endContext ?? $process_progress . '-完结',
             'status' => '未同步',
             'type' => '结束',
         ]);
         $this->endOrderIssueAndSyncProcessLogs($detail);
-        $this->logService->createLog($detail, '终审', '宝时终审-' . $process_progress);
     }
 
     /**
-     * 宝时批量终审
-     * @param $details
-     * @param $params
+     * 自动终审
+     * @param WorkOrderDetail $detail
+     * @param $process_progress
+     * @param null $endContext
      */
-    public function baoShiBatchReview($details, $params)
+    public function autoReview(WorkOrderDetail $detail, $process_progress,$endContext = null)
     {
-        foreach ($details as $detail) {
-            $this->baoShiReview($detail, $params);
-        }
+        $this->logService->createLog($detail, '完结', '承运商更改成功,自动终审');
+        $this->review($detail, $process_progress,$endContext );
     }
 }

+ 41 - 27
app/Services/WorkOrderInterceptService.php

@@ -148,6 +148,10 @@ class WorkOrderInterceptService extends WorkOrderService
             'type' => '处理',
         ]);
         $this->logService->createLog($detail, '处理', '承运商处理-' . $process_progress);
+        if( $process_progress == '拦截失败'){
+            $this->logService->createLog($detail, '终审', '承运商无法拦截,自动终审-无法拦截');
+            $this->review($detail,'无法拦截','无法拦截-自动完结');
+        }
     }
 
     /**
@@ -170,33 +174,7 @@ class WorkOrderInterceptService extends WorkOrderService
     public function baoShiReviewIntercept(WorkOrderDetail $detail, $params)
     {
         $process_progress = $params['process_progress'];
-        $detail->update([
-            'status' => WorkOrder::$TO_BO_OWNER_END_STATUS,
-            'process_progress' => $process_progress,
-            'last_status' => WorkOrder::$BAO_SHI_REVIEW_STATUS,
-            'logistic_handle_tag' => 0,
-        ]);
-        $detail->workOrder()->update([
-            'status' => WorkOrder::$TO_BO_OWNER_END_STATUS,
-            'process_progress' => $process_progress,
-            'last_status' => WorkOrder::$BAO_SHI_REVIEW_STATUS,
-            'owner_tag' => WorkOrder::$STRAND_TAG,
-            'logistic_tag' => WorkOrder::$DEFAULT_TAG,
-            'bao_shi_tag' => WorkOrder::$DEFAULT_TAG,
-            'work_order_status' => 0,
-            'last_handler_id' => Auth::id(),
-        ]);
-
-        $detail->processLogs()->create([
-            'work_order_id' => $detail->work_order_id,
-            'work_order_detail_id' => $detail->id,
-            'user_id' => Auth::id(),
-            'content' => $process_progress.'-拦截工单',
-            'status' => '未同步',
-            'type' => '结束',
-        ]);
-
-        $this->endOrderIssueAndSyncProcessLogs($detail);
+        $this->review($detail, $process_progress);
         $this->logService->createLog($detail, '终审', '宝时终审-' . $process_progress);
     }
 
@@ -252,4 +230,40 @@ class WorkOrderInterceptService extends WorkOrderService
         $this->logService->createLog($detail, '终审', '自动终审-' . $process_progress);
     }
 
+    /**
+     * @param WorkOrderDetail $detail
+     * @param $process_progress
+     * @param null $endContext
+     */
+    public function review(WorkOrderDetail $detail, $process_progress,$endContext = null): void
+    {
+        $detail->update([
+            'status' => WorkOrder::$TO_BO_OWNER_END_STATUS,
+            'process_progress' => $process_progress,
+            'last_status' => WorkOrder::$BAO_SHI_REVIEW_STATUS,
+            'logistic_handle_tag' => 0,
+        ]);
+        $detail->workOrder()->update([
+            'status' => WorkOrder::$TO_BO_OWNER_END_STATUS,
+            'process_progress' => $process_progress,
+            'last_status' => WorkOrder::$BAO_SHI_REVIEW_STATUS,
+            'owner_tag' => WorkOrder::$STRAND_TAG,
+            'logistic_tag' => WorkOrder::$DEFAULT_TAG,
+            'bao_shi_tag' => WorkOrder::$DEFAULT_TAG,
+            'work_order_status' => 0,
+            'last_handler_id' => Auth::id(),
+        ]);
+
+        $detail->processLogs()->create([
+            'work_order_id' => $detail->work_order_id,
+            'work_order_detail_id' => $detail->id,
+            'user_id' => Auth::id(),
+            'content' => $endContext ?? $process_progress . '-拦截工单',
+            'status' => '未同步',
+            'type' => '结束',
+        ]);
+
+        $this->endOrderIssueAndSyncProcessLogs($detail);
+    }
+
 }

+ 1 - 1
app/Services/WorkOrderMistakeService.php

@@ -32,7 +32,7 @@ class WorkOrderMistakeService extends WorkOrderService
 
     public function checkWorkOrder($nos)
     {
-        $issueType = $this->issueTypeService->firstOrCreate(['name' => '信息更改']);
+        $issueType = $this->issueTypeService->firstOrCreate(['name' => '错漏发']);
         $orderQuery = Order::query()->select('id')->where('code', $nos);
         $workOrder = WorkOrder::query()->select('id')->whereIn('order_id', $orderQuery)->first();
         if (!$workOrder) return false;

+ 17 - 0
app/Services/WorkOrderService.php

@@ -372,6 +372,23 @@ class WorkOrderService
                 'order_issue_type_id' => $detail->order_issue_type_id,
             ]);
         }
+
+        $order_issue->update([
+            'logistic_indemnity_money' => $work_order->logistic_indemnity_money,
+            'logistic_express_remission' => $work_order->logistic_express_remission,
+            'baoshi_indemnity_money' => $work_order->bao_shi_indemnity_money,
+            'baoshi_express_remission' => $work_order->bao_shi_express_remission,
+            'user_owner_group_id' => $work_order->user_owner_group_id,
+        ]);
+
+        $work_order_user_workgroup_ids = $work_order->userWorkGroups()->get()->map(function($item){
+            return $item->id;
+        })->toArray();
+
+        $order_issue_work_groups = $order_issue->userWorkgroups()->get()->map(function($item){
+            return $item->id;
+        } )->toArray();
+        $order_issue->userWorkgroups()->attach(array_diff($work_order_user_workgroup_ids,$order_issue_work_groups));
         $process_logs = $detail->processLogs()->where('status', '未同步')->get();
         $order_issue->logs()->insert($process_logs->map((function ($process_log) use ($order_issue) {
             return [

+ 38 - 8
app/WorkOrder.php

@@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
 
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Database\Eloquent\SoftDeletes;
 use Illuminate\Support\Facades\Auth;
@@ -28,6 +29,7 @@ class WorkOrder extends Model
         'reviewer_id',              // 审核人
         'last_handler_id',          // 上一个处理人
         'order_issue_type_id',      // 问题件类型
+        'work_order_detail_id',     // 详情
         'process_progress',         // 处理进度 -----------------------------------
         // 拦截:       承运商->[已处理,已签收]         宝时审核->[`无法拦截`,`成功已退回,不赔偿`,`拦截在途丢件,赔偿`]
         // 信息更改:    承运商->[已处理,无法更改]       宝时审核->[更改成功,更改失败]
@@ -48,35 +50,47 @@ class WorkOrder extends Model
         "is_new_rejecting",         // 回库标记
         'created_at',
         'rejecting_status',         // 退回状态
+
+        'logistic_indemnity_money',     // 承运商赔偿金额
+        'logistic_express_remission',   // 承运商减免
+        'bao_shi_indemnity_money',      // 宝时赔偿金额
+        'bao_shi_express_remission',    // 宝时减免
+        'user_owner_group_id',
     ];
     /**
      * @var int 默认
      */
-    public static $DEFAULT_STATUS = 0;              //
+    public static $DEFAULT_STATUS = 0;
     /**
      * @var int  宝时处理
      */
-    public static $BAO_SHI_HANDLER_STATUS = 1;      //  宝时处理
+    public static $BAO_SHI_HANDLER_STATUS = 1;
+
     /**
      * @var int 货主处理
      */
-    public static $OWNER_HANDLER_STATUS = 2;        //  货主处理
+    public static $OWNER_HANDLER_STATUS = 2;
+
     /**
      * @var int 承运商处理
      */
-    public static $LOGISTIC_HANDLER_STATUS = 3;     //  承运商处理
+    public static $LOGISTIC_HANDLER_STATUS = 3;
+
     /**
      * @var int 宝时终审
      */
-    public static $BAO_SHI_REVIEW_STATUS = 4;       //  宝时终审
+    public static $BAO_SHI_REVIEW_STATUS = 4;
+
     /**
      * @var int 完成
      */
-    public static $END_STATUS = 5;                  //  完成
+    public static $END_STATUS = 5;
+
     /**
      * @var int 待货主完结
      */
-    public static $TO_BO_OWNER_END_STATUS = 6;      //  待货主完结
+    public static $TO_BO_OWNER_END_STATUS = 6;
+
 
     /**
      * @var int `新`标记
@@ -234,6 +248,21 @@ class WorkOrder extends Model
         return $this->belongsTo(OrderDetail::class,'order_id','order_id');
     }
 
+    public function userWorkGroups(): BelongsToMany
+    {
+        return $this->belongsToMany(UserWorkgroup::class,'work_order_user_workgroup');
+    }
+
+    public function userOwnerGroup(): BelongsTo
+    {
+        return $this->BelongsTo(UserOwnerGroup::class);
+    }
+
+    public function detail(): BelongsTo
+    {
+        return $this->belongsTo(WorkOrderDetail::class,'work_order_detail_id','id');
+    }
+
     public function scopeFilter($query, $filters)
     {
         return $filters->apply($query);
@@ -252,7 +281,8 @@ class WorkOrder extends Model
 
     public function defaultWith(): array
     {
-        return ['owner', 'logistic', 'issueType', 'creator', 'lastHandler','orderDetail','orderIssueRejectedBills', 'details' => function ($query) {
+        return ['owner', 'logistic', 'issueType', 'creator', 'lastHandler','orderDetail','orderIssueRejectedBills.rejectedBill.items',
+            'userWorkGroups','details' => function ($query) {
             return $query->with(['commodities.commodity', 'logs' => function ($query) {
                 return $query->with('creator')->orderByDesc('created_at');
             }, 'images.uploadFile', 'issueType', 'processLogs' => function ($query) {

+ 15 - 4
app/WorkOrderDetail.php

@@ -3,10 +3,11 @@
 namespace App;
 
 use App\Traits\ModelTimeFormat;
-use Illuminate\Database\Eloquent\Model;
-
 use App\Traits\ModelLogChanging;
+
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Support\Facades\Auth;
 
@@ -21,7 +22,7 @@ class WorkOrderDetail extends Model
         'price',                    // 商品价值
         'sku_amount',               // 破损sku数
         'type',                     // 快递异常填写:在途异常,签收未收到
-        'last_handler_id',             // 上一个处理人
+        'last_handler_id',          // 上一个处理人
         'reissue_logistic_number',  // 补发单号
         'return_logistic_number',   // 退回单号 (错漏发:商家填写) (破损:创建时填写)
         'process_progress',         // 处理进度
@@ -33,8 +34,8 @@ class WorkOrderDetail extends Model
         'return_address',           // 退回单 寄件人地址
         'return_phone',             // 退回单 寄件人联系号码
         'return_name',              // 退回单 寄件人姓名
-
         'logistic_handle_tag',      // 承运商在处理标记
+
     ];
 
     static public $enums = [
@@ -198,6 +199,16 @@ class WorkOrderDetail extends Model
         return $this->hasMany(WorkOrderProcessLog::class,'work_order_detail_id','id');
     }
 
+    public function userOwnerGroup(): BelongsTo
+    {
+        return $this->belongsTo(UserOwnerGroup::class);
+    }
+
+    public function userWorkgroups(): BelongsToMany
+    {
+        return $this->belongsToMany(UserWorkgroup::class);
+    }
+
     // 未完成历史标记
     public function undoneTag()
     {

+ 1 - 1
config/users.php

@@ -1,7 +1,7 @@
 <?php
 
 return [
-    'superAdmin' => ['xuxiaodong','ldaaww','baoshi56','周亚萍','shiyao','zhouzhendong','zengjun',"yang",'huhao','zy','刘媛媛','李家磊',env('SUPER_ADMIN',"")],
+    'superAdmin' => ['xuxiaodong','ldaaww','baoshi56','徐薇','周亚萍','shiyao','zhouzhendong','zengjun',"yang",'huhao','zy','刘媛媛','李家磊',env('SUPER_ADMIN',"")],
     'token_expire_minutes'=>7200,
     'token_check_in_expire_minutes'=>432000, //打卡过期时间,单位为秒
     'cookie_expire_minutes'=>7200,//cookie过期时间,单位分钟

+ 41 - 0
database/migrations/2022_01_19_172151_work_order_details_add_indemnity_money.php

@@ -0,0 +1,41 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class WorkOrderDetailsAddIndemnityMoney extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->decimal('logistic_indemnity_money')->index()->nullable()->comment('承运商赔偿金额');
+            $table->enum('logistic_express_remission', ['原单减免', '补发减免', '全部减免'])->index()->nullable()->comment('承运商快递减免');
+            $table->decimal('bao_shi_indemnity_money')->index()->nullable()->comment('宝时赔偿金额');
+            $table->enum('bao_shi_express_remission', ['原单减免', '补发减免', '全部减免'])->index()->nullable()->comment('宝时快递减免');
+            $table->integer('user_owner_group_id')->index()->nullable()->comment('项目责任方');
+        });
+
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->dropColumn('logistic_indemnity_money');
+            $table->dropColumn('logistic_express_remission');
+            $table->dropColumn('bao_shi_indemnity_money');
+            $table->dropColumn('bao_shi_express_remission');
+            $table->dropColumn('user_owner_group_id');
+        });
+    }
+}

+ 32 - 0
database/migrations/2022_01_21_111254_work_orders_add_work_order_detail_id.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class WorkOrdersAddWorkOrderDetailId extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->bigInteger('work_order_detail_id')->index()->comment('当前工单详情');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->dropColumn('work_order_detail_id');
+        });
+    }
+}

+ 32 - 0
database/migrations/2022_01_21_132626_create_work_order_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 CreateWorkOrderUserWorkgroupTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('work_order_user_workgroup', function (Blueprint $table) {
+            $table->bigInteger('work_order_id')->comment('工单');
+            $table->bigInteger('user_workgroup_id')->comment('仓库组');
+            $table->unique(['work_order_id','user_workgroup_id']);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('work_order_user_workgroup');
+    }
+}

+ 2 - 2
resources/views/equipment/_detailInfo.blade.php

@@ -1,6 +1,6 @@
-<div class="modal fade" id="detailInfo" tabindex="-1" role="dialog" data-keyboard="false" aria-hidden="true"
+<div class="modal fade" id="detailInfo" tabindex="-1" role="dialog" data-keyboard="false" style="z-index: 1042" aria-hidden="true"
      :data-backdrop="current.eqId ? 'true' : 'static'" >
-    <div class="modal-dialog modal-lg modal-dialog-centered" role="document">
+    <div class="modal-dialog modal-lg modal-dialog-centered" role="document" style="z-index: 1043">
         <div class="modal-content">
             <div class="modal-header row m-0">
                 <div class="col-4 form-inline h-5 font-weight-bold">

+ 21 - 0
resources/views/equipment/_failTipList.blade.php

@@ -0,0 +1,21 @@
+<div class="modal fade" id="failTipList" style="z-index: 1044" tabindex="1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog modal-lg modal-dialog-centered" role="document" style="z-index: 1045">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h1 class="offset-4 text-muted">部分构建失败原因</h1>
+                <button type="button" class="close" data-dismiss="modal">&times;</button>
+            </div>
+            <div class="modal-body p-0">
+                <table class="table table-bordered w-100 overflow-y-scrollbar-200" style="max-height: 400px !important;">
+                    <tr v-for="(val,key) in failTipList">
+                        <td class="text-dark font-weight-bold text-center">@{{ key }}</td>
+                        <td class="text-danger">@{{ val }}</td>
+                    </tr>
+                </table>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">了解了</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 76 - 24
resources/views/equipment/_location.blade.php

@@ -1,8 +1,8 @@
-<div class="modal fade" id="locationModal" v-if="currentEqChildIndex!==null" tabindex="1" role="dialog" aria-hidden="true">
-    <div class="modal-dialog modal-lg modal-dialog-centered" role="document">
+<div class="modal fade" id="locationModal" v-if="currentEqChildIndex!==null" style="z-index: 1044" tabindex="1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog modal-lg modal-dialog-centered" role="document" style="z-index: 1045">
         <div class="modal-content">
             <div class="modal-header">
-                <h1 class="offset-5">@{{ current.code+'-'+((currentEqChildIndex+1)<10 ? '0'+(currentEqChildIndex+1) : (currentEqChildIndex+1)) }}</h1>
+                <h1 class="offset-5" v-if="!batchSign">@{{ current.code+'-'+((currentEqChildIndex+1)<10 ? '0'+(currentEqChildIndex+1) : (currentEqChildIndex+1)) }}</h1>
                 <button type="button" class="close" data-dismiss="modal">&times;</button>
             </div>
             <div class="modal-body p-0">
@@ -11,43 +11,95 @@
                 </div>
                 <div class="w-100" v-else>
                     <table class="table table-bordered w-100 h-100 m-0"
-                        v-if="current.children[currentEqChildIndex].row>0 && current.children[currentEqChildIndex].column>0">
+                        v-if="!batchSign && (current.children && current.children[currentEqChildIndex] && current.children[currentEqChildIndex].row>0 && current.children[currentEqChildIndex].column>0)">
                         <tr v-for="row in current.children[currentEqChildIndex].row">
                             <td v-for="column in current.children[currentEqChildIndex].column" v-if="locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)]"
                                 class="p-0 text-center position-relative">
-                                <div style="border: 2px darkgray solid;" class="el-center w-100 h-100 text-secondary font-weight-bold"
-                                :style="locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code|childStyle">
-                                    @{{ locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code }}</div>
-                                <div style="position: absolute;bottom: 0" class="w-100 row">
-                                    <div class="col-5 offset-1">
-                                        <h6 class="text-muted">在库数量:</h6><b>@{{ locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code | qty }}</b>
-                                    </div>
-                                    <div class="col-5">
-                                        <h6 class="text-muted">待操作数量:</h6><b>@{{ locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code | qtyOver }}</b>
+                                <div style="min-height: 120px">
+                                    <div class="w-100 h-100 text-secondary font-weight-bold"
+                                         :style="locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code|childStyle">
+                                        @{{ locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code }}</div>
+                                    <div style="position: absolute;bottom: 0" class="w-100 row">
+                                        <div class="col-5 offset-1">
+                                            <h6 class="text-muted">在库数量:</h6><b>@{{ locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code | qty }}</b>
+                                        </div>
+                                        <div class="col-5">
+                                            <h6 class="text-muted">待动数量:</h6><b>@{{ locations[(row-1)*current.children[currentEqChildIndex].column+(column-1)].code | qtyOver }}</b>
+                                        </div>
                                     </div>
                                 </div>
                             </td>
                         </tr>
                     </table>
-                    <div class="w-100 mt-5 row" v-else>
-                        <div class="input-group m-3 col-5">
-                            <input type="number" step="1" class="form-control" placeholder="构建行数" v-model="buildPool.row">
-                            <div class="input-group-append">
-                                <span class="input-group-text">行</span>
+                    <div class="w-100 mt-3" v-else>
+                        <div class="row">
+                            <div class="input-group m-3 col-5">
+                                <input type="number" step="1" class="form-control" placeholder="构建行数" v-model="buildPool.row">
+                                <div class="input-group-append">
+                                    <span class="input-group-text">行</span>
+                                </div>
+                            </div>
+                            <div class="col-1 mt-4 h5 font-weight-bold">×</div>
+                            <div class="input-group m-3 col-5">
+                                <input type="number" step="1" class="form-control" placeholder="构建列数" v-model="buildPool.column">
+                                <div class="input-group-append">
+                                    <span class="input-group-text">列</span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="row mt-5">
+                            <label class="offset-1 col-4 text-right" for="usage">用途</label>
+                            <select class="col-5 form-control" id="usage" v-model="buildPool.usage">
+                                <option v-for="(msg,key) in locationAttr.usage" :value="key">@{{ key+'('+msg+')' }}</option>
+                            </select>
+                        </div>
+                        <div class="row mt-3">
+                            <label class="offset-1 col-4 text-right" for="handling">处理方式</label>
+                            <select class="col-5 form-control" id="handling" v-model="buildPool.handling">
+                                <option v-for="(msg,key) in locationAttr.handling" :value="key">@{{ key+'('+msg+')' }}</option>
+                            </select>
+                        </div>
+                        <div class="row mt-3">
+                            <label class="offset-1 col-4 text-right" for="attribute">属性</label>
+                            <select class="col-5 form-control" id="attribute" v-model="buildPool.attribute">
+                                <option v-for="(msg,key) in locationAttr.attribute" :value="key">@{{ key+'('+msg+')' }}</option>
+                            </select>
+                        </div>
+                        <div class="row mt-3">
+                            <label class="offset-1 col-4 text-right" for="category">类别</label>
+                            <select class="col-5 form-control" id="category" v-model="buildPool.category">
+                                <option v-for="(msg,key) in locationAttr.category" :value="key">@{{ key+'('+msg+')' }}</option>
+                            </select>
+                        </div>
+                        <div class="row mt-3">
+                            <label class="offset-1 col-4 text-right" for="demand">需求</label>
+                            <select class="col-5 form-control" id="demand" v-model="buildPool.demand">
+                                <option v-for="(msg,key) in locationAttr.demand" :value="key">@{{ key+'('+msg+')' }}</option>
+                            </select>
+                        </div>
+                        <div class="row mt-3">
+                            <label class="offset-1 col-4 text-right" for="mixFlag">是否允许产品混放</label>
+                            <div class="col-5">
+                                <input class="switch" type="checkbox" id="mixFlag" v-model="buildPool.mixFlag" />
+                            </div>
+                        </div>
+                        <div class="row mt-3">
+                            <label class="offset-1 col-4 text-right" for="mixLotFlag">是否允许批次混放</label>
+                            <div class="col-5">
+                                <input class="switch" type="checkbox" id="mixLotFlag" v-model="buildPool.mixLotFlag" />
                             </div>
                         </div>
-                        <div class="col-1 mt-4 h5 font-weight-bold">×</div>
-                        <div class="input-group m-3 col-5">
-                            <input type="number" step="1" class="form-control" placeholder="构建列数" v-model="buildPool.column">
-                            <div class="input-group-append">
-                                <span class="input-group-text">列</span>
+                        <div class="row mt-3">
+                            <label class="offset-1 col-4 text-right" for="loseIdFlag">上架后是否释放跟踪号</label>
+                            <div class="col-5">
+                                <input class="switch" type="checkbox" id="loseIdFlag" v-model="buildPool.loseIdFlag" />
                             </div>
                         </div>
                     </div>
                 </div>
             </div>
             <div class="modal-footer">
-                <button v-if="current.children[currentEqChildIndex].row>0 && current.children[currentEqChildIndex].column>0" @click="removeLocationBind()"
+                <button v-if="!batchSign && (current.children && current.children[currentEqChildIndex] && current.children[currentEqChildIndex].row>0 && current.children[currentEqChildIndex].column>0)" @click="removeLocationBind()"
                         class="pull-right btn btn-danger">解除该设备库位绑定</button>
                 <button v-else @click="locationBind()" class="pull-right btn btn-success">根据行列自动构建库位</button>
             </div>

+ 38 - 0
resources/views/equipment/_locationAttr.blade.php

@@ -0,0 +1,38 @@
+<div class="modal fade" id="locationAttr" tabindex="-1" aria-labelledby="modalTitle" style="z-index: 1042" role="dialog" aria-hidden="true">
+    <div class="modal-dialog modal-lg modal-dialog-centered" style="z-index: 1043">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="modalTitle">批量生成库位</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body container-fluid row p-0">
+                <div class="col-md-6" style="border-right: 1px #D3D3D3 solid">
+                    <div class="row p-2 m-0 cursor-pointer" style="border-top: 1px solid #dee2e6;"
+                         v-for="(arr,idx) in batchEquipment" :class="idx==batchEquipmentSign ? 'box-shadow-dark' : ''"
+                         @click="batchEquipmentSelected(arr,idx)">
+                        <div class="col-md-5">
+                            <div style="border: 1px #0070C0 solid" :style="[{backgroundColor:equipments[idx].color},{width:(equipments[idx].h*ratio)+'px'},{height:(equipments[idx].w*ratio)+'px'}]"></div>
+                        </div>
+                        <div class="col-md-5 text-overflow-replace">
+                            @{{ equipments[idx].describe }}
+                        </div>
+                        <div class="col-md-2" @click="showEquipmentCode(arr)">
+                            @{{ arr.length }}组
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-6" v-if="current.eqId">
+                    <div v-for="layer in flipLayer" style="border: 1px #000000 solid;height: 70px;cursor: pointer" @click="nextDetailBatch(layer)"
+                         :style="[layer===1 ? {borderTop:'none'} : '',layer===current.layer ? {borderBottom:'none'} : '',{width:100*(current.grid)+'px'}]">
+                        <span class="h-100 w-100 el-center">@{{ layer<10 ? '0'+layer : layer }}</span>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 245 - 16
resources/views/equipment/index.blade.php

@@ -59,10 +59,18 @@
         #loading p{position:absolute;top:55%;left:48%;width:33px;height:33px;margin-top:-15px;margin-left:-15px;}
 
         .equipment{
+            cursor: pointer
+        }
+        .equipment-exist{
+            border-width:2px;
+            border-style: groove;
+            border-color: #0000FF;
+        }
+        .equipment-not-exist{
+            opacity: 0.5;
             border-width:1px;
-            border-color: #0070C0;
             border-style: dashed;
-            cursor: pointer
+            border-color: #0070C0;
         }
     </style>
 </head>
@@ -87,6 +95,7 @@
                 </ul>
             </div>
             <button class="btn btn-info mt-5 w-100 text-white" @click="openRepository()">新增库区</button>
+            <button class="btn btn-success mt-5 w-100 text-white" @click="searchingSelectEq()">批量构建库位</button>
             <p class="font-weight-bold p-0 mb-0 mt-1">位置</p>
             <div class="row text-muted small">
                 <small class="col-6">X</small>
@@ -180,6 +189,12 @@
                     </div>
                 </div>
             </div>
+            <div class="row text-muted mt-1">
+                <div class="col-4">库位比</div>
+                <div class="input-group input-group-sm col-8 m-0">
+                    <input class="switch" type="checkbox" @change="loadElement()"/>
+                </div>
+            </div>
             <div class="row mt-3">
                 <h5 class="font-weight-bold ml-3">设备</h5>
                 <div class="form-check ml-3">
@@ -230,16 +245,29 @@
                     </vue-drag-resize>
                     <vue-drag-resize class="equipment"
                                      v-for="(element,index) in equipmentElements" @clicked="showDetail(element)"
-                                     :id="'eq-'+index"
+                                     :id="'eq-'+index" :class="element.exist ? 'equipment-exist' : 'equipment-not-exist'"
                                      v-if="!element.removeSign"
                                      :is-resizable="false" :snap-to-grid="grid" :grid-x="40" :grid-y="30"
                                      :style="[{backgroundColor:element.color}]"
                                      @activated="onActivated(element)"
                                      @dragging="equipmentDrag"
                                      :key="'eq-'+index+element.turn" :prevent-active-behavior="isNotEdit"
-                                     :parent-limitation="true" :w="(element.turn ? element.w : element.h)*ratio" :h="(element.turn ? element.h : element.w)*ratio"
+                                     :parent-limitation="true" :w="(element.turn ? element.w : element.h)*ratio"
+                                     :h="(element.turn ? element.h : element.w)*ratio"
                                      :x="element.x" :y="element.y" :z="90">
-                        <div class="h-100 txt-sty w-100 el-center" :class="element.turn ? 're' : ''">@{{ element.code }}</div>
+                        <div class="h-100 w-100" v-if="isShowRatio">
+                            <div class="h-100 w-100 p-0" v-if="element.children && element.children.length>0">
+                                <div :style="{height:100/element.children.length+'%'}" v-for="(child,idx) in element.children"
+                                     :class="(element.children[element.children.length-1-idx]).location_tab==='0-0' ? '' : 'bg-danger'"
+                                     class="border border-dark text-dark small el-center w-100 m-0">
+                                    @{{ (element.children[element.children.length-1-idx]).location_tab | formatCount }}
+                                </div>
+                            </div>
+                            <div class="h-100 w-100 txt-sty el-center" v-else>
+                                <i class="fa fa-spinner fa-spin"></i>
+                            </div>
+                        </div>
+                        <div class="h-100 txt-sty w-100 el-center" :class="element.turn ? 're' : ''" v-else>@{{ element.code }}</div>
                     </vue-drag-resize>
                 </div>
             </div>
@@ -255,6 +283,8 @@
     @include("equipment._warehouseDetail")
     @include("equipment._repository")
     @include("equipment._buildGroup")
+    @include("equipment._locationAttr")
+    @include("equipment._failTipList")
 </div>
 </body>
 <script src="{{ mix('js/app.js') }}"></script>
@@ -324,6 +354,14 @@
             elSeList:[
                 {id:-1,w:1.2,h:2.4,grid:2,color:"RGB(255,255,0)",describe:"消防栓设施或立柱,不可设库位"},
             ],//场景元素预设列表
+            locationAttr:null,//库位建立时的可选择属性
+            batchEquipment:{
+
+            },//设备类型 与设备下标的映射
+            batchEquipmentSign:"",//当前选择的batchEquipment下标
+            batchSign:false,//当前是否为批量构建
+            failTipList:{},//构建失败的库位提示信息
+            isShowRatio:undefined,//是否展示库位现存比例
         },
         mounted() {
             this.initPage();
@@ -373,6 +411,54 @@
             };
         },
         methods:{
+            loadElement(){
+                if (this.isShowRatio===undefined){
+                    this.isShowRatio = true;
+                    this.equipmentElements.forEach(eq=>{
+                        if (eq.exist){
+                            this.getChildren(eq);
+                        }else if(!eq.children){
+                            eq.children = [];
+                        }
+                    });
+                }else{
+                    this.isShowRatio = !this.isShowRatio;
+                }
+            },
+            //获取库位的可选择属性
+            _getLocationAttr(){
+                if (this.locationAttr!==null){
+                    return;
+                }
+                $.ajax({
+                    url : this.baseUrl+"location/getAttr",
+                    type : "post",
+                    dataType : "JSON",
+                    success : (res,status)=>{
+                        if (res.code===200){
+                            this.locationAttr = res.data;
+                        }else{
+                            window.toast.error(res.message);
+                        }
+                    },
+                    error : (err,status)=>{
+                        window.toast.error("库位选择属性加载失败");
+                    },
+                    timeout:3000,
+                })
+            },
+            /**
+             * 显示设备编码列表
+             */
+            showEquipmentCode(arr){
+                event.stopPropagation();
+                let obj = {};
+                arr.forEach(index=>{
+                    obj[this.equipmentElements[index].code] = "";
+                });
+                this.failTipList = obj;
+                $("#failTipList").modal("show");
+            },
             //检索所有元素,获取在指定范围内的元素
             searchingSelectEq(){
                 afterExt = function (){
@@ -392,13 +478,43 @@
                         }
                         resolve(result);
                     }).then(indexArr=>{
-                        indexArr.forEach(index=>{
-                            console.log(vue.equipmentElements[index].code);
-                        });
+                        if (indexArr.length===0){
+                            toast.error("未选中任何设备");
+                            return;
+                        }
+                        vue.batchOperationEquipment(indexArr);
                     });
                 }
                 clipScreenshots();
             },
+            /**
+             * 批量选中设备后唤起构建器
+             */
+            batchOperationEquipment(indexArr){
+                this.current = {};
+                let obj = {};
+                indexArr.forEach(index=>{
+                    let eq = this.equipmentElements[index];
+                    let eqTypeIndex = this._getEqTypeIndex(eq.id);
+                    if (!obj[eqTypeIndex])obj[eqTypeIndex] = [];
+                    obj[eqTypeIndex].push(index);
+                });
+                this.batchEquipment = obj;
+                $("#locationAttr").modal('show');
+            },
+            /**
+             * 根据库位类型ID获取库位类型下标
+             */
+            _getEqTypeIndex(id){
+                //当前是ID为下标+1,所以直接ID-1获取下标
+                return id-1;
+                for (let i=0;i<this.equipments.length;i++){
+                    if (this.equipments[i].id==id){
+                        return i;
+                    }
+                }
+                return null;
+            },
             buildComponent(eq){
                 let component = {
                     "x":eq.x,"y":eq.y,"width":eq.turn ? eq.w : eq.h,"height":eq.turn ? eq.h : eq.w,"name":"","color":eq.color,
@@ -767,6 +883,7 @@
                                     let selfInfo = this.equipments[coords.id-1];
                                     equipmentElements.push(Object.assign({
                                         eqId:eq.id,
+                                        exist:eq.exist,
                                         code:eq.code,
                                         width:eq.width,
                                         depth:eq.depth,
@@ -798,15 +915,55 @@
                 let val = event.target.value;
                 this.currentEl[key] = val ? parseFloat(val) : 0;
             },
+            _getObjFirstKey(obj){
+                for(let key in obj){
+                    return key;
+                }
+                return null;
+            },
+            /**
+             * 构建库位的默认值信息
+             * */
+            _locationAttrDefault(){
+                this.buildPool.usage = this._getObjFirstKey(this.locationAttr.usage);
+                this.buildPool.handling = this._getObjFirstKey(this.locationAttr.handling);
+                this.buildPool.attribute = this._getObjFirstKey(this.locationAttr.attribute);
+                this.buildPool.category = this._getObjFirstKey(this.locationAttr.category);
+                this.buildPool.demand = this._getObjFirstKey(this.locationAttr.demand);
+                this.buildPool.mixFlag = true;
+                this.buildPool.mixLotFlag = false;
+                this.buildPool.loseIdFlag = true;
+            },
+            /**
+             * 批量构建库位时的操作
+             * */
+            nextDetailBatch(index){
+                if (!this.current.children || this.current.children.length===0){
+                    window.toast.error("设备信息尚未加载完毕,请稍后重试!");
+                    return;
+                }
+                this.batchSign = true;
+                this.currentEqChildIndex = index-1;
+                setTimeout(function (){
+                    let parentDom = document.getElementById("locationAttr").firstChild.firstChild;
+                    let childDom = document.getElementById("locationModal").firstChild.firstChild;
+                    childDom.style.minWidth = parentDom.offsetWidth+'px';
+                    childDom.style.minHeight = parentDom.offsetHeight+'px';
+                    $("#locationModal").modal("show");
+                },20);
+                this._locationAttrDefault();
+            },
             //子设备选定时的库位加载
             nextDetail(index){
                 if (!this.current.eqId)return;
+                this.batchSign = false;
                 this.currentEqChildIndex = index-1;
                 this.isLoadLocation = true;
+                this._locationAttrDefault();
                 setTimeout(function (){
                     let parentDom = document.getElementById("detailInfo").firstChild.firstChild;
                     let childDom = document.getElementById("locationModal").firstChild.firstChild;
-                    childDom.style.minWidth = parentDom.offsetWidth+'px';
+                    childDom.style.minWidth = (parentDom.offsetWidth+200)+'px';
                     childDom.style.minHeight = parentDom.offsetHeight+'px';
                     $("#locationModal").modal("show");
                 },20);
@@ -820,13 +977,8 @@
                         switch (res.code){
                             case 200:
                                 this.locations = res.data[0];
-                                this.locationMapping = res.data[1];
+                                this.locationMapping = res.data[1] ? res.data[1] : {};
                                 this.isLoadLocation = false;
-                                setTimeout(()=>{
-                                    let parentDom = document.getElementById("detailInfo").firstChild.firstChild;
-                                    let childDom = document.getElementById("locationModal").firstChild.firstChild;
-                                    childDom.children[1].firstChild.style.height = parentDom.children[1].offsetHeight+'px';
-                                },10);
                                 break;
                             default:
                                 window.toast.error(res.message);
@@ -840,6 +992,7 @@
                 })
             },
             showDetail(equipment){
+                this._getLocationAttr();
                 if (!this.isNotEdit)return;
                 this.current = equipment;
                 setTimeout(()=>{
@@ -849,6 +1002,9 @@
                 this.getChildren(this.current);
             },
             getChildren(equipment){
+                if (equipment.children && equipment.children.length>0){
+                    return;
+                }
                 $.ajax({
                     url : this.baseUrl+"equipment/getChildren",
                     type : "post",
@@ -975,7 +1131,64 @@
                     timeout:3000,
                 })
             },
+            locationBatchBind(){
+                $("#loading").show();
+                let arr = this.batchEquipment[this.batchEquipmentSign];
+                let request = [];
+                let failTipList = {};
+                arr.forEach(index=>{
+                    let eq = this.equipmentElements[index];
+                    if (!eq){
+                        window.toast.error("异常设备选择");
+                    }else if (!eq.children || eq.children.length===0 || !eq.children[this.currentEqChildIndex]){
+                        failTipList[eq.code]="详情尚未加载完毕";
+                    }else{
+                        let item = eq.children[this.currentEqChildIndex];
+                        let code = eq.code+'-'+((this.currentEqChildIndex+1)<10 ? '0'+(this.currentEqChildIndex+1) : (this.currentEqChildIndex+1));
+                        request.push(Object.assign({id:item.id,code:code},
+                            this.buildPool))
+                    }
+                });
+                $.ajax({
+                    url : this.baseUrl+"location/locationBatchBound",
+                    type : "post",
+                    dataType : "JSON",
+                    data : JSON.stringify(request),
+                    headers:{'Content-Type':'application/json;charset=utf8'},
+                    success : (res)=>{
+                        switch (res.code){
+                            case 200:
+                                $("#locationModal").modal('hide');
+                                window.toast.success("构建完毕!");
+                                this.failTipList = Object.assign(failTipList,res.data);
+                                if (JSON.stringify(this.failTipList)!=="{}"){
+                                    $("#failTipList").modal("show");
+                                }
+                                let ele = document.querySelectorAll("#locationAttr span.el-center")[this.current.layer-1-this.currentEqChildIndex];
+                                ele.className += " bg-success";
+                                break;
+                            default:
+                                window.toast.error(res.message);
+                        }
+                    },
+                    error : (err)=>{
+                        window.tempTip.setIndex(999);
+                        window.tempTip.show("网络错误");
+                    },
+                    complete:(req,status)=>{
+                        $("#loading").hide();
+                        if (status==='timeout'){
+                            window.toast.error("库位批量构建失败,响应超时");
+                        }
+                    },
+                    timeout:3000,
+                });
+            },
             locationBind(){
+                if (this.batchSign){
+                    this.locationBatchBind();
+                    return;
+                }
                 if (this.isLoadLocation)return;
                 let eq = this.current.children[this.currentEqChildIndex];
                 let code = this.current.code+'-'+((this.currentEqChildIndex+1)<10 ? '0'+(this.currentEqChildIndex+1) : (this.currentEqChildIndex+1));
@@ -984,7 +1197,8 @@
                     url : this.baseUrl+"location/locationBind",
                     type : "post",
                     dataType : "JSON",
-                    data : {id:eq.id,row:this.buildPool.row,column:this.buildPool.column,code:code},
+                    headers:{'Content-Type':'application/json;charset=utf8'},
+                    data : JSON.stringify(Object.assign({id:eq.id,code:code},this.buildPool)),
                     success : (res)=>{
                         switch (res.code){
                             case 200:
@@ -1129,6 +1343,17 @@
                     timeout:3000,
                 })
             },
+            /**
+             * 批量构建设备库位时的选中操作
+             * */
+            batchEquipmentSelected(arr,index){
+                this.current = this.equipmentElements[arr[0]];
+                this.batchEquipmentSign = index;
+                arr.forEach(i=>{
+                    this.getChildren(this.equipmentElements[i]);
+                })
+                this._getLocationAttr();
+            },
         },
         filters:{
             qty(code){
@@ -1149,6 +1374,10 @@
                 return (qty>0 || other>0) ?
                     'color: #fff;background-color: #38c172;border-color: #38c172;' : '';
             },
+            formatCount(tab){
+                let arr = tab.split("-");
+                return arr[0]*arr[1];
+            }
         }
     });
 </script>

+ 1 - 1
resources/views/order/issue/index.blade.php

@@ -6,6 +6,7 @@
         <div style="@cannot('订单管理-问题件-客户不可见')min-width: 3000px;@else min-width: 1990px; @endcannot">
             <div id="list" class="d-none container-fluid">
                 <div id="form_div" style="min-width: 2250px;"></div>
+
                 <div class="form-inline mt-1" id="btn">
                     <span class="dropdown">
                         <button type="button"
@@ -918,7 +919,6 @@
                                         </td>
                                     </tr>
                                 </table>
-
                             </td>
                             <td>
                                 @can('订单管理-问题件-编辑')

+ 50 - 45
resources/views/order/workOrder/_issue_logs.blade.php

@@ -7,7 +7,6 @@
                     @click="showAddDiv('AddLog_'+item.order_issue.id)">新
             </button>
         </div>
-
         <div class="addLogDiv row m-0 p-0 form-group" style="display: none;"
              :id="'AddLog_'+item.order_issue.id">
             <input type="hidden" name="id" :value="item.order_issue.id">
@@ -26,56 +25,62 @@
                 <button type="button"
                         class="btn btn-primary ml-2 m-0 p-0"
                         style="width: 50px"
-                        @click="orderIssueVue.addOrderIssueLog('AddLog_'+item.order_issue.id,item.order_issue.id,item.issue_logs)">添加
+                        @click="orderIssueVue.addOrderIssueLog('AddLog_'+item.order_issue.id,item.order_issue.id,item.issue_logs)">
+                    添加
                 </button>
             </div>
         </div>
 
     @endcan
-    <template class="p-0 m-0" v-if="item.issue_logs && item.issue_logs.length > 0">
-        <table class="table table-sm p-0 m-0 " :id="'logs'+item.order_issue.id">
-            <tr class="align-center position-static"
-                v-for="(log,logIndex) in item.issue_logs"
-                @click="removeFocusing($event)" v-on:mouseover="showDelBtn($event)"
-                v-on:mouseleave="hideDelBtn($event)">
-                <template v-if="logIndex < 2|| item.order_issue.log_is_show === true">
-                    <td style="max-width: 175px;min-width: 175px;">
-                        <span v-text="log.content"></span>
-                    </td>
-                    <td class="text-muted" style="max-width: 55px;min-width: 55px;">
-                        <span v-if="log.user" v-text="log.user.name"></span>
-                    </td>
-                    <td class="text-muted" style="max-width: 95px;min-width: 95px;">
-                        <span v-text="log.created_at"></span>
-                    </td>
-                    @can('订单管理-问题件-处理结果删除')
-                        <td style="max-width: 35px;min-width: 35px;" class="m-0 p-0 border-0">
-                            <button type="button"
-                                    class="btn btn-sm btn-outline-danger m-0 del-btn invisible"
-                                    @click="orderIssueVue.destroyLog(log,item.issue_logs,logIndex)">
-                                删
-                            </button>
-                        </td>
-                        <td class="m-0 p-0 border-0">
-                            <button type="button"
-                                    class="btn btn-sm btn-outline-primary m-0 del-btn invisible"
-                                    v-show="Number(log.tag) !== 1"
-                                    @click="orderIssueVue.tagIssueLog(log)">标
-                            </button>
-                        </td>
-                    @endcan
-                </template>
-            </tr>
-        </table>
-        <div class="d-flex justify-content-center">
-            <button type="button" class="btn btn-sm btn-outline-primary align-middle mt-1 center-block"
-                    v-if="item.issue_logs.length > 2"
-                    @click="toggleLogs(item.order_issue,$event)">记录共@{{ item.issue_logs.length }}条,点击展开
-            </button>
-        </div>
+    <table class="table table-sm p-0 m-0 " :id="'logs'+item.order_issue.id"
+           v-if="item.issue_logs && item.issue_logs.length > 0">
+        <tr class="align-center position-static"
+            v-for="(log,logIndex) in item.issue_logs"
+            v-on:mouseover="showDelBtn($event)"
+            v-on:mouseleave="hideDelBtn($event)"
+            @click="removeFocusing($event)"
+            v-show=" showOrderIssueProcessLog===item.id || logIndex < 2 "
+        >
+            <td style="max-width: 175px;min-width: 175px;">
+                <span v-text="log.content"></span>
+            </td>
+            <td class="text-muted" style="max-width: 55px;min-width: 55px;">
+                <span v-if="log.user" v-text="log.user.name"></span>
+            </td>
+            <td class="text-muted" style="max-width: 95px;min-width: 95px;">
+                <span v-text="log.created_at"></span>
+            </td>
+            @can('订单管理-问题件-处理结果删除')
+                <td style="max-width: 35px;min-width: 35px;" class="m-0 p-0 border-0">
+                    <button type="button"
+                            class="btn btn-sm btn-outline-danger m-0 del-btn invisible"
+                            @click="orderIssueVue.destroyLog(log,item.issue_logs,logIndex)">
+                        删
+                    </button>
+                </td>
+                <td class="m-0 p-0 border-0">
+                    <button type="button"
+                            class="btn btn-sm btn-outline-primary m-0 del-btn invisible"
+                            v-show="Number(log.tag) !== 1"
+                            @click="orderIssueVue.tagIssueLog(log)">标
+                    </button>
+                </td>
+            @endcan
+        </tr>
+    </table>
+    <div v-if="item.issue_logs.length === 0" class="w-auto h-50">
+    </div>
+    <div class="d-flex justify-content-center">
+        <button type="button" class="btn btn-sm btn-outline-primary align-middle mt-1 center-block"
+                v-show="showOrderIssueProcessLog !== item.id"
+                @click="showOrderIssueProcessLog = item.id">记录共@{{ item.issue_logs.length }}条,点击展开
+        </button>
+        <button type="button" class="btn btn-sm btn-outline-primary align-middle mt-1 center-block"
+                v-show="showOrderIssueProcessLog === item.id"
+                @click="showOrderIssueProcessLog = null">点击收起
+        </button>
 
-    </template>
-    <div v-else class="w-auto h-50">
     </div>
+
 </div>
 

+ 1 - 1
resources/views/order/workOrder/_order_commodity_info.blade.php

@@ -3,7 +3,7 @@
         商品详情
     </div>
     <el-table
-        :key="order_info_commodityes_key"
+        :key="order_info_commodities_key"
         :data="orderInfo.commodities"
         row-key="order_commodities_id"
         border

+ 32 - 26
resources/views/order/workOrder/_process_logs.blade.php

@@ -1,5 +1,7 @@
 <div>
-    @can('订单管理-工单处理-承运商编辑')
+    @if( \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-宝时编辑') ||
+            \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-商家编辑') ||
+             \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-承运商编辑'))
     <div class="add-btn"
          style="position: absolute;display: none;margin-top: -35px;z-index: 51"
          :id="'AddProcessLogBtn'+item.pending_detail.id">
@@ -24,40 +26,44 @@
             </button>
         </div>
     </div>
-    @endcan
+    @endif
     <template class="p-0 m-0" v-if="item.process_logs.length > 0">
         <table class="table table-sm p-0 m-0 " :id="'logs'+item.pending_detail.id">
             <tr class="align-center position-static"
                 v-for="(log,logIndex) in item.process_logs"
-                @click="removeFocusing($event)" v-on:mouseover="showDelBtn($event)"
-                v-on:mouseleave="hideDelBtn($event)">
-                <template v-if="logIndex < 2|| item.log_is_show === true">
-                    <td style="max-width: 175px;min-width: 175px;">
-                        <span v-text="log.content"></span>
-                    </td>
-                    <td class="text-muted" style="max-width: 55px;min-width: 55px;">
-                        <span v-if="log.user" v-text="log.user.name"></span>
-                    </td>
-                    <td class="text-muted" style="max-width: 95px;min-width: 95px;">
-                        <span v-text="log.created_at"></span>
-                    </td>
-                    @can('订单管理-工单处理-承运商编辑')
-                    <td style="max-width: 35px;min-width: 35px;" class="m-0 p-0 border-0">
-                        <button type="button"
-                                class="btn btn-sm btn-outline-danger m-0 del-btn invisible"
-                                @click="destroyProcessLog(item,log,logIndex)">
-                            
-                        </button>
-                    </td>
-                    @endcan
-                </template>
+                v-on:mouseover="showDelBtn($event)"
+                v-on:mouseleave="hideDelBtn($event)"
+                @click="removeFocusing($event)"
+                v-show="showWorkOrderProcessLog === item.id || logIndex<2">
+                <td style="max-width: 175px;min-width: 175px;">
+                    <span v-text="log.content"></span>
+                </td>
+                <td class="text-muted" style="max-width: 55px;min-width: 55px;">
+                    <span v-if="log.user" v-text="log.user.name"></span>
+                </td>
+                <td class="text-muted" style="max-width: 150px;min-width: 150px;">
+                    <span v-text="log.created_at"></span>
+                </td>
+                @if( \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-宝时编辑') || \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-商家编辑') )
+                <td style="max-width: 35px;min-width: 35px;" class="m-0 p-0 border-0">
+                    <button type="button"
+                            class="btn btn-sm btn-outline-danger m-0 del-btn invisible"
+                            @click="destroyProcessLog(item,log,logIndex)">
+                        
+                    </button>
+                </td>
+                @endif
             </tr>
         </table>
         <div class="d-flex justify-content-center">
             <button type="button" class="btn btn-sm btn-outline-primary align-middle mt-1 center-block"
-                    v-if="item.process_logs.length > 2"
-                    @click="toggleWorkOrderLogs(item,$event)"
+                    v-if="item.process_logs.length > 2 && showWorkOrderProcessLog !== item.id"
+                    @click="showWorkOrderProcessLog = item.id"
                     v-text="'记录共'+item.process_logs.length +'条,点击展开'"></button>
+
+            <button type="button" class="btn btn-sm btn-outline-primary align-middle mt-1 center-block"
+                    v-show="showWorkOrderProcessLog === item.id"
+                    @click="showWorkOrderProcessLog = null">点击收起</button>
         </div>
 
     </template>

+ 40 - 0
resources/views/order/workOrder/_rejected_item_equals_order_commodity.blade.php

@@ -0,0 +1,40 @@
+<el-dialog :visible.sync="dialogCommoditiesEqualsVisible" width="75%">
+    <table class="table table-bordered table-sm">
+        <tr class="text-center">
+           <th colspan="3" class="bg-light-info" style="width: 600px">
+               订单商品信息
+           </th>
+           <th colspan="3" class="bg-light-khaki" style="width: 600px">
+               退回商品信息
+           </th>
+        </tr>
+        <tr>
+            <th class="bg-light-info">商品条码</th>
+            <th class="bg-light-info">商品名</th>
+            <th class="bg-light-info">数量</th>
+            <th class="bg-light-khaki">商品条码</th>
+            <th class="bg-light-khaki">商品名</th>
+            <th class="bg-light-khaki">数量</th>
+        </tr>
+        <tr v-for="item in commodityEqualsMap">
+            <td class="bg-light-info" v-text="item.order_commodity_sku"></td>
+            <td class="bg-light-info" v-text="item.order_commodity_name"></td>
+            <td class="bg-light-info" v-text="item.order_commodity_amount"></td>
+            <td class="bg-light-khaki" v-text="item.rejected_item_sku"></td>
+            <td class="bg-light-khaki" v-text="item.rejected_item_name"></td>
+            <td class="bg-light-khaki">
+                <div v-for="item_quality_label in item.rejected_item_quality_label">
+                    <span class="badge badge-primary"
+                        v-show="item_quality_label.quality_label === '正品'" v-text="'正品数量:' + item_quality_label.amount"></span>
+                    <span class="badge badge-danger"
+                        v-show="item_quality_label.quality_label === '次品'" v-text="'次品数量' + item_quality_label.amount"></span>
+                    <span class="badge badge-secondary"
+                        v-show="item_quality_label.quality_label === '未知'" v-text="'未知数量' + item_quality_label.amount"></span>
+                </div>
+            </td>
+        </tr>
+    </table>
+    <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogCommoditiesEqualsVisible = false">关 闭</el-button>
+    </div>
+</el-dialog>

+ 373 - 66
resources/views/order/workOrder/index.blade.php

@@ -11,6 +11,16 @@
             <div class="">
                 <div id="form_div" style="min-width: 1220px;"></div>
                 <div class="ml-3 form-inline" id="btn">
+                     <span class="dropdown">
+                        <button type="button"
+                                class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget"
+                                data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">导出Excel
+                        </button>
+                        <div class="dropdown-menu">
+                            <a class="dropdown-item" href="javascript:" @click="workOrderExport(false)">导出勾选内容</a>
+                            <a class="dropdown-item" href="javascript:" @click="workOrderExport(true)">导出所有页</a>
+                        </div>
+                    </span>
                     @can('订单管理-订单问题件生成')
                         <button type="button"
                                 class="ml-2 btn  btn-sm btn-outline-dark "
@@ -30,15 +40,17 @@
                                 class="ml-1 btn btn-outline-primary btn-sm"
                                 @click="baoShiBatchHandler">宝时批量处理
                         </button>
+                    @endcan
+                    @if(\Illuminate\Support\Facades\Gate::check('订单管理-工单处理-宝时编辑') || \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-承运商编辑'))
                         <button type="button"
                                 class="ml-1 btn btn-outline-primary btn-sm"
-                                @click="showBatchStoreProcessLogs">批量处理日志
+                                @click="showBatchStoreProcessLogs">工单批量处理日志
                         </button>
-                    @endcan
+                    @endif
                     @can('订单管理-问题件-编辑')
                         <button type="button"
                                 class="ml-1 btn btn-outline-dark btn-sm"
-                                @click="showBatchEditOrderIssueLog">批量处理说明
+                                @click="showBatchEditOrderIssueLog">问题件批量处理日志
                         </button>
                     @endcan
 
@@ -75,11 +87,12 @@
 
                                     <template>
                                         <span class="badge badge-success" v-show="isLogisticHandler(item)">承</span>
-                                        <span v-show="item.order_detail && ['有','已处理'].includes(item.order_detail.is_new_rejecting)"
+                                        <span
+                                            v-show="item.order_detail && ['有','已处理'].includes(item.order_detail.is_new_rejecting)"
                                             class="badge badge-primary">退</span>
                                     </template>
 
-                                    <template >
+                                    <template>
                                         <br v-show="item.is_issue_order">
                                         <a :href="'{{url("order/issue/index")}}'+'?is_handle=ture&orderCode='+item.orderno"
                                            v-show="item.is_issue_order"
@@ -91,7 +104,7 @@
                                     <template v-show="item.order_detail">
                                         <br>
                                         <span class="badge  badge-light"
-                                            v-text="item.order_detail ? item.order_detail.rejecting_status : ''"></span>
+                                              v-text="item.order_detail ? item.order_detail.rejecting_status : ''"></span>
                                     </template>
                                 </td>
                                 <td>
@@ -104,6 +117,10 @@
                                     <button class="btn btn-sm btn-outline-secondary"
                                             @click="showOrderCommoditiesInfo(item)">商品详情
                                     </button>
+                                    <br>
+                                    <button class="btn btn-sm btn-outline-secondary" @click="getEqualsMap(item)">
+                                        商品比较
+                                    </button>
                                 </td>
                                 <td>
                                     @can('订单管理-订单问题件生成')
@@ -194,8 +211,8 @@
                                     <span class="badge  badge-warning" v-if="'快递异常' === item.issue_type_name"
                                           v-text="item.type"></span>
                                 </td>
-                                <td v-text="item.shop_name"></td>
                                 <td v-text="item.owner_name"></td>
+                                <td v-text="item.shop_name"></td>
                                 <td v-text="item.order_client_code"></td>
                                 <td v-text="item.logisitc_name"></td>
                                 <td>
@@ -203,12 +220,11 @@
                                         <span v-text="logistic_number"></span>
                                     </div>
                                 </td>
-
                                 <td v-text="item.created_at"></td>
                                 <td v-text="item.status"></td>
                                 <td v-text="item.creator ? item.creator.name : ''"></td>
                                 <td v-text="item.result_explain ? item.result_explain: item.remark"></td>
-                                <td class="text-muted child-layer-3-hide" >
+                                <td class="text-muted child-layer-3-hide">
                                     <div class="form-inline">
                                         <div class="form-group">
                                             <input type="text" class="form-control form-text form-control-sm mr-1">
@@ -223,18 +239,63 @@
                                              v-for="relation in item.order_issue_rejected_bills">
                                             <input type="text" class="form-control form-control-sm mt-1 mr-1"
                                                    :value="relation.logistic_number_return"
-{{--                                                       @change="reviseJoinRejectedBill(item,orderIssueRejectedBill.logistic_number_return,$event)"--}}
                                                    @focus="displayDelBtn(true,$event)"
                                                    @blur="displayDelBtn(false,$event)">
                                             <button type="button" class="btn btn-sm btn-outline-danger mt-1 d-none"
-                                                    @click="unJoinLogisticNumberReturn(item,relation.logistic_number_return,i)"
-                                            >
+                                                    @click="unJoinLogisticNumberReturn(item,relation.logistic_number_return,i)">
                                             </button>
                                         </div>
                                     </div>
                                 </td>
-
+                                @if( \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-宝时编辑') || \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-商家编辑') )
+                                    <td class="p-0 child-layer-3-hide align-center">
+                                        <div class="m-0 p-0" v-if="item.rejected_bill_items">
+                                            <table class="table table-sm m-0" v-show="showRejectedBillItem === item.id">
+                                                <tr v-for="rejected_bill_item in item.rejected_bill_items">
+                                                    <td class="w-50">
+                                                        <span v-text="rejected_bill_item.barcode_goods"></span>
+                                                    </td>
+                                                    <td>
+                                                        <p class="text-truncate text-primary m-0 p-0 tooltipTarget"
+                                                           style="width: 100px;cursor:pointer;text-decoration: underline"
+                                                           title="双击展开"
+                                                           @dblclick="nowrapText($event)"
+                                                           v-text="rejected_bill_item.name_goods"></p>
+                                                        <p class="text-nowrap m-0 p-0 tooltipTarget"
+                                                           style="display: none;cursor:pointer"
+                                                           title="双击收起"
+                                                           @dblclick="truncateText($event)"
+                                                           v-text="rejected_bill_item.name_goods"></p>
+                                                    </td>
+                                                    <td class="w-25">
+                                                        <span v-text="rejected_bill_item.amount"></span>
+                                                    </td>
+                                                    <td class="w-25">
+                                                        <span v-text="rejected_bill_item.quality_label"></span>
+                                                    </td>
+                                                    <td class="w-auto">
+                                                        <span v-text="rejected_bill_item.remark"></span>
+                                                    </td>
+                                                </tr>
+                                            </table>
+                                            <div class="text-center" v-show="item.rejected_bill_item_amount_count > 0">
+                                                <button type="button"
+                                                        class="btn btn-sm btn-outline-primary align-middle mt-1"
+                                                        v-show="showRejectedBillItem !== item.id"
+                                                        @click="showRejectedBillItem = item.id"
+                                                        v-text="'商品' + item.rejected_bill_item_amount_count + '件,点击展开'">
+                                                </button>
+                                                <button type="button"
+                                                        class="btn btn-sm btn-outline-primary align-middle mt-1"
+                                                        v-show="showRejectedBillItem === item.id"
+                                                        @click="showRejectedBillItem = null">
+                                                    点击收起
+                                                </button>
+                                            </div>
+                                        </div>
+                                    </td>
+                                @endif
                                 <td class="log-td"
                                     v-on:mouseover="showAddBtn($event)"
                                     v-on:mouseleave="hideAddBtn($event)">
@@ -247,10 +308,10 @@
                                         @include('order.workOrder._issue_logs')
                                     </td>
                                 @endcan
-                                <td class="container">
+                                <td class="container" style="min-width: 500px">
                                     <div class="row">
                                         @can('订单管理-工单处理-删除')
-                                            <div class="col-1 ">
+                                            <div class="col-2 ">
                                                 <div class="header-alert">
                                                     <button type="button"
                                                             class="btn btn-sm btn-outline-danger"
@@ -260,16 +321,72 @@
                                                 </div>
                                             </div>
                                         @endcan
-                                        <div class="col-6 m-0 ">
+                                        <div class="col-10 m-0 ">
                                             @include('order.workOrder._work_order_details')
                                         </div>
-                                        <div @can('订单管理-工单处理-删除') class="col-5 m-0"
-                                             @else class="col-6 p-0" @endcan>
-                                            @include('order.workOrder._work_order_log')
-                                        </div>
                                     </div>
-
                                 </td>
+                                @can('订单管理-工单处理-宝时编辑')
+                                    <td>
+                                        <input type="number" class="form-control form-control-sm"
+                                               v-model="item.logistic_indemnity_money"
+                                               @change="changeWorkOrderInfo(item,'logistic_indemnity_money',$event)">
+                                    </td>
+                                    <td>
+                                        <select class="form-control form-control-sm"
+                                                v-model="item.logistic_express_remission"
+                                                @change="changeWorkOrderInfo(item,'logistic_express_remission',$event)">
+                                            <option v-for="type in workOrderRemissionType" :value="type.name"
+                                                    v-text="type.name"></option>
+                                        </select>
+                                    </td>
+                                    <td>
+                                        <input type="number" class="form-control form-control-sm"
+                                               v-model="item.bao_shi_indemnity_money"
+                                               @change="changeWorkOrderInfo(item,'bao_shi_indemnity_money',$event)">
+                                    </td>
+                                    <td>
+                                        <select
+                                            class="form-control form-control-sm"
+                                            v-model="item.bao_shi_express_remission"
+                                            @change="changeWorkOrderInfo(item,'bao_shi_express_remission',$event)">
+                                            <option v-for="type in workOrderRemissionType" :value="type.name"
+                                                    v-text="type.name"></option>
+                                        </select>
+                                    </td>
+
+                                    <td>
+                                        <table class="table table-sm">
+                                            <tr>
+                                                <td>
+                                                    <select class="form-control form-control-sm"
+                                                            @change="createUserWorkGroup(item,$event)">
+                                                        <option value=""></option>
+                                                        <option v-for="data in userWorkgroup" :value="data.name"
+                                                                v-text="data.value"></option>
+                                                    </select>
+                                                </td>
+                                            </tr>
+                                            <tr v-for="(user_workgroup,index) in item.user_work_groups">
+                                                <td>
+                                                    <span v-text="user_workgroup.name"></span>
+                                                    <button class="btn btn-sm btn-outline-danger float-right" @click="destroyUserWorkGroup(item,index,$event)">删</button>
+                                                </td>
+                                            </tr>
+                                        </table>
+
+
+                                    </td>
+                                    <td>
+                                        <select class="form-control form-control-sm"
+                                                v-model="item.user_owner_group_id"
+                                                @change="changeUserOwnerGroup(item,$event)">
+                                            <option v-for="data in userOwnerGroup" :value="data.name"
+                                                    v-text="data.value"></option>
+                                        </select>
+                                    </td>
+                                @endcan
+                            </tr>
                         </template>
                         </tbody>
                     </table>
@@ -277,9 +394,6 @@
                     {{ $workOrders->withQueryString()->links() }}
                 </div>
             </div>
-            @can('订单管理-工单处理-审核')
-                {{--                @include('order.workOrder._edit_issue_type')--}}
-            @endcan
         </div>
         <div class="row">
             @include('order.workOrder._work_order_show')
@@ -292,6 +406,7 @@
         @include('order.workOrder._edit_order_issue_log')
         @include('order.workOrder._edit_process_log')
         @include('order.workOrder._order_commodity_info')
+        @include('order.workOrder._rejected_item_equals_order_commodity')
     </div>
 @endsection()
 
@@ -299,7 +414,8 @@
     <script type="text/javascript" src="{{asset('js/queryForm/queryForm.js')}}"></script>
     <script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>
     <script type="text/javascript" src="{{mix('js/element-ui.js') }}"></script>
-{{--    <script src="https://unpkg.com/element-ui/lib/index.js"></script>--}}
+    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
 
     <style>
         .fade-enter-active {
@@ -424,6 +540,20 @@
                     },
                     @endforeach
                 ],
+                userWorkgroup: [
+                        @foreach($userWorkgroup as $item)
+                    {
+                        name: '{{$item->id}}', value: '{{$item->name}}'
+                    },
+                    @endforeach
+                ],
+                userOwnerGroup: [
+                        @foreach($userOwnerGroup as $item)
+                    {
+                        name: '{{$item->id}}', value: '{{$item->name}}'
+                    },
+                    @endforeach
+                ],
                 logisticEditWorkOrder: {
                     id: null,
                     issue_type_name: null,
@@ -505,12 +635,16 @@
                 dialogBatchEditOrderIssueLogVisible: false,  // 问题件日志
                 dialogProcessLogVisible: false,              // 工单处理日志
                 dialogOrderCommoditiesVisible: false,              // 订单商品详情
+                dialogCommoditiesEqualsVisible:false,       // 商品对比
 
                 showProcessLogId: null,         // workOrder->id
                 showAddDetailProcessLog: null,        // workOrderDetail->ids
                 showAddProcessLogFrom: null,     //
                 showAddProcessLogBtn: null,
+                showWorkOrderProcessLog: null,
+                showOrderIssueProcessLog: null,
 
+                showRejectedBillItem: null,          // 退回商品详情
                 batchHandlerWorkOrder: {
                     issue_type_name: '',
                     process_progress: '',
@@ -524,7 +658,20 @@
                 orderInfo: {
                     commodities: [],
                 },
-                order_info_commodityes_key: 1,
+                order_info_commodities_key: 101,
+                workOrderRemissionType: [
+                    {name:'原单减免',value:'原单减免'},
+                    {name:'补发减免',value:'补发减免'},
+                    {name:'全部减免',value:'全部减免'},
+                ],
+                rejectingStatus:[
+                    {name:'无',value:'无'},
+                    {name:'未退回',value:'未退回'},
+                    {name:'全部退回',value:'全部退回'},
+                    {name:'部分退回',value:'部分退回'},
+                    {name:'差异退回',value:'差异退回'},
+                    ],
+                commodityEqualsMap:[],
             },
             computed: {},
             mounted() {
@@ -613,6 +760,16 @@
                     },
                     {name: 'is_end', type: 'checkbox', tip: '是否已拦截', data: [{name: 'ture', value: '已完成'}]},
                 ], [
+                    {name: 'logistic_indemnity_money', type: 'input', placeholder: '承运商赔偿金额'},
+                    {name: 'logistic_express_remission', type: 'select', placeholder: '承运商快递减免',data:this.workOrderRemissionType},
+                    {name: 'bao_shi_indemnity_money', type: 'input', placeholder: '宝时赔偿金额'},
+                    {name: 'bao_shi_express_remission', type: 'select', placeholder: '宝时快递减免',data:this.workOrderRemissionType},
+                    {name: 'user_work_group_id', type: 'select_multiple_select',
+                        tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的仓库责任方'],
+                        placeholder: ['仓库责任方', '定位或多选仓库责任方'],data:this.userWorkgroup},
+                    {name: 'user_owner_group_id', type: 'select', placeholder: '项目责任方',data:this.userOwnerGroup},
+                    {name: 'rejecting_status', type: 'select', placeholder: '退回状态',data:this.rejectingStatus},
+                ],[
                     {name: 'order_issue_log', type: 'input', placeholder: '问题件处理日志'},
                     {
                         name: ['log_content', 'addtime'],
@@ -639,6 +796,16 @@
                     },
                     {name: 'shop_name', type: 'input', placeholder: '商铺名'},
                     {name: 'work_order_process_log', type: 'input', placeholder: '工单处理日志'},
+                    {name:"rejectingStatus",type:'select', placeholder: '退单状态',
+                        data:[
+                            {name: '无', value: '无'},
+                            {name: '未退回', value: '未退回'},
+                            {name: '全部退回', value: '全部退回'},
+                            {name: '部分退回', value: '部分退回'},
+                            {name: '差异退回', value: '差异退回'},
+                            {name: '超量退回', value: '超量退回'},
+                        ]
+                    }
                 ]];
                 this.form = new query({
                     el: '#form_div',
@@ -651,9 +818,8 @@
                     {name: 'operation', value: '操作', neglect: true},
                     {name: 'work_type', value: '工单类型', neglect: true},
                     {name: 'process_progress', value: '当前进度', neglect: true},
-
-                    {name: 'shop_name', value: '店铺名称'},
                     {name: 'owner', value: '客户', neglect: true},
+                    {name: 'shop_name', value: '店铺名称'},
                     {name: 'client_no', value: '客户订单号'},
                     {name: 'logistic_name', value: '承运人'},
                     {name: 'logistic_numbers', value: '快递单号'},
@@ -662,28 +828,43 @@
                     {name: 'creator', value: '创建人'},
                     {name: 'remark', value: '情况说明'},
                     {name: 'return_logistic_number', value: '退回单号'},
-                    {name: 'process_logs', value: '处理日志'},
+                        @if( \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-宝时编辑') || \Illuminate\Support\Facades\Gate::check('订单管理-工单处理-商家编辑') )
+                    {
+                        name: 'rejected_bills_items', value: '退回商品详情'
+                    },
+                        @endif
+                    {
+                        name: 'process_logs', value: '处理日志'
+                    },
                         @can('订单管理-工单处理-宝时编辑')
                     {
-                        name: 'order_issue_log', value: '处理结果'
+                        name: 'order_issue_log', value: '问题件处理结果'
                     },
                         @endcan
                     {
                         name: 'ab_operation', type: 'multi', title: "其他操作", rows: [
                                 @can('订单管理-工单处理-删除')
                             {
-                                value: "删除", col: "1"
+                                value: "删除", col: "2"
                             },
-                            {value: "查看资料", col: "6"},
-                            {value: "处理日志", col: "5"},
+                            {value: "查看资料", col: "10"},
                                 @else
                             {
-                                value: "查看资料", col: "6"
+                                value: "查看资料", col: "12"
                             },
-                            {value: "处理日志", col: "6"},
                             @endcan
                         ], neglect: true
                     },
+                        @can('订单管理-工单处理-宝时编辑')
+                    {
+                        name: 'logistic_indemnity_money', value: '承运商赔偿金额'
+                    },
+                    {name: 'logistic_express_remission', value: '承运商快递减免'},
+                    {name: 'bao_shi_indemnity_money', value: '宝时赔偿金额'},
+                    {name: 'bao_shi_express_remission', value: '宝时快递减免'},
+                    {name: 'user_work_groups', value: '仓库组责任方'},
+                    {name: 'user_owner_group', value: '项目组责任方'},
+                    @endcan
                 ];
                 new Header({
                     el: "table",
@@ -778,15 +959,6 @@
                         $(e.target).text("记录共" + orderIssue.logs.length + "条,点击展开");
                     }
                 },
-                toggleWorkOrderLogs(item, e, index) {
-                    if (item.log_is_show === false) {
-                        item.log_is_show = true;
-                        $(e.target).text('点击收起');
-                    } else {
-                        item.log_is_show = false;
-                        $(e.target).text("记录共" + item.process_logs.length + "条,点击展开");
-                    }
-                },
                 sortOrder(workOrder) {
                     workOrder.last_handler_name = workOrder.last_handler ? workOrder.last_handler.name : '';
                     workOrder.detail_infos = this.groupDetails(workOrder);                          // 工单详情
@@ -810,6 +982,23 @@
                     workOrder.order_commodities = this.groupOrderPackageCommodities(workOrder);
                     workOrder.is_issue_order = workOrder.order_issue !== null;
                     if (workOrder.order_issue !== null) workOrder.order_issue.log_is_show = 'order_issue' in workOrder;
+                    let rejected_bill_items = this.groupRejectedBillItems(workOrder);
+                    workOrder.rejected_bill_items = rejected_bill_items;
+                    workOrder.rejected_bill_item_amount_count = rejected_bill_items ? rejected_bill_items.map(e => Number(e.amount)).reduce((a, b) => Number(a) + Number(b), 0) : 0;
+                },
+                groupRejectedBillItems(workOrder) {
+                    let {order_issue_rejected_bills} = workOrder;
+                    if (!order_issue_rejected_bills) return [];
+                    return order_issue_rejected_bills.map(e => e.rejected_bill).filter(e => e).map(e => e.items).reduce((a, b) => a.concat(b), [])
+                        .map(e => {
+                            return {
+                                amount: e.amount,
+                                quality_label: e.quality_label,
+                                barcode_goods: e.barcode_goods,
+                                name_goods: e.name_goods,
+                                remark: e.remark,
+                            }
+                        });
                 },
                 groupOrderPackageCommodities(workOrder) {
                     let order_packages = workOrder.order ? workOrder.order.packages : [];
@@ -1827,7 +2016,6 @@
                 },
                 logisticCheckDamage() {
                     let {commodities} = this.logisticEditWorkOrder;
-                    commodities.forEach(e => console.log(Number(e.price) === 0));
                     return commodities.filter(e => Number(e.price) === 0).length === 0;
                 },
                 logisticEdit() {
@@ -1929,7 +2117,7 @@
                 getLogisticCheckResult() {
                     let {issue_type_name} = this.logisticEditWorkOrder;
                     let items = [
-                        {issue_type_name: '快递异常', option: ['已处理', '已拦截']},
+                        {issue_type_name: '快递异常', option: ['已签收', '拦截退回']},
                         {issue_type_name: '破损', option: ['核实全部破损', '核实部分破损', '核实未破损']},
                     ];
                     let item = items.find(e => e.issue_type_name === issue_type_name);
@@ -1978,7 +2166,7 @@
                 canTagWorkOrder(item) {
                     let {pending_detail, status, issue_type_name} = item;
                     if (status !== '承运商处理') return false;
-                    if (!['拦截', '取消拦截', '信息更改'].includes(issue_type_name)) return false;
+                    if (!['拦截', '取消拦截', '信息更改','快递异常'].includes(issue_type_name)) return false;
                     let {logistic_handle_tag} = pending_detail;
                     return logistic_handle_tag !== '承运商处理中';
                 },
@@ -3307,7 +3495,7 @@
 
                 showOrderCommoditiesInfo(item) {
                     this.dialogOrderCommoditiesVisible = true;
-                    this.orderInfo.commodities = item.order_commodities;
+                    this.orderInfo.commodities = item.order_commodities
                 },
 
                 displayDelBtn(bool, e) {
@@ -3318,56 +3506,175 @@
                         }, 100);
                     }
                 },
-
-                joinLogisticNumberReturn(item,e,index){
+                nowrapText(e) {
+                    let truncateSpan = $(e.target);
+                    truncateSpan.hide();
+                    truncateSpan.siblings('.text-nowrap').show();
+                },
+                truncateText(e) {
+                    let nowrapSpan = $(e.target);
+                    nowrapSpan.hide();
+                    nowrapSpan.siblings('.text-truncate').show();
+                },
+                joinLogisticNumberReturn(item, e, index) {
                     let logistic_number_return = $(e.target).prev().val();
-                    console.log(logistic_number_return);
                     if (logistic_number_return.trim().length === 0){
                         this.errorTempTip('请输入退回单号进行添加');
                         return;
                     }
                     let url = "{{route('workOrder.rejectedBill.storeApi')}}";
-                    let data = {order_id:item.order_id,logistic_number_return:logistic_number_return};
+                    let data = {order_id: item.order_id, logistic_number_return: logistic_number_return};
                     this.waitingTempTip('处理中');
-                    window.axios.post(url,data).then(res=>{
+                    window.axios.post(url, data).then(res => {
                         window.tempTip.cancelWaitingTip();
-                        if (res.data.success){
+                        if (res.data.success) {
                             this.sortOrder(res.data.data);
-                            this.$set(this.workOrders,index,res.data.data);
+                            this.$set(this.workOrders, index, res.data.data);
                             this.successTempTip('处理完成');
                             this.$forceUpdate();
                             $(e.target).prev().val('');
-                            return ;
+                            return;
                         }
-                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常' )
-                    }).catch(err=>{
+                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常')
+                    }).catch(err => {
                         window.tempTip.cancelWaitingTip();
                         this.errorTempTip(err);
                     });
                 },
-                unJoinLogisticNumberReturn(item,logistic_number_return,index){
-                    if (logistic_number_return.trim().length === 0){
+                unJoinLogisticNumberReturn(item, logistic_number_return, index) {
+                    if (logistic_number_return.trim().length === 0) {
                         this.errorTempTip('请输入退回单号进行添加');
                         return;
                     }
                     let url = "{{route('workOrder.rejectedBill.destroyApi')}}";
-                    let data = {order_id:item.order_id,logistic_number_return:logistic_number_return};
+                    let data = {order_id: item.order_id, logistic_number_return: logistic_number_return};
                     this.waitingTempTip('处理中');
-                    window.axios.post(url,data).then(res=>{
+                    window.axios.post(url, data).then(res => {
                         window.tempTip.cancelWaitingTip();
-                        if (res.data.success){
+                        if (res.data.success) {
                             this.sortOrder(res.data.data);
-                            this.$set(this.workOrders,index,res.data.data);
+                            this.$set(this.workOrders, index, res.data.data);
                             this.successTempTip('处理完成');
                             this.$forceUpdate();
+                            return;
+                        }
+                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常')
+                    }).catch(err => {
+                        window.tempTip.cancelWaitingTip();
+                        this.errorTempTip(err);
+                    });
+                },
+                changeWorkOrderInfo(item, column, e) {
+                    let url = "{{route('workOrder.updateRemissionApi')}}";
+                    let data = {
+                        id: item.id,
+                        column: column,
+                        value: $(e.target).val(),
+                    };
+                    this.waitingTempTip('处理中');
+                    axios.post(url, data).then(res => {
+                        window.tempTip.cancelWaitingTip();
+                        if (res.data.success) {
+                            item[column] = $(e.target).val();
+                            this.successTempTip('处理完成');
+                            return;
+                        }
+                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常,刷新重试');
+                    }).catch(err => {
+                        window.tempTip.cancelWaitingTip();
+                        this.errorTempTip(err);
+                    });
+                },
+                changeUserOwnerGroup(item,e) {
+                    let url ="{{route('workOrder.userOwnerGroup.updateApi')}}";
+                    let data = {
+                        id:item.id,
+                        user_owner_group_id:$(e.target).val(),
+                    };
+                    this.waitingTempTip('处理中');
+                    axios.post(url,data).then(res=>{
+                        window.tempTip.cancelWaitingTip();
+                        if (res.data.success){
+                            item.user_work_group_id = $(e.target).val();
+                            this.successTempTip('处理完成');
+                            return;
+                        }
+                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常,刷新后重试');
+                    }).catch(err=>{
+                        window.tempTip.cancelWaitingTip();
+                        this.errorTempTip(err);
+                    })
+                },
+                createUserWorkGroup(item,e) {
+                    let url = "{{route('workOrder.userWorkGroups.storeApi')}}";
+                    let data = {
+                        id:item.id,
+                        user_workgroup_id:$(e.target).val(),
+                    };
+                    this.waitingTempTip('处理中');
+                    axios.post(url,data).then(res=>{
+                        window.tempTip.cancelWaitingTip();
+                        if (res.data.success){
+                            this.successTempTip('处理完成');
+                            item.user_work_groups = res.data.data;
+                            return;
+                        }
+                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常,刷新后重试');
+                    }).catch(err=>{
+                        window.tempTip.cancelWaitingTip();
+                        this.errorTempTip(err);
+                    })
+                },
+                destroyUserWorkGroup(item,index,e){
+                    if(!confirm('确认删除?')) return;
+                    let url ="{{route('workOrder.userWorkGroups.destroyApi')}}";
+                    let data = {
+                        id:item.id,
+                        user_workgroup_id:$(e.target).val(),
+                    };
+                    this.waitingTempTip('处理中');
+                    axios.post(url,data).then(res=>{
+                        window.tempTip.cancelWaitingTip();
+                        if (res.data.success){
+                            this.successTempTip('处理完成');
+                            item.user_work_groups.splice(index,1);
+                            return;
+                        }
+                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常,刷新后重试');
+                    }).catch(err=>{
+                        window.tempTip.cancelWaitingTip();
+                        this.errorTempTip(err);
+                    })
+                },
+                getEqualsMap(item){
+                    let order_detail_id = item.pending_detail.id;
+                    let url = "{{route('workOrder.commodity.equalsMapApi')}}";
+                    let data = {
+                        id:order_detail_id,
+                    }
+                    this.waitingTempTip('获取中..');
+                    axios.post(url,data).then(res=>{
+                        window.tempTip.cancelWaitingTip();
+                        if(res.data.success){
+                            this.commodityEqualsMap = res.data.data;
+                            this.dialogCommoditiesEqualsVisible = true;
                             return ;
                         }
-                        this.errorTempTip(res.data.message ? res.data.message : '处理出现异常' )
+                        this.errorTempTip(res.data.message ? res.data.message : '获取失败');
                     }).catch(err=>{
                         window.tempTip.cancelWaitingTip();
                         this.errorTempTip(err);
                     });
-                }
+                },
+                workOrderExport(sign) {
+                    let url = '{{route('workOrder.exportApi')}}';
+                    let token = '{{ csrf_token() }}';
+                    if (sign) {
+                        excelExport(true, checkData, url, this.total, token);
+                    } else {
+                        excelExport(false, checkData, url, null, token);
+                    }
+                },
             },
         });
     </script>

+ 1 - 1
resources/views/store/deliveryAppointment/appointment.blade.php

@@ -68,7 +68,7 @@
                                 <input class="col-9 form-control" type="text" id="procurementNumber" v-model="model.procurement_number" :class="errors.procurement_number ? 'is-invalid' : ''">
                             </div>
                             <div class="row mt-2">
-                                <label class="col-3" for="asnNumber">ASN单号</label>
+                                <label class="col-3" for="asnNumber"><b class="text-danger">*&nbsp;</b>ASN单号</label>
                                 <input class="col-9 form-control" placeholder="可以输入多个,使用空格或逗号分隔" @blur="verifyASN()"
                                        type="text" id="asnNumber" v-model="model.asn_number" :class="errors.asn_number ? 'is-invalid' : ''">
                             </div>

+ 3 - 2
resources/views/transport/waybill/index.blade.php

@@ -566,8 +566,8 @@
                         is_cancel:'{{$waybill->order->wms_status ?? ''}}' === '订单取消',
                         origination:'{{$waybill->origination}}',
                         merge_owner:'{{$waybill->merge_owner}}',
-                        destination:'{{$waybill->order_address ?? $waybill->destination}}',
-                        recipient:'{{$waybill->order->consignee_name ?? $waybill->recipient}}',
+                        destination:'{{str_replace("\n", ' ', preg_replace("/[\n\s]/",' ',($waybill->order_address??"")) ?? preg_replace("/[\n\s]/",' ',$waybill->destination))}}',
+                        recipient:'{{str_replace("\n", ' ', preg_replace("/[\n\s]/",' ',$waybill->order->consignee_name ?? $waybill->recipient))}}',
                         recipient_mobile:'{{$waybill->order_consignee_phone ?? $waybill->recipient_mobile}}',
                         charge:'{{$waybill->charge}}',
                         ordering_remark:'{{preg_replace("/[\n\s]/",' ',($waybill->ordering_remark??""))}}',
@@ -648,6 +648,7 @@
                 appendFluxInfo:false,
             },
             mounted:function(){
+                console.log(1);
                 $(".tooltipTarget").tooltip({'trigger':'hover'});
                 $('#list').removeClass('d-none');
                 let data=[

+ 7 - 0
routes/apiLocal.php

@@ -296,6 +296,11 @@ Route::group(['prefix' => 'print'],function (){
 });
 
 Route::prefix('workOrder')->group(function(){
+    Route::post('updateRemission',"WorkOrderController@updateRemissionApi")->name('workOrder.updateRemissionApi');
+    Route::post('userOwnerGroup/update',"WorkOrderController@updateUserOwnerGroupApi")->name('workOrder.userOwnerGroup.updateApi');
+    Route::post('userWorkGroup/store',"WorkOrderController@storeUserWorkGroupApi")->name('workOrder.userWorkGroups.storeApi');
+    Route::post('userWorkGroup/destroy',"WorkOrderController@destroyUserWorkGroupApi")->name('workOrder.userWorkGroups.destroyApi');
+
     Route::post('end','WorkOrderController@ownerEndWorkOrderApi')->name('workOrder.owner.endApi');                              // 承运商完结工单
     Route::post('batchEnd','WorkOrderController@ownerBatchEndWorkOrderApi')->name('workOrder.owner.batchEndApi');               // 承运商处理标记
     Route::post('logisticTag','WorkOrderController@logisticHandlerTagApi')->name('workOrder.logistic.handlerTagApi');           // 承运商处理标记
@@ -361,10 +366,12 @@ Route::prefix('workOrder')->group(function(){
     Route::post('buildOrderIssue','WorkOrderController@buildOrderIssueApi')->name('workOrder.buildOrderIssueApi');          // 生成问题件
     Route::delete('/{id}','WorkOrderController@destroyApi')->name('workOrder.destroyApi');                                  // 工单删除
     Route::post('check','WorkOrderController@checkWorkOrderApi')->name('workOrder.checkApi');                               // 检查订单是否存在工单
+
     Route::prefix('commodity')->group(function(){
         Route::post("/owner","WorkOrderCommoditiesController@ownerUpdateCommoditiesApi")->name("workOrder.commodity.ownerUpdateApi");          // 货主填充商品信息
         Route::post("/logistic","WorkOrderCommoditiesController@logisticUpdateCommoditiesApi")->name("workOrder.commodity.logisticUpdateApi"); // 承运商 更新商品 处理信息
         Route::post("/baoShi","WorkOrderCommoditiesController@baoShiUpdateCommoditiesApi")->name("workOrder.commodity.baoShiUpdateApi");       // 宝时客服 更新丢件信息
+        Route::post('/getCommodityEqualsMap',"WorkOrderCommoditiesController@getCommodityEqualsMapApi")->name('workOrder.commodity.equalsMapApi'); // 商品数量
     });
 
     Route::prefix('rejectedBill/relation')->group(function(){

+ 1 - 0
routes/web.php

@@ -935,6 +935,7 @@ Route::group(['middleware' => 'auth'], function ($route) {
         /** 工单 */
         Route::prefix('workOrder')->group(function () {
             Route::get('index', 'WorkOrderController@index');
+            Route::match(['get', 'post'], 'export', 'WorkOrderController@exportJsonExcel')->name('workOrder.exportApi');
         });
     });
     /** 结算 */