Ver Fonte

Merge branch 'master' into Haozi

haozi há 4 anos atrás
pai
commit
ab548ecd3e
46 ficheiros alterados com 2521 adições e 1079 exclusões
  1. 1 1
      app/Console/Kernel.php
  2. 23 9
      app/Filters/WorkOrderFilters.php
  3. 1 1
      app/Http/Controllers/Auth/RegisterController.php
  4. 5 1
      app/Http/Controllers/CommodityController.php
  5. 15 0
      app/Http/Controllers/KpiController.php
  6. 18 1
      app/Http/Controllers/OrderIssueController.php
  7. 146 17
      app/Http/Controllers/TestController.php
  8. 89 55
      app/Http/Controllers/WorkOrderCommoditiesController.php
  9. 77 146
      app/Http/Controllers/WorkOrderController.php
  10. 0 35
      app/Http/Controllers/WorkOrderProcessLogController.php
  11. 1 1
      app/Services/CommodityService.php
  12. 5 0
      app/Services/OrderIssueService.php
  13. 5 3
      app/Services/OrderPackageCommoditiesService.php
  14. 40 10
      app/Services/WorkOrderCommoditiesService.php
  15. 95 4
      app/Services/WorkOrderDetailService.php
  16. 64 44
      app/Services/WorkOrderImageService.php
  17. 28 3
      app/Services/WorkOrderLogService.php
  18. 91 62
      app/Services/WorkOrderService.php
  19. 29 142
      app/WorkOrder.php
  20. 52 8
      app/WorkOrderCommodities.php
  21. 122 1
      app/WorkOrderDetail.php
  22. 34 3
      app/WorkOrderImage.php
  23. 26 3
      app/WorkOrderLog.php
  24. 6 0
      app/WorkOrderProcessLog.php
  25. 44 0
      database/migrations/2021_11_19_104807_work_order_commodity_add_issue_type.php
  26. 36 0
      database/migrations/2021_11_19_114225_work_order_images_add_columns.php
  27. 43 0
      database/migrations/2021_11_22_133944_work_order_details_add_columns.php
  28. 34 0
      database/migrations/2021_11_22_134750_work_order_logs_add_columns.php
  29. 42 12
      resources/views/kpi/day/index.blade.php
  30. 205 0
      resources/views/kpi/dayDetail/index.blade.php
  31. 263 0
      resources/views/kpi/dayDetailCustomer/index.blade.php
  32. 3 3
      resources/views/kpi/month/index.blade.php
  33. 21 26
      resources/views/order/index/_work_order_info_modal.blade.php
  34. 50 14
      resources/views/order/index/_work_order_modal.blade.php
  35. 132 35
      resources/views/order/index/delivering.blade.php
  36. 26 0
      resources/views/order/issue/_batchUpdateFinalStatus.blade.php
  37. 33 1
      resources/views/order/issue/index.blade.php
  38. 29 21
      resources/views/order/workOrder/_bao_shi_fill_work_order_modal.blade.php
  39. 15 20
      resources/views/order/workOrder/_bao_shi_review_modal.blade.php
  40. 70 0
      resources/views/order/workOrder/_issue_logs.blade.php
  41. 17 27
      resources/views/order/workOrder/_logistic_fill_work_order_modal.blade.php
  42. 14 12
      resources/views/order/workOrder/_owner_fill_work_order_modal.blade.php
  43. 115 50
      resources/views/order/workOrder/_work_order_details.blade.php
  44. 333 278
      resources/views/order/workOrder/index.blade.php
  45. 21 30
      routes/apiLocal.php
  46. 2 0
      routes/web.php

+ 1 - 1
app/Console/Kernel.php

@@ -68,7 +68,7 @@ class  Kernel extends ConsoleKernel
         $schedule->command('LogExpireDelete')->dailyAt('00:01');
         $schedule->command('InventoryDailyLoggingOwner')->dailyAt('08:00')->runInBackground();
         $schedule->command('FluxOrderFix')->hourlyAt(1);
-        //$schedule->command('WASSyncWMSOrderInformation')->everyMinute();
+        $schedule->command('WASSyncWMSOrderInformation')->everyMinute();
         $schedule->command('syncLogCacheTask')->everyMinute();
         $schedule->command('createOwnerReport')->monthlyOn(1);
         $schedule->command('createOwnerBillReport')->monthlyOn(1);

+ 23 - 9
app/Filters/WorkOrderFilters.php

@@ -38,7 +38,8 @@ class WorkOrderFilters
         'order_issue_type',
         'owner',
         'client_code',
-        'is_end'
+        'is_end',
+        'status'
     ];
     protected $array_filter;
     protected $params = [];
@@ -100,17 +101,20 @@ class WorkOrderFilters
 
     private function filterWorkOrderStatus()
     {
-        if (isset($this->params['is_end'])) return;
-        $this->queryBuilder->where('status', '!=', 5);      // 过滤已完成
         $status = [];
-        if (Gate::allows('订单管理-工单处理-客服编辑')) {
-            $status[]=  4;
+        if (Gate::allows('订单管理-工单处理-宝时编辑')) {
+            array_push($status,1,4);
         }
         if (Gate::allows('订单管理-工单处理-承运商编辑')) {
-            $status[]=  3;
+            array_push($status,3);
         }
         if (Gate::allows('订单管理-工单处理-货主编辑')) {
-            $status[]=  1;
+            array_push($status,2);
+        }
+        if (!isset($this->params['is_end'])) {
+            $this->queryBuilder->where('status', '!=', 5);      // 过滤已完成
+        } else {
+            array_push($status,5);
         }
         $this->queryBuilder->whereIn('status',$status);
     }
@@ -124,7 +128,7 @@ class WorkOrderFilters
 
     private function afterFilterLogistic($logistic_ids)
     {
-        if (Gate::allows('订单管理-工单处理-承运商编辑')) {
+        if (Gate::allows('订单管理-工单处理-承运商编辑') && !Gate::allows('订单管理-工单处理-宝时编辑')) {
             $this->queryBuilder->whereIn('logistic_id', array_values($logistic_ids));
         }
     }
@@ -271,5 +275,15 @@ class WorkOrderFilters
     {
         $this->searchWay($this->getOrderQuery(), $client_code, 'orders.client_code');
     }
-
+    public function status($status){
+        $status_list = [];
+        if ($status == '承运商处理'){
+            array_push($status_list,3);
+        } elseif ($status == '宝时处理') {
+            array_push($status_list,4,1);
+        } elseif ($status == '货主处理'){
+            array_push($status_list,2);
+        }
+        $this->queryBuilder->whereIn('status',$status_list);
+    }
 }

+ 1 - 1
app/Http/Controllers/Auth/RegisterController.php

@@ -99,7 +99,7 @@ class RegisterController extends Controller
             $user->suppliers()->sync($supplierIdArr);
         }
 //        $this->guard()->login($user);
-        $carrierIds=$request->input('carrier')??'';
+        $carrierIds=$request->input('logistic')??'';
         if ($carrierIds){
             $carrierIds=explode(',',$carrierIds);
             $user->logistics()->sync($carrierIds);

+ 5 - 1
app/Http/Controllers/CommodityController.php

@@ -398,7 +398,11 @@ class CommodityController extends Controller
 
     public function getCommodityApi(Request $request,CommodityService $service): array
     {
-        $owner = Owner::query()->where('name',$request['owner_name'])->first();
+        $ownerService = new OwnerService();
+        $codes = [$request->input('owner_code')];
+        $ownerService->createByWmsCustomerIds([$request->input('owner_code')]);
+        $owner = Owner::query()->where('code',$request['owner_code'])->first();
+        $service->syncWMSOrderCode($owner,[$request->input('sku')]);
         if (!$owner){
             return ['success' => false ,'message' => '货主未找到'];
         }

+ 15 - 0
app/Http/Controllers/KpiController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Services\UserService;
 use Illuminate\Http\Request;
 
 class KpiController extends Controller
@@ -15,4 +16,18 @@ class KpiController extends Controller
     {
         return view('kpi.day.index');
     }
+
+    public function dayDetailIndex()
+    {
+        return view('kpi.dayDetail.index');
+    }
+
+    public function dayDetailCustomer()
+    {
+        /** @var UserService $userService */
+        $userService = app('UserService');
+        $ownerIds =  $userService->getPermittingOwnerIds(auth()->user());
+        $owners = \App\Owner::query()->select(['id', 'name', 'code'])->whereIn('id', $ownerIds)->get();
+        return view('kpi.dayDetailCustomer.index', compact('owners'));
+    }
 }

+ 18 - 1
app/Http/Controllers/OrderIssueController.php

@@ -26,6 +26,7 @@ use App\UserWorkgroup;
 use Exception;
 use Illuminate\Database\QueryException;
 use Illuminate\Http\Request;
+use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Gate;
@@ -564,7 +565,7 @@ class OrderIssueController extends Controller
             '退回单号', '退单商品名','退单商品条码','退单商品数量','是否正品','退单状态','退单备注',
             '操作类型','说明','操作者','情况说明','问题类别',
             '二次订单号','二次承运商','二次运单号','二次商品条码','二次商品名','二次商品数量',
-            '最终状态', '承运商赔偿金额', '承运商快递减免', '宝时赔偿金额', '宝时快递减免','事故责任方',/*'项目责任方'*/
+            '最终状态', '承运商赔偿金额', '承运商快递减免', '宝时赔偿金额', '宝时快递减免','事故责任方','完结时间'
         ];
         foreach ($order_Issues as $order_issue){
             $order =  $order_issue->order;
@@ -622,6 +623,9 @@ class OrderIssueController extends Controller
                 $userWorkgroupsName.=($userWorkgroup->name).",\r\n";
             });
             if (isset($order_issue->userOwnerGroup->name))$userWorkgroupsName.=$order_issue->userOwnerGroup->name.",\r\n";
+            $endLog = $order_issue->logs->where('type','结束')->last() ?? null;
+            $end_at = $endLog ? $endLog->created_at : null;
+            if ($end_at != null ) $end_at = $end_at->format(\Carbon\Carbon::DEFAULT_TO_STRING_FORMAT);
             $json[] = [
                 isset($order_issue->created_at) ? str_split($order_issue->created_at,10)[0] :'',       // 登记日期
                 isset($order->created_at) ? str_split($order->created_at,10)[0] :'',             // 创建日期
@@ -675,6 +679,7 @@ class OrderIssueController extends Controller
                 $order_issue->baoshi_express_remission,
                 rtrim($userWorkgroupsName,",\r\n"),
 //                $order_issue->userOwnerGroup->name ?? '',
+                $end_at
             ];
         }
         return Export::make($row,$json,"订单问题件");
@@ -807,4 +812,16 @@ class OrderIssueController extends Controller
             return ['success'=>false,'error'=>'删除失败'];
         }
     }
+
+    public function batchUpdateFinalStatusApi(Request $request,OrderIssueService $service): array
+    {
+        if (!Gate::allows('订单管理-问题件-编辑')) return ['success'=>false,'error'=>'没有对应权限'];
+        try {
+            $service->batchUpdateFinalStatus($request->input('ids', []), $request->input('final_status'));
+            return ['success'=>true];
+        } catch (Exception $e) {
+            return ['success'=>false,'message' => '批量修改异常'];
+        }
+
+    }
 }

+ 146 - 17
app/Http/Controllers/TestController.php

@@ -108,6 +108,10 @@ use App\UserDutyCheck;
 use App\ValueStore;
 use App\Waybill;
 use App\WorkOrder;
+use App\WorkOrderCommodities;
+use App\WorkOrderDetail;
+use App\WorkOrderImage;
+use App\WorkOrderLog;
 use Carbon\Carbon;
 use Carbon\CarbonPeriod;
 use Decimal\Decimal;
@@ -649,6 +653,61 @@ sql;
         ValueStore::query()->where('name','last_order_sync_task_end_at')->update(['value' => '2021-10-12 06:23:38']);
     }
 
+    public function test3()
+    {
+        foreach (Batch::query()->where("updated_at",">=","2021-11-22 09:00:00")->get() as $batch){
+            try {
+                $this->assignBatch($batch->code);
+            }catch (\Exception $e){
+                continue;
+            }
+        }
+    }
+
+    public function assignBatch($code)
+    {
+        $batches = Batch::query()->where("code",$code)->get();
+        if (!$batches->count()){
+            $wave = DB::connection("oracle")->selectOne(DB::raw("select * from DOC_WAVE_HEADER where WAVENO = ?"),[$code]);
+            if (!$wave){
+                dd("FLUX无波次");
+            }
+            $owner = app("OwnerService")->codeGetOwner($wave->customerid);
+            $obj = [
+                "wms_status" => $this->wms_status($wave),
+                "wms_type"=>$wave->descr,
+                "created_at"=>date("Y-m-d H:i:s"),
+                "wms_created_at"=>$wave->addtime,
+                "updated_at"=>$wave->edittime,
+                "owner_id"=>$owner->id,
+            ];
+            $wave = Batch::query()->where("code",$code)->first();
+            if (!$wave){
+                $obj["code"] = $code;
+                $wave = Batch::query()->create($obj);
+            }else{
+                Batch::query()->where("code",$code)->update($obj);
+            }
+            $ordernos = array_column(DB::connection("oracle")->select(DB::raw("select orderno from DOC_WAVE_DETAILS where WAVENO = ?"),[$code]),"orderno");
+            Order::query()->whereIn("code",$ordernos)->update([
+                "batch_id"=>$wave->id
+            ]);
+            Order::query()->with(["batch","bin"])->whereIn("code",$ordernos)->get()->each(function ($order){
+                if (!$order->bin){
+                    $bin = DB::connection("oracle")->selectOne(DB::raw("select seqno from DOC_WAVE_DETAILS where waveno = ? and orderno = ?"),[$order->batch->code,$order->code]);
+                    if ($bin){
+                        OrderBin::query()->create([
+                            'order_id' => $order->id,
+                            'number' => $bin->seqno,
+                        ]);
+                    }
+                }
+            });
+            $batches = Batch::query()->where("code",$code)->get();
+        }
+        app("BatchService")->assignTasks($batches);
+    }
+
 
     public function syncOrder()
     {
@@ -672,7 +731,16 @@ sql;
     {
 //        $batches=Batch::query()->where('id',161071)->get();
 //        BroadcastBatchToZhengCangJob::dispatch($batches);
-        dd(Carbon::now()->subDays());
+//        $sql = <<<sql
+//select department_id,obligation_id,owner_id,max(valid_time) from department_obligation_owner group by obligation_id,owner_id,department_id
+//sql;
+//        $info = DB::select(DB::raw($sql));
+//        dd($info);
+//        $owner=Owner::query()->with(['departmentObligationOwner'])->find(403);
+//        dd($owner);
+//        $a=app('ObligationService')->recombineCodeIdArr();
+        $now=Carbon::now()->subMonths(-1)->startOfMonth()->startOfDay()->toDateTimeString();
+        dd($now);
     }
 
     public function syncOrderIssue()
@@ -684,7 +752,10 @@ sql;
 
     public function test123()
     {
-
+        $user = User::query()->where('name','yanyuanmin')->first();
+        Auth::setUser($user);
+        dd(Auth::user());
+        return ;
         $reflection = new \ReflectionClass(new OrderIssue());
         dump($reflection->getMethods());
         dump($reflection->getConstants());
@@ -704,23 +775,81 @@ sql;
         }
     }
 
-    public function testLabor()
+    public function SyncOrder11(){
+        WorkOrder::query()->whereIn('id',['3420','3421','3422'])->update(['status'=>'3']);
+        WorkOrder::query()->whereIn('id',['3423','3424','3425'])->update(['status'=>'3']);
+    }
+
+    public function workOrderChangeVersion()
+    {
+        $workOrders = WorkOrder::query()->with('details')->get();
+        $workOrderDetails = $this->groupByWorkOrderId(WorkOrderDetail::query()->get());
+        $WorkOrderLogs = $this->groupByWorkOrderId(WorkOrderLog::query()->get());
+        $workOrderImages = $this->groupByWorkOrderId(WorkOrderImage::query()->get());
+        $workOrderCommodities = $this->groupByWorkOrderId(WorkOrderCommodities::query()->get());
+        $workOrderLogUpDateParams = [['id','tag','work_order_detail_id']];
+        $workOrderImagesUpDateParams = [['id','tag','work_order_detail_id']];
+        $workOrderCommoditiesUpDateParams = [['id','tag','work_order_detail_id']];
+        foreach ($workOrders as $workOrder) {
+            $detail =  $workOrderDetails[$workOrder->id][0] ?? null;
+            if (!$detail){
+                $detail = new WorkOrderDetail([
+                    'work_order_id' => $workOrder->id,
+                    'order_issue_type_id' => $workOrder->order_issue_type_id ?? '',
+                    'remark' => $workOrder->remark,
+                    'status' => $workOrder->status,
+                ]);
+                if ($detail->status == '完结'){$detail->tag = 1;}
+                else {$detail->tag = 0;}
+                $detail->status = $workOrder->status;
+                $detail->save();
+            } else {
+                $detail->order_issue_type_id = $workOrder->order_issue_type_id ?? '';
+                $detail->remark = $workOrder->remark ?? '';
+                $detail->status = $workOrder->status;
+                $detail->update();
+            }
+            if ($WorkOrderLogs[$workOrder->id]??false){
+                $arrays = $this->getUpdateParams($workOrder,$detail,$WorkOrderLogs[$workOrder->id] ?? null);
+                array_push($workOrderLogUpDateParams,$arrays);
+            }
+            if ($workOrderImages[$workOrder->id]??false){
+                $arrays = $this->getUpdateParams($workOrder,$detail,$workOrderImages[$workOrder->id] ?? null);
+                array_push($workOrderImagesUpDateParams,$arrays);
+            }
+            if (  $workOrderCommodities[$workOrder->id]??false){
+                $arrays = $this->getUpdateParams($workOrder,$detail,$workOrderCommodities[$workOrder->id] ?? null);
+                array_push($workOrderCommoditiesUpDateParams,$arrays);
+            }
+        }
+
+        $service = new BatchUpdateService();
+        if (count($workOrderLogUpDateParams) > 1) $service->batchUpdate('work_order_logs',$workOrderLogUpDateParams);
+        if (count($workOrderImagesUpDateParams) > 1) $service->batchUpdate('work_order_images',$workOrderImagesUpDateParams);
+        if (count($workOrderCommoditiesUpDateParams) > 1) $service->batchUpdate('work_order_commodities',$workOrderCommoditiesUpDateParams);
+    }
+
+    public function getUpdateParams($workOrder,$detail,$items):array
     {
-//        $datas=['22668','22669','22673','22675','22676','22677','22678','22679','22682','22684','22686','22688','22691','22693','22695','22698'];//嘉权
-        $datas=['22680','22687','22690','22692','22697','22700',];//金旋
-        foreach ($datas as $data){
-//            LaborReportStatus::query()->create([
-//                'labor_report_id'=>$data,
-//                'created_at'=>'2021-11-22 18:10:00',
-//                'status'=>'已退场'
-//            ]);
+        $array = [];
+        $tag = $detail->status == '完成' ? 1 : 0;
+        foreach ($items as $item){
+            $item = ['id' => $item->id,'tag' => $tag,'work_order_detail_id' => $detail->id];
+            $array[] = $item;
+        }
+        return $array;
+    }
 
-            LaborReport::query()->where('id',$data)->update([
-                'check_in_at'=>'2021-11-23 09:00:00',
-                'verify_at'=>'2021-11-23 09:00:00',
-                'group_user_id'=>84,
-                'user_workgroup_id'=>4,
-            ]);
+    public function groupByWorkOrderId($items): array
+    {
+        $array = [];
+        foreach ($items as $item) {
+            if (in_array($item->id,$array)){
+                $array[$item->work_order_id][] = $item;
+            } else {
+                $array[$item->work_order_id] = [$item];
+            }
         }
+        return $array;
     }
 }

+ 89 - 55
app/Http/Controllers/WorkOrderCommoditiesController.php

@@ -2,84 +2,118 @@
 
 namespace App\Http\Controllers;
 
-use App\WorkOrderCommodities;
-use Illuminate\Http\Request;
+use App\Services\WorkOrderCommoditiesService;
+use App\Services\WorkOrderDetailService;
+use App\Services\WorkOrderLogService;
+use App\Services\WorkOrderService;
+ use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Gate;
 
 class WorkOrderCommoditiesController extends Controller
 {
     /**
-     * Display a listing of the resource.
-     *
-     * @return \Illuminate\Http\Response
+     * @var WorkOrderCommoditiesService $service
+     * @var WorkOrderDetailService $detailService
+     * @var WorkOrderLogService $logService
+     * @var WorkOrderService $workOrderService
      */
-    public function index()
-    {
-        //
-    }
+    private $service;
+    private $detailService;
+    private $logService;
+    private $workOrderService;
 
-    /**
-     * Show the form for creating a new resource.
-     *
-     * @return \Illuminate\Http\Response
-     */
-    public function create()
+    public function __construct()
     {
-        //
+        $this->service = app(WorkOrderCommoditiesService::class);
+        $this->detailService = app(WorkOrderDetailService::class);
+        $this->logService = app(WorkOrderLogService::class);
+        $this->workOrderService = app(WorkOrderService::class);
     }
 
     /**
-     * Store a newly created resource in storage.
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @return \Illuminate\Http\Response
+     * 货主填充商品信息
+     * @param Request $request
+     * @return array
      */
-    public function store(Request $request)
+    public function ownerUpdateCommoditiesApi(Request $request): array
     {
-        //
-    }
+        if (Gate::denies('订单管理-工单处理-货主编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        $workOrder = $this->service->find($request->input('id'));
 
-    /**
-     * Display the specified resource.
-     *
-     * @param  \App\WorkOrderCommodities  $workOrderCommodities
-     * @return \Illuminate\Http\Response
-     */
-    public function show(WorkOrderCommodities $workOrderCommodities)
-    {
-        //
-    }
+        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
 
-    /**
-     * Show the form for editing the specified resource.
-     *
-     * @param  \App\WorkOrderCommodities  $workOrderCommodities
-     * @return \Illuminate\Http\Response
-     */
-    public function edit(WorkOrderCommodities $workOrderCommodities)
-    {
-        //
+        $this->service->updateWorkOrderCommoditiesByJsonArray($workOrder, $request->input('commodities'),'货主已处理');
+
+        if(($workOrder->issueType->name ?? '') == '快递丢件'){
+            $this->logService->createLog($workOrder,'处理','货主填充数据');
+            $workOrder->changeStatus('宝时处理');
+        }
+        $workOrder->loadDefaultWith();
+        return ['success' => true, 'data' => $workOrder];
     }
 
     /**
-     * Update the specified resource in storage.
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @param  \App\WorkOrderCommodities  $workOrderCommodities
-     * @return \Illuminate\Http\Response
+     * 承运商 填充 商品信息
+     * @param Request $request
+     * @return array
      */
-    public function update(Request $request, WorkOrderCommodities $workOrderCommodities)
+    public function logisticUpdateCommoditiesApi(Request $request): array
     {
-        //
+        if (Gate::denies('订单管理-工单处理-承运商编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        $workOrder = $this->workOrderService->find($request->input('id'));
+        $detail = $this->detailService->find($request->input('detail_id'));
+
+        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
+
+        $this->service->updateWorkOrderCommoditiesByJsonArray($detail, $request->input('commodities'));
+
+
+        $issueType = $workOrder->issueType->name ?? '';
+        if (in_array($issueType,['破损','快递异常'])){
+            $workOrder->changeStatus('宝时终审');
+            $detail->changeStatus('宝时终审');
+            $this->logService->createLog($detail,'处理','承运商处理');
+        } else if (in_array($issueType,['拦截','信息更改'])){
+            $workOrder->changeStatus('完成');
+            $this->logService->createLog($detail,'完结','承运商完成');
+            $this->detailService->endDetail($detail);
+        }
+
+        $workOrder->loadDefaultWith();
+
+        return ['success' => true, 'data' => $workOrder];
     }
 
     /**
-     * Remove the specified resource from storage.
-     *
-     * @param  \App\WorkOrderCommodities  $workOrderCommodities
-     * @return \Illuminate\Http\Response
+     * 宝时 填充工单信息
+     * @param Request $request
+     * @return array
      */
-    public function destroy(WorkOrderCommodities $workOrderCommodities)
+    public function baoShiUpdateCommoditiesApi(Request $request): array
     {
-        //
+        if (Gate::denies('订单管理-工单处理-宝时编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        $workOrder = $this->workOrderService->find($request->input('id'));
+        $detail = $this->detailService->find($request->input('detail_id'));
+
+        if (!$workOrder || !$detail) return ['success' => false, 'message' => '参数异常'];
+
+        $issue_type = $workOrder->issueType->name ?? '';
+
+        $this->service->updateWorkOrderCommoditiesByJsonArray($detail, $request->input('commodities'),'完结',true);
+
+        if ($issue_type == '错漏发') {
+            $workOrder->changeStatus('完成');
+            $this->detailService->endDetail($detail);
+        }
+
+        $workOrder->loadDefaultWith();
+
+        return ['success' => true, 'data' => $workOrder];
     }
 }

+ 77 - 146
app/Http/Controllers/WorkOrderController.php

@@ -9,6 +9,7 @@ use App\OrderIssue;
 use App\Services\OrderService;
 use App\Services\OwnerService;
 use App\Services\WorkOrderCommoditiesService;
+use App\Services\WorkOrderDetailService;
 use App\Services\WorkOrderLogService;
 use App\Services\WorkOrderService;
 use App\WorkOrder;
@@ -21,28 +22,26 @@ class WorkOrderController extends Controller
     /**
      * @var WorkOrderService $service
      * @var WorkOrderCommoditiesService $commoditiesService
+     * @var WorkOrderDetailService $detailService
      * @var WorkOrderLogService $logService
      * @var OrderService $orderService
      * @var OwnerService $ownerService
      */
     public $service;
+    public $detailService;
     public $commoditiesService;
     public $logService;
     public $orderService;
     public $ownerService;
 
-    public function __construct(
-        WorkOrderService $service,
-        WorkOrderCommoditiesService $commoditiesService,
-        WorkOrderLogService $logService,
-        OrderService $orderService,
-        OwnerService $ownerService)
+    public function __construct()
     {
-        $this->service = $service;
-        $this->commoditiesService = $commoditiesService;
-        $this->logService = $logService;
-        $this->orderService = $orderService;
-        $this->ownerService = $ownerService;
+        $this->service = app(WorkOrderService::class);
+        $this->detailService = app('WorkOrderDetailService');
+        $this->commoditiesService = app(WorkOrderCommoditiesService::class);
+        $this->logService = app(WorkOrderLogService::class);
+        $this->orderService = app(OrderService::class);
+        $this->ownerService = app(OwnerService::class);
     }
 
     public function index(Request $request, WorkOrderFilters $filters)
@@ -62,33 +61,11 @@ class WorkOrderController extends Controller
         return view('order.workOrder.index', compact('workOrders', 'logistics', 'orderIssueTypes', 'owners'));
     }
 
-    // 审核 api
-    public function reviewApi(Request $request): array
-    {
-        if (Gate::denies('订单管理-工单处理-审核')) return ['success' => false, 'message' => '没有对应的编辑权限'];
-
-        $workOrder = WorkOrder::query()->find($request['id']);
-
-        return $this->service->review($workOrder);
-    }
-
-    // 批量审核 api
-    public function batchReviewApi(Request $request): array
-    {
-        if (Gate::denies('订单管理-工单处理-审核')) {
-            return ['success' => false, 'message' => '没有对应的编辑权限'];
-        }
-
-        if (WorkOrder::query()->whereIn('id', $request['ids'])->whereNotNull('review_at')->exists())
-            return ['success' => false, 'message' => '选中的工单已有审核完成,刷新页面重试'];
-
-        $work_orders = WorkOrder::query()->whereIn('id', $request['ids'])->get();
-
-        $this->service->tags($work_orders);
-
-        return $this->service->batchReview($work_orders);
-    }
-
+    /**
+     * 工单生成问题件
+     * @param Request $request
+     * @return array
+     */
     public function buildOrderIssueApi(Request $request): array
     {
         if (Gate::denies('订单管理-订单问题件生成'))
@@ -115,6 +92,12 @@ class WorkOrderController extends Controller
         return ['success' => true, 'data' => $workOrders];
     }
 
+    /**
+     * 创建工单
+     * @param Request $request
+     * @return array
+     * @throws \Illuminate\Contracts\Container\BindingResolutionException
+     */
     public function storeApi(Request $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
@@ -127,6 +110,11 @@ class WorkOrderController extends Controller
         return $this->service->build($params);
     }
 
+    /**
+     * 拦截工单
+     * @param WorkOrderRequest $request
+     * @return array|bool[]
+     */
     public function interceptApi(WorkOrderRequest $request):array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
@@ -144,6 +132,11 @@ class WorkOrderController extends Controller
         return ['success' => true];
     }
 
+    /**
+     * 信息更改 工单
+     * @param WorkOrderRequest $request
+     * @return array|bool[]
+     */
     public function informationChangeApi(WorkOrderRequest $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
@@ -156,6 +149,11 @@ class WorkOrderController extends Controller
         return ['success' => true];
     }
 
+    /**
+     * 快递丢件 工单
+     * @param WorkOrderRequest $request
+     * @return array|bool[]
+     */
     public function lossApi(WorkOrderRequest $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
@@ -170,6 +168,11 @@ class WorkOrderController extends Controller
         return ['success' => true];
     }
 
+    /**
+     * 破损工单
+     * @param WorkOrderRequest $request
+     * @return array|bool[]|false[]
+     */
     public function damagedApi(WorkOrderRequest $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
@@ -179,11 +182,15 @@ class WorkOrderController extends Controller
 
         $workOrder = $this->service->createDamagedWorkOrder($request->all());
 
-
         if ($workOrder) return ['success' => true];
         else return ['success' => false];
     }
 
+    /**
+     * 快递异常
+     * @param Request $request
+     * @return array|bool[]
+     */
     public function expressAbnormalApi(Request $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
@@ -196,6 +203,11 @@ class WorkOrderController extends Controller
         return ['success' => true];
     }
 
+    /**
+     * 错漏发
+     * @param Request $request
+     * @return array|bool[]
+     */
     public function mistakeApi(Request $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
@@ -208,6 +220,11 @@ class WorkOrderController extends Controller
         return ['success' => true];
     }
 
+    /**
+     * 填充丢件
+     * @param Request $request
+     * @return array
+     */
     public function fillLossApi(Request $request): array
     {
         if (Gate::denies('订单管理-订单-宝时编辑') || Gate::denies('订单管理-订单-货主编辑')){
@@ -215,6 +232,7 @@ class WorkOrderController extends Controller
         }
 
         $workOrder = $this->service->find($request->input('id'));
+        $detail = $this->detailService->find($request->input('detail_id'));
 
         $this->service->fillLossWorkOrder($workOrder,$request->all());
 
@@ -223,18 +241,22 @@ class WorkOrderController extends Controller
         return ['success' => true,'data' => $workOrder];
     }
 
+    /**
+     * 商家填充丢件信息
+     * @param Request $request
+     * @return array
+     */
     public function updateLossApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-货主编辑'))
             return ['success' => false, 'message' => '没有对应权限'];
 
         $workOrder = $this->service->find($request->input('id'));
+        $detail = $this->detailService->find($request->input('detail_id'));
 
-        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
-
-        $workOrder = $this->service->fillLossWorkOrder($workOrder, $request->all());
+        if (!$workOrder || !$detail) return ['success' => false, 'message' => '参数错误,刷新重试'];
 
-        if (!$workOrder) return ['success' => false, 'message' => '创建异常'];
+        $workOrder = $this->service->fillLossWorkOrder($workOrder, $detail,$request->all());
 
         $workOrder->loadDefaultWith();
 
@@ -281,132 +303,41 @@ class WorkOrderController extends Controller
         return ['success' => true];
     }
 
-    public function updateWorkOrderStatusApi(Request $request): array
-    {
-        if (Gate::denies('订单管理-工单处理-宝时编辑'))
-            return ['success' => false, 'message' => '没有对应权限'];
-        try {
-            $workOrder = $this->service->find($request->input('id'));
-
-            $workOrder->work_order_status = $request['work_order_status'];
-
-            $workOrder->update();
-        } catch (\Exception $e) {
-            return ['success' => false, 'message' => '编辑工单状态失败'];
-        }
-        return ['success' => true];
-    }
-
-    public function logisticUpdateWorkOrderStatusApi(Request $request): array
-    {
-        if (Gate::denies('订单管理-工单处理-承运商编辑'))
-            return ['success' => false, 'message' => '没有对应权限'];
-        try {
-            $workOrder = $this->service->find($request->input('id'));
-
-            $workOrder->work_order_status = $request['work_order_status'];
-
-            $workOrder->update();
-        } catch (\Exception $e) {
-            return ['success' => false, 'message' => '编辑工单状态失败'];
-        }
-        return ['success' => true];
-    }
-
-    public function ownerUpdateCommoditiesApi(Request $request): array
-    {
-        if (Gate::denies('订单管理-工单处理-货主编辑')) {
-            return ['success' => false, 'message' => '没有对应权限'];
-        }
-
-        $workOrder = $this->service->find($request->input('id'));
-
-        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
-
-        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder, $request->input('commodities'));
-
-        if(($workOrder->issueType->name ?? '') == '快递丢件'){
-            $this->logService->createLog($workOrder,'处理','货主填充数据');
-            $workOrder->changeStatus('宝时处理');
-        }
-
-        $workOrder->loadDefaultWith();
-
-        return ['success' => true, 'data' => $workOrder];
-    }
-
-    public function logisticUpdateCommoditiesApi(Request $request): array
+    public function logisticEndApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-承运商编辑')) {
             return ['success' => false, 'message' => '没有对应权限'];
         }
-        $workOrder = $this->service->find($request->input('id'));
-
-        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
-
-        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder, $request->input('commodities'));
-
-        $workOrder->loadDefaultWith();
-        $issueType = $workOrder->issueType->name ?? '';
-        if (in_array($issueType,['破损','快递异常','快递丢件'])){
-            $workOrder->changeStatus('宝时终审');
-            $this->logService->createLog($workOrder,'处理','承运商处理');
-
-        } else if (in_array($issueType,['拦截','信息更改'])){
-            $workOrder->changeStatus('完成');
-            $this->logService->createLog($workOrder,'完结','承运商完成');
-        }
 
-
-        return ['success' => true, 'data' => $workOrder];
-    }
-
-    public function baoShiUpdateCommoditiesApi(Request $request): array
-    {
-        if (Gate::denies('订单管理-工单处理-宝时编辑')) {
-            return ['success' => false, 'message' => '没有对应权限'];
-        }
         $workOrder = $this->service->find($request->input('id'));
 
-        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
-
-        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder, $request->input('commodities'));
-
-        $workOrder->loadDefaultWith();
-
-        if (($workOrder->issueType->name ?? '') === '错漏发') {
-            $workOrder->changeStatus('完成');
-            $this->logService->createLog($workOrder, '完结', '错漏发完结');
-        }
-
-        return ['success' => true, 'data' => $workOrder];
-    }
-
-    public function logisticEndApi(Request $request): array
-    {
-        if (Gate::denies('订单管理-工单处理-承运商编辑')) {
-            return ['success' => false, 'message' => '没有对应权限'];
-        }
-        $workOrder = $this->service->find($request->input('id'));
+        $detail = $this->detailService->find($request->input('detail_id'));
 
-        if (!$workOrder) return ['success' => false, 'message' => '参数错误,刷新重试'];
+        if (!$workOrder || !$detail) return ['success' => false, 'message' => '参数错误,刷新重试'];
 
-        $this->service->logisticEnd($workOrder);
+        $this->service->logisticEnd($workOrder,$detail);
 
         $workOrder->loadDefaultWith();
 
         return ['success' => true, 'data' => $workOrder];
     }
 
+    /**
+     * 宝时终审
+     * @param Request $request
+     * @return array
+     */
     public function baoShiReviewApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-客服编辑')) {
             return ['success' => false, 'message' => '没有对应权限'];
         }
         $workOrder = $this->service->find($request->input('id'));
+        $detail = $this->detailService->find($request->input('detail_id'));
 
-        $this->service->baoShiReview($workOrder,$request->input('commodities'));
+        if (!$workOrder || !$detail) return ['success' => false, 'message' => '参数异常'];
 
+        $this->service->baoShiReview($workOrder,$detail,$request->input('commodities'));
         $workOrder->loadDefaultWith();
 
         return ['success' => true,'data' => $workOrder];

+ 0 - 35
app/Http/Controllers/WorkOrderProcessLogController.php

@@ -10,40 +10,5 @@ use Illuminate\Support\Facades\Gate;
 
 class WorkOrderProcessLogController extends Controller
 {
-    public function logisticStoreApi(Request $request, WorkOrderProcessLogService $service): array
-    {
-        if (Gate::denies('订单管理-工单处理-承运商编辑')) return ['success' => false, 'message' => '没有对应的编辑权限'];
-        if ($service->hasLogisticProcessLog($request->input('work_order_id'))) {
-            return ['success' => false, 'message' => '对应处理日志已存在'];
-        }
-        try {
-            $log = $service->createLogisticProcessLog($request->all());
-            $log->workOrder()->update(['work_order_status'=>'3']);
-            return ['success' => true, 'data' => $log];
-        } catch (\Exception $e) {
-            return ['success' => false, 'message' => '添加处理信息失败'];
-        }
-    }
 
-    public function storeApi(Request $request, WorkOrderProcessLogService $service): array
-    {
-        if (Gate::denies('订单管理-工单处理-宝时编辑')) return ['success' => false, 'message' => '没有对应的编辑权限'];
-
-        if ($service->hasBaoShiProcessLog($request->input('work_order_id'))) {
-            return ['success' => false, 'message' => '对应处理日志已存在'];
-        }
-        $log = $service->createBaoShiProcessLog($request->all());
-        return ['success' => true, 'data' => $log];
-    }
-
-    public function updateApi(Request $request): array
-    {
-        $log = WorkOrderProcessLog::query()
-            ->where('id', $request->input('id'))->first();
-
-        $params = $request->all();
-        $params['creator_id'] = Auth::user()['id'];
-        $log->update($params);
-        return ['success' => true, 'data' => $log];
-    }
 }

+ 1 - 1
app/Services/CommodityService.php

@@ -319,7 +319,7 @@ class CommodityService
         $inner_params = [];
         $created_at = new Carbon();
         $basSku->each(function ($bas_sku) use (&$inner_params, $owner, $created_at) {
-            $inner_params = [
+            $inner_params[] = [
                 'owner_id' => $owner->id,
                 'sku' => $bas_sku->sku,
                 'name' => $bas_sku->descr_c,

+ 5 - 0
app/Services/OrderIssueService.php

@@ -463,5 +463,10 @@ class OrderIssueService
             else $orderIssue->is_work_order = false;
         }
     }
+
+    public function batchUpdateFinalStatus($ids,$status)
+    {
+        OrderIssue::query()->whereIn('id',$ids)->update(['final_status'=>$status]);
+    }
 }
 

+ 5 - 3
app/Services/OrderPackageCommoditiesService.php

@@ -542,6 +542,8 @@ class OrderPackageCommoditiesService
         foreach ($orderHeaders as $orderHeader) {
             $order_no = $orderHeader->orderno;
             $actAllocationDetails = $orderHeader->actAllocationDetails ?? [];
+            $logistic_number = null;
+            if (in_array($orderHeader['userdefine1'],['WPSFSY', 'JDKD'])) $logistic_number= $orderHeader['soreference5'];
             if($orderHeader['sostatus'] == '90'){
                 $logistic_number = $orderHeader['soreference5'];
                 if($logistic_number == '' ) $logistic_number= $orderHeader['orderno'];
@@ -562,8 +564,8 @@ class OrderPackageCommoditiesService
                     }
                 });
             }else{
-                $actAllocationDetails->each(function($item)use(&$params,$order_no){
-                    $logistic_number = $item->picktotraceid;
+                $actAllocationDetails->each(function($item)use(&$params,$order_no,$logistic_number){
+                    $logistic_number = $logistic_number ?? $item->picktotraceid;
                     $sku = $item->sku;
                     $key = ' orderno='.$order_no.' logsitic_number='.$logistic_number.' sku='.$sku.' ';
                     if(isset($params[$key])){
@@ -571,7 +573,7 @@ class OrderPackageCommoditiesService
                     }else{
                         $params[$key] = [
                             'orderno'=>$item->orderno,
-                            'logistic_number'=>$item->picktotraceid,
+                            'logistic_number'=>$logistic_number,
                             'sku' => $sku,
                             'amount' => $item->qty_each,
                             'owner_code' => $item->customerid

+ 40 - 10
app/Services/WorkOrderCommoditiesService.php

@@ -5,6 +5,7 @@ namespace App\Services;
 use App\Traits\ServiceAppAop;
 use App\WorkOrder;
 use App\WorkOrderCommodities;
+use App\WorkOrderDetail;
 
 class WorkOrderCommoditiesService
 {
@@ -12,50 +13,79 @@ class WorkOrderCommoditiesService
 
     protected $modelClass = WorkOrderCommodities::class;
 
-    public function createWorkOrderCommodityByJson(WorkOrder $workOrder, $json)
+    public function createWorkOrderCommodityByJson(WorkOrderDetail $detail, $json)
     {
         $obj = json_decode($json);
-        $workOrder->commodities()->create([
+        $detail->commodities()->create([
+            'work_order_id' => $detail->work_order_id ?? '',
+            'work_order_detail_id' =>$detail->id ?? '',
             'commodity_id' => $obj->commodity_id ?? '',
             'sku' => $obj->sku,
             'amount' => $obj->amount ?? '',
+            'price' => $obj->price ?? '',
             'logistic_number' => $obj->logistic_number ?? '',
             'abnormal_amount' => $obj->abnormal_amount ?? '',
             'check_amount' => $obj->check_amount ?? '',
             'bao_shi_check_amount' => $obj->bao_shi_check_amount ?? '',
             'check_result' => $obj->check_result ?? '',
-            'process_result' => $commodity->process_result ?? '',
+            'process_result' => $obj->process_result ?? '',
+            'abnormal_type' => $obj->abnormal_type ?? '',
+            'issue_type' => $detail->order_issue_type_id ?? '',
         ]);
     }
 
     /**
      * 工单详情
-     * @param $workOrder $workOrder
+     * @param WorkOrderDetail $detail
      * @param $array
      */
-    public function createWorkOrderCommoditiesByJsonArray(WorkOrder $workOrder, $array)
+    public function createWorkOrderCommoditiesByJsonArray(WorkOrderDetail $detail, $array)
     {
         foreach ($array as $json) {
-            $this->createWorkOrderCommodityByJson($workOrder, $json);
+            $this->createWorkOrderCommodityByJson($detail, $json);
         }
     }
 
-    public function updateWorkOrderCommoditiesByJsonArray(WorkOrder $workOrder, $array)
+    /**
+     * @param WorkOrderDetail $detail
+     * @param $array
+     */
+    public function updateWorkOrderCommoditiesByJsonArray(WorkOrderDetail $detail, $array)
     {
         foreach ($array as $json) {
-            $this->updateWorkOrderCommoditiesByJson($workOrder, $json);
+            $this->updateWorkOrderCommoditiesByJson($detail, $json);
         }
     }
 
-    public function updateWorkOrderCommoditiesByJson(WorkOrder $workOrder, $json)
+    /**
+     * @param WorkOrderDetail $detail
+     * @param $json
+     */
+    public function updateWorkOrderCommoditiesByJson(WorkOrderDetail $detail, $json)
     {
         $obj = json_decode($json);
-        $workOrder->commodities()->where('id', $obj->id)->update([
+        $detail->commodities()->where('id', $obj->id)->update([
             'check_amount' => $obj->check_amount ?? '',
             'bao_shi_check_amount' => $obj->bao_shi_check_amount ?? '',
             'check_result' => $obj->check_result ?? '',
             'process_result' => $obj->process_result ?? '',
+            'process_result_info' => $obj->process_result_info ?? '',
         ]);
     }
 
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function undoneTag(WorkOrderDetail $detail)
+    {   // 标记为未完成历史标记
+        $detail->commodities()->update(['tag' => 2]);
+    }
+
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function endDetail(WorkOrderDetail $detail)
+    {    // 标记为完成
+        $detail->commodities()->update(['tag' => 1]);
+    }
 }

+ 95 - 4
app/Services/WorkOrderDetailService.php

@@ -2,7 +2,8 @@
 
 namespace App\Services;
 
- use App\Traits\ServiceAppAop;
+use App\Traits\ServiceAppAop;
+use App\WorkOrder;
 use App\WorkOrderDetail;
 
 class WorkOrderDetailService
@@ -10,11 +11,101 @@ class WorkOrderDetailService
     use ServiceAppAop;
     protected $modelClass=WorkOrderDetail::class;
 
-    public function createWorkOrderDetail($workOrder,$params)
+    /**
+     * @var WorkOrderCommoditiesService $commodityService
+     * @var WorkOrderImageService $imageService
+     * @var WorkOrderLogService $logService
+     */
+    private $commodityService;
+    private $imageService;
+    private $logService;
+
+    public function __construct()
+    {
+        $this->commodityService =  app(WorkOrderCommoditiesService::class);
+        $this->imageService = app(WorkOrderImageService::class);
+        $this->logService = app(WorkOrderLogService::class);
+    }
+
+    public function createWorkOrderDetail(WorkOrder $workOrder,$params): WorkOrderDetail
     {
         $param  = (new WorkOrderDetail($params))->getAttributes();
-        $workOrder->details()->create($param);
-        $workOrder->loadMissing('details');
+
+        $param['order_issue_type_id'] = $workOrder['order_issue_type_id'];
+        $param['remark'] = $workOrder['remark'];
+
+        $detail = $workOrder->details()->create($param);
+
+        $this->commodityService->createWorkOrderCommoditiesByJsonArray($detail, $params['commodities'] ?? []);
+
+        $this->imageService->createWorkOrderImages($detail,$params);
+
+        return $detail;
+    }
+
+    /**
+     * 填充丢件工单信息
+     * @param WorkOrderDetail $detail
+     * @param $params
+     */
+    public function fillLossDetail(WorkOrderDetail $detail,$params)
+    {
+        $param = (new WorkOrderDetail($params))->getAttributes();
+
+        $detail->update($param);
+
+        $this->imageService->createWorkOrderImages($detail, $params);                                                   // 图片信息
+
+        $this->commodityService->createWorkOrderCommoditiesByJsonArray($detail, $params['commodities'] ?? []);          // 商品信息
+
+        $this->logService->createLog($detail, '处理', '填充丢件信息');                                                    // 创建日志
+    }
+
+    /**
+     * @param $id
+     * @return WorkOrderDetail
+     */
+    public function find($id):WorkOrderDetail
+    {
+        /** @var WorkOrderDetail $item */
+        $item = WorkOrderDetail::query()->where('id', $id)->first();
+        return $item;
+    }
+
+
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function undoneTag(WorkOrderDetail $detail)
+    {   // 标记为未完成历史标记
+        $detail->undoneTag();
+        $this->commodityService->undoneTag($detail);
+        $this->imageService->undoneTag($detail);
+        $this->logService->undoneTag($detail);
+    }
+
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function endDetail(WorkOrderDetail $detail)
+    {
+        // 标记为完成
+        $detail->end();
+        $this->commodityService->endDetail($detail);
+        $this->imageService->endDetail($detail);
+        $this->logService->endDetail($detail);
+    }
+
+    /**
+     * @param WorkOrder $workOrder
+     */
+    public function undoneTagsByWorkOrder(WorkOrder $workOrder)
+    {
+        foreach ($workOrder->details ?? [] as $detail){
+            if ($detail->tag !== '完成' && $detail->tag !== '标记'){
+                $this->undoneTag($detail);
+            }
+        }
     }
 
 }

+ 64 - 44
app/Services/WorkOrderImageService.php

@@ -3,121 +3,141 @@
 namespace App\Services;
 
 use App\Traits\ServiceAppAop;
+use App\WorkOrder;
+use App\WorkOrderDetail;
 use App\WorkOrderImage;
 use Illuminate\Http\UploadedFile;
 
 class WorkOrderImageService
 {
     use ServiceAppAop;
-    protected $modelClass=WorkOrderImage::class;
+
+    protected $modelClass = WorkOrderImage::class;
 
     /**
      * 外包装
-     * @param $workOrder
+     * @param WorkOrderDetail $detail
      * @param $images
      */
-    public function createWorkOrderPackageImages($workOrder,$images)
+    public function createWorkOrderPackageImages(WorkOrderDetail $detail, $images)
     {
         foreach ($images as $image) {
-           $this->createWorkOrderPackageImage($workOrder,$image);
+            $this->createWorkOrderPackageImage($detail, $image);
         }
-     }
+    }
 
     /**
-     * @param $workOrder
+     * @param WorkOrderDetail $detail
      * @param $image
      */
-    public function createWorkOrderPackageImage($workOrder,$image)
+    public function createWorkOrderPackageImage(WorkOrderDetail $detail, $image)
     {
-        /** @var UploadedFile  $image */
-        $count = $workOrder->images()->where('type',1)->count();
+        /** @var UploadedFile $image */
+        $count = $detail->images()->where('type', 1)->count();
         /** @var WorkOrderImage $workOrderImage */
-        $workOrderImage = $workOrder->images()->create(['type' => 1, 'number' => ++$count]);
+        $workOrderImage = $detail->images()->create(['type' => 1, 'number' => ++$count]);
         $workOrderImage->saveFile($image);
     }
 
     /**
      * 工单商品
-     * @param $workOrder
+     * @param WorkOrderDetail $detail
      * @param $images
      */
-    public function createWorkOrderCommodityImages($workOrder,$images)
+    public function createWorkOrderCommodityImages(WorkOrderDetail $detail, $images)
     {
         foreach ($images as $image) {
-            $this->createWorkOrderCommodityImage($workOrder,$image);
+            $this->createWorkOrderCommodityImage($detail, $image);
         }
-     }
+    }
 
     /**
-     * @param $workOrder
+     * @param WorkOrderDetail $detail
      * @param $image
      */
-    public function createWorkOrderCommodityImage($workOrder,$image)
+    public function createWorkOrderCommodityImage(WorkOrderDetail $detail, $image)
     {
-        /** @var UploadedFile  $image */
-        $count = $workOrder->images()->where('type',2)->count();
+        /** @var UploadedFile $image */
+        $count = $detail->images()->where('type', 2)->count();
         /** @var WorkOrderImage $workOrderImage */
-        $workOrderImage = $workOrder->images()->create(['type' => 2, 'number' => ++$count]);
+        $workOrderImage = $detail->images()->create(['type' => 2, 'number' => ++$count]);
         $workOrderImage->saveFile($image);
     }
 
     /**
      * 交易截图
-     * @param $workOrder
+     * @param WorkOrderDetail $detail
      * @param $images
      */
-    public function createWorkOrderDealImages($workOrder,$images)
+    public function createWorkOrderDealImages(WorkOrderDetail $detail, $images)
     {
         foreach ($images as $image) {
-            $this->createWorkOrderDealImage($workOrder,$image);
+            $this->createWorkOrderDealImage($detail, $image);
         }
-     }
+    }
 
-    public function createWorkOrderDealImage($workOrder,$image)
+    public function createWorkOrderDealImage(WorkOrderDetail $detail, $image)
     {
-        /** @var UploadedFile  $image */
-        $count = $workOrder->images()->where('type',3)->count();
+        /** @var UploadedFile $image */
+        $count = $detail->images()->where('type', 3)->count();
         /** @var WorkOrderImage $workOrderImage */
-        $workOrderImage = $workOrder->images()->create(['type' => 3, 'number' => ++$count]);
+        $workOrderImage = $detail->images()->create(['type' => 3, 'number' => ++$count]);
         $workOrderImage->saveFile($image);
     }
 
     /**
      * 退款截图
-     * @param $workOrder
+     * @param WorkOrderDetail $detail
      * @param $images
      */
-    public function createWorkOrderRefundImages($workOrder, $images)
+    public function createWorkOrderRefundImages(WorkOrderDetail $detail, $images)
     {
         foreach ($images as $image) {
-            $this->createWorkOrderRefundImage($workOrder,$image);
+            $this->createWorkOrderRefundImage($detail, $image);
         }
-     }
+    }
 
-    public function createWorkOrderRefundImage($workOrder,$image)
+    public function createWorkOrderRefundImage(WorkOrderDetail $detail, $image)
     {
-        /** @var UploadedFile  $image */
-        $count = $workOrder->images()->where('type',4)->count();
+        /** @var UploadedFile $image */
+        $count = $detail->images()->where('type', 4)->count();
         /** @var WorkOrderImage $workOrderImage */
-        $workOrderImage = $workOrder->images()->create(['type' => 4, 'number' => ++$count]);
+        $workOrderImage = $detail->images()->create(['type' => 4, 'number' => ++$count]);
         $workOrderImage->saveFile($image);
     }
 
 
-    public function createImages($workOrder,$package_images = null,$commodity_images = null,$deal_images = null,$refund_images = null)
+    public function createImages(WorkOrderDetail $detail, $package_images = null, $commodity_images = null, $deal_images = null, $refund_images = null)
     {
-        if ($package_images) $this->createWorkOrderPackageImages($workOrder,$package_images);
-        if ($commodity_images) $this->createWorkOrderCommodityImages($workOrder,$commodity_images);
-        if ($deal_images) $this->createWorkOrderDealImages($workOrder,$deal_images);
-        if ($refund_images) $this->createWorkOrderRefundImages($workOrder,$refund_images);
+        if ($package_images) $this->createWorkOrderPackageImages($detail, $package_images);
+        if ($commodity_images) $this->createWorkOrderCommodityImages($detail, $commodity_images);
+        if ($deal_images) $this->createWorkOrderDealImages($detail, $deal_images);
+        if ($refund_images) $this->createWorkOrderRefundImages($detail, $refund_images);
     }
 
-    public function createWorkOrderImages($workOrder,$params)
+    public function createWorkOrderImages(WorkOrderDetail $detail, $params)
     {
-        $package_images=  $params['packageImages'] ?? [];
+        $package_images = $params['packageImages'] ?? [];
         $commodity_images = $params['commodityImages'] ?? [];
-        $deal_images  = $params['dealImages'] ?? [];
+        $deal_images = $params['dealImages'] ?? [];
         $refund_images = $params['refundImages'] ?? [];
-        $this->createImages($workOrder,$package_images,$commodity_images,$deal_images,$refund_images);
+        $this->createImages($detail, $package_images, $commodity_images, $deal_images, $refund_images);
+    }
+
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function undoneTag(WorkOrderDetail $detail)
+    {   // 标记为未完成历史标记
+        $detail->images()->update(['tag' => 2]);
     }
+
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function endDetail(WorkOrderDetail $detail)
+    {    // 标记为完成
+        $detail->images()->update(['tag' => 1]);
+    }
+
 }

+ 28 - 3
app/Services/WorkOrderLogService.php

@@ -4,6 +4,7 @@ namespace App\Services;
 
 use App\Traits\ServiceAppAop;
 use App\WorkOrder;
+use App\WorkOrderDetail;
 use App\WorkOrderLog;
 use Illuminate\Support\Facades\Auth;
 
@@ -13,16 +14,40 @@ class WorkOrderLogService
 
     protected $modelClass = WorkOrderLog::class;
 
-    public function createLog(WorkOrder $workOrder, $type, $content)
+    /**
+     * @param WorkOrderDetail $detail
+     * @param $type
+     * @param $content
+     */
+    public function createLog(WorkOrderDetail $detail, $type, $content)
     {
         $user = Auth::user();
         $log = new WorkOrderLog([
-            'work_order_id' => $workOrder->id,
+            'work_order_id' => $detail->work_order_id ?? '',
+            'work_order_detail_id' => $detail->id ?? '',
             'type' => $type,
             'creator_id' => $user['id'] ?? '',
-            'content' => $content
+            'content' => $content,
+            'tag' => 0,
         ]);
         $log->save();
     }
 
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function undoneTag(WorkOrderDetail $detail)
+    {   // 标记为未完成历史标记
+        $detail->logs()->update(['tag' => 2]);
+    }
+
+    /**
+     * @param WorkOrderDetail $detail
+     */
+    public function endDetail(WorkOrderDetail $detail)
+    {    // 标记为完成
+        $detail->logs()->update(['tag' => 1]);
+    }
+
+
 }

+ 91 - 62
app/Services/WorkOrderService.php

@@ -8,6 +8,7 @@ use App\OrderIssueType;
 use App\OrderPackage;
 use App\Traits\ServiceAppAop;
 use App\WorkOrder;
+use App\WorkOrderDetail;
 use App\WorkOrderProcessLog;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
@@ -36,19 +37,14 @@ class WorkOrderService
     private $issueTypeService;
     private $orderService;
 
-    public function __construct(WorkOrderLogService $logService,
-                                WorkOrderImageService $imageService,
-                                WorkOrderCommoditiesService $commoditiesService,
-                                WorkOrderDetailService $detailService,
-                                OrderIssueTypeService $issueTypeService,
-                                OrderService $orderService)
+    public function __construct()
     {
-        $this->logService = $logService;
-        $this->imageService = $imageService;
-        $this->commoditiesService = $commoditiesService;
-        $this->detailService = $detailService;
-        $this->issueTypeService = $issueTypeService;
-        $this->orderService = $orderService;
+        $this->logService = app(WorkOrderLogService::class);
+        $this->imageService = app(WorkOrderImageService::class);
+        $this->commoditiesService = app(WorkOrderCommoditiesService::class);
+        $this->detailService = app(WorkOrderDetailService::class);
+        $this->issueTypeService = app(OrderIssueTypeService::class);
+        $this->orderService = app(OrderService::class);
     }
 
     /**
@@ -86,17 +82,27 @@ class WorkOrderService
                 $this->createDamagedWorkOrder($param);
             } else if ('快递丢件' == $type_name) {
                 $this->createLossWorkOrder($param);
-            } else {
-                $this->createDefaultWorkOrder($param);
             }
         }
         return ['success' => true];
     }
 
-    public function createWorkOrder($order, $issueType, $remark)
+    public function createOrResetWorkOrder($order, $issueType, $remark)
     {
         $user = Auth::user();
-
+        $workOrder = WorkOrder::query()->where('order_id', $order->id)->orderByDesc('created_at')->first();
+        if ($workOrder) {
+
+            $this->detailService->undoneTagsByWorkOrder($workOrder);
+
+            $workOrder->update([
+                'remark' => $remark,
+                'order_issue_type_id' => $issueType->id,
+                'creator_id' => $user['id'] ?? '',
+                'status' => 0,
+            ]);
+            return $workOrder;
+        }
         return WorkOrder::query()->create([
             'order_id' => $order->id,
             'logistic_id' => $order->logistic_id ?? '',
@@ -113,7 +119,7 @@ class WorkOrderService
     public function createAndNotification($order, $orderIssueType, $remark): WorkOrder
     {
         /** @var WorkOrder $workOrder */
-        $workOrder = $this->createWorkOrder($order, $orderIssueType, $remark);
+        $workOrder = $this->createOrResetWorkOrder($order, $orderIssueType, $remark);
 
         $workOrder->notification();
 
@@ -129,13 +135,13 @@ class WorkOrderService
 
         $order = $this->orderService->first(['code' => $param['order_no']]);
 
-        $remark = $param['remark'] ?? '拦截工单';
+        $workOrder = $this->createAndNotification($order, $issueType, $param['remark'] ?? '拦截工单');
 
-        $workOrder = $this->createAndNotification($order, $issueType, $remark);
+        $detail = $this->detailService->createWorkOrderDetail($workOrder,$param);
 
         $workOrder->changeStatus('承运商处理');
 
-        $this->logService->createLog($workOrder, '创建', '创建');
+        $this->logService->createLog($detail, '创建', '创建');
 
         return $workOrder;
     }
@@ -151,10 +157,14 @@ class WorkOrderService
 
         $workOrder = $this->createAndNotification($order, $issueType, $param['remark'] ?? '');
 
-        $this->commoditiesService->createWorkOrderCommoditiesByJsonArray($workOrder, $param['commodities']);
+        $detail = $this->detailService->createWorkOrderDetail($workOrder, $param);
+
+        $this->logService->createLog($detail, '创建', '创建');
 
         $workOrder->changeStatus('宝时处理');
 
+        $detail->changeStatus('宝时处理');
+
         return $workOrder;
     }
 
@@ -169,15 +179,13 @@ class WorkOrderService
 
         $workOrder = $this->createAndNotification($order, $issueType, $param['remark'] ?? '');
 
-        $this->imageService->createWorkOrderImages($workOrder, $param);
-
-        $this->detailService->createWorkOrderDetail($workOrder, $param);
+        $detail = $this->detailService->createWorkOrderDetail($workOrder, $param);
 
-        $this->commoditiesService->createWorkOrderCommoditiesByJsonArray($workOrder, $param['commodities']); // 登记商品信息
+        $this->logService->createLog($detail, '创建', '创建工单');
 
         $workOrder->changeStatus('承运商处理');
 
-        $this->logService->createLog($workOrder, '创建', '创建工单');
+        $detail->changeStatus('宝时处理');
 
         return $workOrder;
     }
@@ -193,13 +201,13 @@ class WorkOrderService
 
         $workOrder = $this->createAndNotification($order, $issueType, $param['remark'] ?? '');
 
-        $this->imageService->createWorkOrderImages($workOrder, $param);
-
-        $this->commoditiesService->createWorkOrderCommoditiesByJsonArray($workOrder, $param['commodities']);
+        $detail = $this->detailService->createWorkOrderDetail($workOrder, $param);
 
         $workOrder->changeStatus('承运商处理');
 
-        $this->logService->createLog($workOrder, '创建', '创建工单');
+        $detail->changeStatus('宝时处理');
+
+        $this->logService->createLog($detail, '创建', '创建工单');
 
         return $workOrder;
     }
@@ -215,23 +223,15 @@ class WorkOrderService
 
         $workOrder = $this->createAndNotification($order, $issueType, $param['remark'] ?? '');
 
-        $workOrder->changeStatus('承运商处理');
+        $detail = $this->detailService->createWorkOrderDetail($workOrder, $param);
 
-        $this->logService->createLog($workOrder, '创建', '创建工单');
-
-        return $workOrder;
-    }
+        $workOrder->changeStatus('承运商处理');
 
-    /**
-     * 其他
-     */
-    public function createDefaultWorkOrder($param): WorkOrder
-    {
-        $orderIssueType = $this->issueTypeService->firstOrCreate(['name' => '其他']);
+        $detail->changeStatus('承运商处理');
 
-        $order = $this->orderService->first(['code' => $param['order_no']]);
+        $this->logService->createLog($detail, '创建', '创建工单');
 
-        return $this->createAndNotification($order, $orderIssueType, $param['remark'] ?? '');
+        return $workOrder;
     }
 
     /**
@@ -245,9 +245,13 @@ class WorkOrderService
 
         $workOrder = $this->createAndNotification($order, $orderIssueType, $param['remark'] ?? '');
 
+        $detail = $this->detailService->createWorkOrderDetail($workOrder, $param);
+
         $workOrder->changeStatus('货主处理');
 
-        $this->logService->createLog($workOrder, '创建', '创建工单');
+        $detail->changeStatus('货主处理');
+
+        $this->logService->createLog($detail, '创建', '创建工单');
 
         return $workOrder;
     }
@@ -255,32 +259,37 @@ class WorkOrderService
     /**
      *  填充丢件信息
      */
-    public function fillLossWorkOrder(WorkOrder $workOrder, $param): WorkOrder
+    public function fillLossWorkOrder(WorkOrder $workOrder,WorkOrderDetail $detail, $params): WorkOrder
     {
-        $workOrder->saveWorkOrderDetail($param);        // 收方信息 丢件价值 补发单号
+        $this->detailService->fillLossDetail($detail,$params);
 
-        $this->imageService->createWorkOrderImages($workOrder, $param);
+        $detail->changeStatus('宝时终审');
 
-        $workOrder->changeStatus('承运商处理');
-
-        $this->logService->createLog($workOrder, '处理', '填充丢件信息');
-
-        $this->commoditiesService->createWorkOrderCommoditiesByJsonArray($workOrder, $param['commodities'] ?? '');
+        $workOrder->changeStatus('宝时终审');
 
-        return $workOrder;
+        return $this->getDefaultWith($workOrder->id);
     }
 
-    public function end(WorkOrder $workOrder)
+    /**
+     * @param WorkOrder $workOrder
+     * @param WorkOrderDetail $detail
+     */
+    public function end(WorkOrder $workOrder, WorkOrderDetail $detail)
     {
+        $this->detailService->endDetail($detail);
+        $this->logService->createLog('完结', '完结工单');
         $workOrder->end();
-
-        $this->logService->createLog($workOrder, '完结', '完结工单');
     }
 
-    public function logisticEnd(WorkOrder $workOrder)
+    /**
+     * @param WorkOrder $workOrder
+     * @param WorkOrderDetail $detail
+     */
+    public function logisticEnd(WorkOrder $workOrder, WorkOrderDetail $detail)
     {
+        $this->logService->createLog($detail,'完结', '承运商完结工单');
+        $this->detailService->endDetail($detail);
         $workOrder->changeStatus('完成');
-        $this->logService->createLog($workOrder, '完结', '承运商完结工单');
     }
 
     public function find($id): WorkOrder
@@ -290,6 +299,9 @@ class WorkOrderService
         return $item;
     }
 
+    public function getDefaultWith($id){
+        return WorkOrder::query()->defaultWith()->find($id);
+    }
 
     /**
      * 工单审核
@@ -307,15 +319,23 @@ class WorkOrderService
         return ['success' => true, 'data' => $workOrders->first()];
     }
 
-    public function baoShiReview(WorkOrder $workOrder,$params)
+    /**
+     * 终审
+     * @param WorkOrder $workOrder
+     * @param WorkOrderDetail $detail
+     * @param $params
+     */
+    public function baoShiReview(WorkOrder $workOrder,WorkOrderDetail $detail, $params)
     {
         $user = Auth::user();
 
         $workOrder->update(['reviewer_id' => $user['id'], 'review_at' => Carbon::now(), 'status' => '5']);
 
-        $this->logService->createLog($workOrder,'终审','终审完成');
+        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($detail, $params);
+
+        $this->logService->createLog($detail,'终审', '终审完成');
 
-        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder,$params);
+        $this->detailService->endDetail($detail);
     }
 
     /**
@@ -408,6 +428,10 @@ class WorkOrderService
         return WorkOrder::query()->whereIn('order_id', $package_query)->whereIn('order_issue_type_id', $order_issue_query)->exists();
     }
 
+    /**
+     * 标记工单
+     * @param $orders
+     */
     public function tagWorkOrder(&$orders)
     {
         $orderNos = data_get($orders, '*.orderno');
@@ -426,9 +450,14 @@ class WorkOrderService
         }
     }
 
+    /**
+     * 校验工单是否存在
+     * @param $nos
+     * @return mixed
+     */
     public function checkWorkOrder($nos)
     {
-        return  WorkOrder::query()->defaultWith()->whereIn('order_id', function ($query) use ($nos) {
+        return WorkOrder::query()->defaultWith()->whereIn('order_id', function ($query) use ($nos) {
             $query->from('orders')->selectRaw('id');
             if (is_array($nos))
                 $query->whereIn('code', $nos);

+ 29 - 142
app/WorkOrder.php

@@ -24,20 +24,16 @@ class WorkOrder extends Model
 
     // 工单 信息
     protected $fillable = [
-        'owner_id',      // 货主
-        'logistic_id',      // 承运商
-        'order_issue_type_id', // 问题件类型
-        'status',           // 审核状态
-        'creator_id',       // 创建人
-        'reviewer_id',      // 审核人
-        'review_at',            // 审核时间
-        'order_id',             // 订单id
-        'uniquely_tag',         // 唯一标识
-        'remark',       // 工单信息描述
-//        'work_order_type_id',  // 工单类型
-//        'grad',         // 紧急等级
-//        'outer_table_name',     // 链接表名
-//        'work_order_status', // 工单状态
+        'owner_id',                 // 货主
+        'logistic_id',              // 承运商
+        'order_issue_type_id',      // 问题件类型
+        'status',                   // 审核状态
+        'creator_id',               // 创建人
+        'reviewer_id',              // 审核人
+        'review_at',                // 审核时间
+        'order_id',                 // 订单id
+        'uniquely_tag',             // 唯一标识
+        'remark',                   // 工单信息描述
     ];
 
     static public $enums = [
@@ -49,20 +45,7 @@ class WorkOrder extends Model
             '宝时终审' => 4,
             '完成' => 5,
         ],
-//        'work_order_status' => [
-//            '' => 0,
-//            '创建' => 1,
-//            '信息已填写' => 2,
-//            '快递已处理' => 3,
-//            '工单完成' => 4,
-//        ],
-//        'grad' => [
-//            '' => 0,
-//            '一般' => 1,
-//            '重要' => 2,
-//            '紧急' => 3,
-//            '重要且紧急' => 4,
-//        ],
+
     ];
 
     function __construct(array $attributes = [])
@@ -89,38 +72,6 @@ class WorkOrder extends Model
         }
     }
 
-//    public function getWorkOrderStatusAttribute($value)
-//    {
-//        if (!$value) return '';
-//        return self::$enums['work_order_status'][$value];
-//    }
-//
-//    public function setWorkOrderStatusAttribute($value)
-//    {
-//        if (!$value) return ;
-//        if (is_numeric($value)) {
-//            $this->attributes['work_order_status'] = $value;
-//        } else {
-//            $this->attributes['work_order_status'] = self::$enums['work_order_status'][$value];
-//        }
-//    }
-//
-//    public function getGradAttribute($value)
-//    {
-//        if (!$value) return '';
-//        return self::$enums['grad'][$value];
-//    }
-//
-//    public function setGradAttribute($value)
-//    {
-//        if (!$value) return ;
-//        if (is_numeric($value)) {
-//            $this->attributes['grad'] = $value;
-//        } else {
-//            $this->attributes['grad'] = self::$enums['grad'][$value];
-//        }
-//    }
-
     // 关联订单
     public function order(): BelongsTo
     {
@@ -169,66 +120,11 @@ class WorkOrder extends Model
         return $this->belongsTo(OrderIssue::class, 'order_id', 'order_id');
     }
 
-    // 图片
-    public function images(): HasMany
-    {
-        return $this->hasMany(WorkOrderImage::class);
-    }
-
-    public function getPackageImagesAttribute()
-    {
-        return $this->images->where('type', 1);
-    }
-
-    public function getCommodityImagesAttribute()
-    {
-        return $this->images->where('type', 2);
-    }
-
-    public function getDealImagesAttribute()
-    {
-        return $this->images->where('type', 3);
-    }
-
-    public function getRefundImagesAttribute()
-    {
-        return $this->images->where('type', 4);
-    }
-
-
-    // 工单详情
     public function details(): HasMany
     {
         return $this->hasMany(WorkOrderDetail::class);
     }
 
-    // 工单商品信息
-    public function commodities(): HasMany
-    {
-        return $this->hasMany(WorkOrderCommodities::class);
-    }
-
-    // 处理日志
-    public function processLogs(): HasMany
-    {
-        return $this->hasMany(WorkOrderProcessLog::class);
-    }
-
-    public function baoShiLog()
-    {
-        return $this->processLogs->where('type', 1);
-    }
-
-    public function logisticLog()
-    {
-        return $this->processLogs->where('type', 2);
-    }
-
-    public function logs(): HasMany
-    {
-        return $this->hasMany(WorkOrderLog::class);
-    }
-
     public function scopeFilter($query, $filters)
     {
         return $filters->apply($query);
@@ -237,40 +133,31 @@ class WorkOrder extends Model
     /** 默认 with 参数 */
     public function scopeDefaultWith($query)
     {
-        $query->with(['type', 'owner', 'logistic', 'issueType', 'creator', 'details', 'commodities.commodity','logs.creator',
-            'processLogs.creator',
-            'images.uploadFile',
+        $query->with($this->defaultWith());
+    }
+
+    public function defaultWith(): array
+    {
+        return  ['type', 'owner', 'logistic', 'issueType', 'creator', 'details' => function ($query) {
+            return $query->with('commodities.commodity', 'logs.creator', 'images.uploadFile','issueType');
+        },
             'reviewer',
             'order.packages',
             'orderIssue' => function ($query) {
-                /** @var Builder $query */
-                $query->with(['issueType', 'logs' => function ($query) {
-                    if (Gate::denies('订单管理-问题件-客户不可见')) {
-                        $query->with('user')->orderByDesc('created_at');
-                    } else {
-                        $query->with('user')->where('tag', '=', 0)->orderByDesc('created_at');
-                    }
-                }]);
+            /** @var Builder $query */
+            $query->with(['issueType', 'logs' => function ($query) {
+                if (Gate::denies('订单管理-问题件-客户不可见')) {
+                    $query->with('user')->orderByDesc('created_at');
+                } else {
+                    $query->with('user')->where('tag', '=', 0)->orderByDesc('created_at');
+                }
             }]);
+        }];
     }
 
     public function loadDefaultWith()
     {
-        $this->loadMissing(['type', 'owner', 'logistic', 'issueType', 'creator', 'details', 'commodities.commodity','logs.creator',
-            'processLogs.creator',
-            'images.uploadFile',
-            'reviewer',
-            'order.packages',
-            'orderIssue' => function ($query) {
-                /** @var Builder $query */
-                $query->with(['issueType', 'logs' => function ($query) {
-                    if (Gate::denies('订单管理-问题件-客户不可见')) {
-                        $query->with('user')->orderByDesc('created_at');
-                    } else {
-                        $query->with('user')->where('tag', '=', 0)->orderByDesc('created_at');
-                    }
-                }]);
-            }]);
+        $this->loadMissing($this->defaultWith());
     }
 
     public function notification()
@@ -294,7 +181,7 @@ class WorkOrder extends Model
     // 工单完结
     public function end()
     {
-        $this->update(['status'  => 4]);
+        $this->update(['status' => 4]);
     }
 
     public function changeStatus($status)

+ 52 - 8
app/WorkOrderCommodities.php

@@ -10,22 +10,66 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
 class WorkOrderCommodities extends Model
 {
-    use ModelLogChanging;
     use ModelTimeFormat;
 
     protected $fillable = [
         'work_order_id',
+        'work_order_detail_id', // 工单详情
+        'tag',                 // 当前工单状态
         'commodity_id',
-        'sku',
+        'price',                // 商品价值
+        'sku',                  // 商品条码
         'logistic_number',      // 快递单号数量
-        'check_amount',         // 复核数量
-        'bao_shi_check_amount', // 宝时复核数量
-        'abnormal_amount',      // 异常数量
-        'amount',               // 订单数量
-        'check_result',         // 核实结果
-        'process_result',       // 处理结果
+        'check_amount',         // 承运商核实数量 (承运商核实商品数量)
+        'bao_shi_check_amount', // 宝时复核数量 (宝时核实商品数量)
+        'issue_type',           // 异常类型   (对应工单异常类型)
+        'abnormal_type',        // 问题类型  (商品问题类型)
+        'abnormal_amount',      // 异常数量  (默认为订单数量) 错漏发 (客户实收数量)
+        'amount',               // 订单数量  (原订单商品数量)
+        'check_result',         // 核实结果  (核实)
+        'process_result',       // 处理结果  终审填充(破损:[赔偿,不赔偿] 错漏发:[少发,多发,’多发,客户退回‘,’少发,不补发‘,核实未错漏发])
+        'process_result_info',  // 处理结果详情 -----------------------------------
+                                // (错漏发: string 为选项类型 与 process_result 相关
+                                //      1.【少发】宝时补发(商家不做单)
+                                //      2.【多发,客户买下】商家做出库单(物流选自提,宝时不发货)
+                                //      3.【多发,客户退回】1.客户自行退回(提供退回单号) 2.宝时上门取件(提供寄件信息,地址,联系人,电话)
+                                //      4.【少发,不补发】商家做入库单,选择明细和数量
+                                //      5.【核实未错漏发】)
+                                // -----------------------------------
     ];
 
+    static public $enums = [
+        'tag' => [
+            '' => 0,
+            '完成' => 1,
+            '标记' => 2, // 工单重新创建,未完成原始数据进行历史标记,完成原始数据不进行处理
+        ],
+    ];
+
+    function __construct(array $attributes = [])
+    {
+        foreach (self::$enums as &$enum) {
+            $enum = $enum + array_flip($enum);
+        }
+        parent::__construct($attributes);
+    }
+
+    public function getTagAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['tag'][$value];
+    }
+
+    public function setTagAttribute($value)
+    {
+        if (!$value) return;
+        if (is_numeric($value)) {
+            $this->attributes['tag'] = $value;
+        } else {
+            $this->attributes['tag'] = self::$enums['tag'][$value];
+        }
+    }
+
     public function workOrder(): BelongsTo
     {
         return $this->belongsTo(WorkOrder::class);

+ 122 - 1
app/WorkOrderDetail.php

@@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasMany;
 
 class WorkOrderDetail extends Model
 {
@@ -15,17 +16,137 @@ class WorkOrderDetail extends Model
 
     protected $fillable = [
         'work_order_id',
+        'order_issue_type_id',      // 工单异常类型
         'price',                    // 商品价值
         'sku_amount',               // 破损sku数
         'receive_address',          // 收方信息
         'reissue_logistic_number',  // 补发单号
         'return_logistic_number',   // 退回单号
-        'logistic_number',
+        'logistic_number',          // 快递单号
+        'status',                   // 当前状态
+        'remark',                   // 创建工单时的问题标记
+        'tag',                      // 标记当前工单是否为历史标记
     ];
 
+    static public $enums = [
+        'status' => [
+            '' => 0,
+            '宝时处理' => 1,
+            '货主处理' => 2,
+            '承运商处理' => 3,
+            '宝时终审' => 4,
+            '完成' => 5,
+        ],
+        'tag' => [
+            '' => 0,
+            '完成' => 1,
+            '标记' => 2,
+        ],
+    ];
+
+    function __construct(array $attributes = [])
+    {
+        foreach (self::$enums as &$enum) {
+            $enum = $enum + array_flip($enum);
+        }
+        parent::__construct($attributes);
+    }
+
+    public function getStatusAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['status'][$value];
+    }
+
+    public function setStatusAttribute($value)
+    {
+        if (!$value) return;
+        if (is_numeric($value)) {
+            $this->attributes['status'] = $value;
+        } else {
+            $this->attributes['status'] = self::$enums['status'][$value];
+        }
+    }
+
+    public function getTagAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['tag'][$value];
+    }
+
+    public function setTagAttribute($value)
+    {
+        if (!$value) return;
+        if (is_numeric($value)) {
+            $this->attributes['tag'] = $value;
+        } else {
+            $this->attributes['tag'] = self::$enums['tag'][$value];
+        }
+    }
+
     public function workOrder(): BelongsTo
     {
         return $this->belongsTo(WorkOrder::class);
     }
 
+    public function issueType(): BelongsTo
+    {
+        return $this->belongsTo(OrderIssueType::class,'order_issue_type_id');
+    }
+
+    // 图片
+    public function images(): HasMany
+    {
+        return $this->hasMany(WorkOrderImage::class);
+    }
+
+    public function getPackageImagesAttribute()
+    {
+        return $this->images->where('type', 1);
+    }
+
+    public function getCommodityImagesAttribute()
+    {
+        return $this->images->where('type', 2);
+    }
+
+    public function getDealImagesAttribute()
+    {
+        return $this->images->where('type', 3);
+    }
+
+    public function getRefundImagesAttribute()
+    {
+        return $this->images->where('type', 4);
+    }
+
+    public function logs(): HasMany
+    {
+        return $this->hasMany(WorkOrderLog::class);
+    }
+
+    public function commodities(): HasMany
+    {
+        return $this->hasMany(WorkOrderCommodities::class);
+    }
+
+    // 未完成历史标记
+    public function undoneTag(){
+        if ($this->tag != '完成'){
+            $this->update(['tag' => 2]);
+        }
+    }
+
+    // 完成标记
+    public function end(){
+        $this->status = 5;
+        $this->tag = 1;
+        $this->update();
+    }
+
+    public function changeStatus($status)
+    {
+        $this->status = $status;
+        $this->update();
+    }
 }

+ 34 - 3
app/WorkOrderImage.php

@@ -17,8 +17,16 @@ class WorkOrderImage extends Model
 
     protected $fillable = [
         'work_order_id',
-        'type',
-        'number',
+        'order_issue_type_id',  // 工单异常类型
+        'work_order_detail_id', // 工单详情
+        'type',         // 类型 ------------------------
+                        // 1: 外包装图片
+                        // 2: 内物破碎图片
+                        // 3: 交易截图
+                        // 4: 退款成功截图 ( 需带有付款时间,快递单号,内物详情和实付款的交易截图)
+                        // ------------------------
+        'number',       // 编号
+        'tag',          // 当前状态
     ];
 
     static public $enums = [
@@ -29,8 +37,14 @@ class WorkOrderImage extends Model
             '交易截图' => 3,
             '退款成功截图' => 4,
         ],
+        'tag' => [
+            '' => 0,
+            '完成' => 1,
+            '标记' => 2,
+        ],
     ];
 
+
     function __construct(array $attributes = [])
     {
         foreach (self::$enums as &$enum) {
@@ -39,7 +53,7 @@ class WorkOrderImage extends Model
         parent::__construct($attributes);
     }
 
-    public function getStatusAttribute($value)
+    public function getTypeAttribute($value)
     {
         if (!$value) return '';
         return self::$enums['type'][$value];
@@ -55,6 +69,23 @@ class WorkOrderImage extends Model
         }
     }
 
+    public function getStatusAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['status'][$value];
+    }
+
+    public function setStatusAttribute($value)
+    {
+        if (!$value) return;
+        if (is_numeric($value)) {
+            $this->attributes['status'] = $value;
+        } else {
+            $this->attributes['status'] = self::$enums['status'][$value];
+        }
+    }
+
+
     public function workOrder(): BelongsTo
     {
         return $this->belongsTo(WorkOrder::class);

+ 26 - 3
app/WorkOrderLog.php

@@ -12,7 +12,14 @@ class WorkOrderLog extends Model
 {
     use ModelTimeFormat;
 
-    protected $fillable = ['work_order_id','content','type','creator_id'];
+    protected $fillable = [
+        'work_order_id',
+        'work_order_detail_id',
+        'content',
+        'type',                     // 记录类型
+        'creator_id',               // 创建人
+        'tag',                      // 标记
+    ];
 
     static public $enums = [
         'type' => [
@@ -22,6 +29,11 @@ class WorkOrderLog extends Model
             '终审' => 3,
             '完结' => 4,
         ],
+        'tag' => [
+            '' => 0,
+            '完结' => 1,
+            '标记' => 2,
+        ],
     ];
 
     function __construct(array $attributes = [])
@@ -48,9 +60,20 @@ class WorkOrderLog extends Model
         }
     }
 
-    public function workOrder(): BelongsTo
+    public function getTagAttribute($value)
     {
-        return $this->belongsTo(WorkOrder::class);
+        if (!$value) return '';
+        return self::$enums['tag'][$value];
+    }
+
+    public function setTagAttribute($value)
+    {
+        if (!$value) return;
+        if (is_numeric($value)) {
+            $this->attributes['tag'] = $value;
+        } else {
+            $this->attributes['tag'] = self::$enums['tag'][$value];
+        }
     }
 
     public function creator(): BelongsTo

+ 6 - 0
app/WorkOrderProcessLog.php

@@ -7,6 +7,12 @@ use Illuminate\Database\Eloquent\Model;
 use App\Traits\ModelLogChanging;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
+
+/**
+ * 无用模型
+ * Class WorkOrderProcessLog
+ * @package App
+ */
 class WorkOrderProcessLog extends Model
 {
     use ModelLogChanging;

+ 44 - 0
database/migrations/2021_11_19_104807_work_order_commodity_add_issue_type.php

@@ -0,0 +1,44 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class WorkOrderCommodityAddIssueType extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_order_commodities', function (Blueprint $table) {
+            $table->integer('work_order_detail_id')->index()->comment('工单详情');
+            $table->integer('tag')->comment('历史标记');
+
+            $table->string('issue_type')->comment('商品异常类型');
+            $table->string('abnormal_type')->comment('工单异常类型');
+            $table->string('process_result_info')->index()->comment('处理结果详情');
+            $table->decimal('price')->comment('价格');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_order_commodities', function (Blueprint $table) {
+            $table->dropColumn('work_order_detail_id');
+            $table->dropColumn('tag');
+
+            $table->dropColumn('issue_type');
+            $table->dropColumn('abnormal_type');
+            $table->dropColumn('process_result_info');
+            $table->dropColumn('price');
+        });
+    }
+}

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

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class WorkOrderImagesAddColumns extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_order_images', function (Blueprint $table) {
+            $table->integer('tag')->comment('标记');
+            $table->integer('order_issue_type_id')->comment('工单异常类型');
+            $table->integer('work_order_detail_id')->index()->comment('工单详情');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_order_images', function (Blueprint $table) {
+            $table->dropColumn('tag');
+            $table->dropColumn('order_issue_type_id');
+            $table->dropColumn('work_order_detail_id');
+        });
+    }
+}

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

@@ -0,0 +1,43 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class WorkOrderDetailsAddColumns extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_order_details', function (Blueprint $table) {
+            $table->integer('order_issue_type_id')->index()->comment('工单异常类型');
+            $table->integer('status')->comment('工单状态');
+            $table->integer('tag')->comment('历史标记');
+            $table->string('remark')->nullable()->comment('工单描述');
+
+            $table->string('receive_address')->default('')->change();
+            $table->string('reissue_logistic_number')->default('')->change();
+            $table->string('return_logistic_number')->default('')->change();
+            $table->string('logistic_number')->default('')->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_order_details', function (Blueprint $table) {
+            $table->dropColumn('order_issue_type_id');
+            $table->dropColumn('status');
+            $table->dropColumn('remark');
+            $table->dropColumn('tag');
+        });
+    }
+}

+ 34 - 0
database/migrations/2021_11_22_134750_work_order_logs_add_columns.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class WorkOrderLogsAddColumns extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_order_logs', function (Blueprint $table) {
+            $table->integer('work_order_detail_id')->index()->comment('工单详情');
+            $table->integer('tag')->comment('历史标记');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_order_logs', function (Blueprint $table) {
+            $table->dropColumn('work_order_detail_id');
+            $table->dropColumn('tag');
+        });
+    }
+}

+ 42 - 12
resources/views/kpi/day/index.blade.php

@@ -12,21 +12,37 @@
                    style="background: #fff;" id="table">
                 <tr v-for="(item,i) in details.data" :key="i">
                     <td><input class="checkItem" type="checkbox" :value="item.id"></td>
+                    <td class="td-warm text-muted"><span>@{{ item.departmentName }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.statTime.slice(0,10) }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.avgOnDutyTime }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.avgOffDutyTime }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.attendanceNum }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ Math.round(item.workTimes) }}</span></td>
+
+
+                    <td class="td-warm text-muted"><span>@{{ item.deliveryGoodsNum }}</span></td>
+                    <td class="td-warm text-muted"><span>@{{ item.delayDeliveryGoodsNum }}</span></td>
+
+                    <td class="td-warm text-muted"><span>@{{ item.returnOrderNum }}</span></td>
+                    <td class="td-warm text-muted"><span>@{{ item.returnGoodsNum }}</span></td>
+                    <td class="td-warm text-muted"><span>@{{ item.returnDelayNum }}</span></td>
+
+
                     <td class="td-warm text-muted"><span>@{{ item.totalDeliveryQty }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.expressCollectQty }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.whDeliveryNum }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.transferDeliveryNum }}</span></td>
-                    <td class="td-warm text-muted"><span>@{{ item.purchaseEntryNum }}</span></td>
-                    <td class="td-warm text-muted"><span>@{{ item.transferEntryNum }}</span></td>
-                    <td class="td-warm text-muted"><span>@{{ item.returnEntryNum }}</span></td>
+
+
+                    <td class="td-warm text-muted"><span>@{{ item.purchaseStoreNum }}</span></td>
+                    <td class="td-warm text-muted"><span>@{{ item.allotStoreNum }}</span></td>
+                    <td class="td-warm text-muted"><span>@{{ item.returnStoreNum }}</span></td>
+
+
                     <td class="td-warm text-muted"><span>@{{ item.inventoryNum }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.inventoryQty }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.occupationArea }}</span></td>
+
                     <td class="td-warm text-muted"><span>@{{ item.delay24Qty }}</span></td>
                     <td class="td-warm text-muted"><span>@{{ item.delay48Qty }}</span></td>
                 </tr>
@@ -63,7 +79,7 @@
                     pages: null,
                     size: null
                 },
-                size: 10,
+                size: 50,
                 current: 1
             },
             created() {
@@ -98,9 +114,9 @@
                     let url = '';
                     let env = "{{ config('app.env') }}";
                     if (env === 'local') {
-                        url = ' http://127.0.0.1:8111'
+                        url = 'http://127.0.0.1:8111'
                     } else if (env === 'production') {
-                        url = ' http://101.133.135.193'
+                        url = 'https://stat.baoshi56.com'
                     }
                     return url;
                 },
@@ -125,20 +141,30 @@
                 },
                 rendingHeader() {
                     let column = [
+                        {name: 'department_name', value: '工作组', neglect: true, class: "td-cool"},
                         {name: 'stat_time', value: '统计日期', neglect: true, class: "td-cool"},
                         {name: 'avg_on_duty_time', value: '平均上班时间', neglect: true, class: "td-cool"},
                         {name: 'avg_off_duty_time', value: '平均下班时间', class: "td-cool"},
                         {name: 'attendance_num', value: '出勤人数', neglect: true, class: "td-cool"},
                         {name: 'work_times', value: '生产工时', class: "td-cool"},
 
+                        {name: 'delivery_goods_num', value: '收货商品数', class: "td-warm"},
+                        {name: 'delay_delivery_goods_num', value: '延迟收货数', neglect: true, class: "td-warm"},
+
+                        {name: 'return_order_num', value: '登记订单数', class: "td-cool"},
+                        {name: 'return_goods_num', value: '登记商品数', neglect: true, class: "td-cool"},
+                        {name: 'return_delay_num', value: '延迟登记数', class: "td-cool"},
+
                         {name: 'total_delivery_qty', value: '总发货量', class: "td-warm"},
                         {name: 'express_collect_qty', value: '快递揽收数量', neglect: true, class: "td-warm"},
                         {name: 'wh_delivery_num', value: '仓库发货个数', class: "td-warm"},
                         {name: 'transfer_delivery_num', value: '调拨出库总个数', class: "td-warm"},
 
-                        {name: 'purchase_entry_num', value: '采购入库数', class: "td-cool"},
-                        {name: 'transfer_entry_num', value: '调拨入库数', class: "td-cool"},
-                        {name: 'return_entry_num', value: '退货入库数', class: "td-cool"},
+
+                        {name: 'purchase_store_num', value: '采购入库数', class: "td-cool"},
+                        {name: 'allot_store_num', value: '调拨入库数', neglect: true, class: "td-cool"},
+                        {name: 'return_store_num', value: '退件入库数', class: "td-cool"},
+
 
                         {name: 'inventory_num', value: '盘点库位数', class: "td-warm"},
                         {name: 'inventory_qty', value: '盘点数量', class: "td-warm"},
@@ -155,15 +181,19 @@
                         restorationColumn: 'id',
                         fixedTop: ($('#form_div').height()) + ($('#btn').height()) + 2,
                         before: [
-                            {colspan: '6', value: '人员工时(含临时工)', class: "table-header-layer-1"},
+                            {colspan: '7', value: '人员工时(含临时工)', class: "table-header-layer-1"},
+
+                            {colspan: '2', value: '收货清点', class: "table-header-layer-1"},
+
+                            {colspan: '3', value: '退货登记', class: "table-header-layer-1"},
                             {
                                 colspan: '4',
                                 value: '出库',
                                 font: "fa fa-file-text-o",
                                 class: "table-header-layer-1"
                             },
-                            {colspan: '3', value: '入库', font: "fa fa-truck", class: "table-header-layer-1"},
-                            {colspan: '3', value: '库存', font: "fa fa-truck", class: "table-header-layer-1"},
+                            {colspan: '3', value: '上架', font: "fa fa-truck", class: "table-header-layer-1"},
+                            {colspan: '3', value: '盘点', font: "fa fa-truck", class: "table-header-layer-1"},
                             {colspan: '2', value: '异常', font: "fa fa-truck", class: "table-header-layer-1"},
                         ],
                     }).init();

+ 205 - 0
resources/views/kpi/dayDetail/index.blade.php

@@ -0,0 +1,205 @@
+@extends('layouts.app')
+@section('title')KPI-日报表@endsection
+@section('content')
+<div class="d-none" id="list">
+    <div class="container-fluid">
+        <div id="form_div"></div>
+        <!--            导出-->
+        <span class="dropdown"></span>
+        {{--            <h3>2021</h3>--}}
+        <!--            表格-->
+        <table class="table table-striped table-bordered table-hover text-nowrap waybill-table td-min-width-80"
+               style="background: #fff;" id="table">
+            <tr v-for="(item,i) in details.data" :key="i">
+                <td><input class="checkItem" type="checkbox" :value="item.id"></td>
+                <td class="td-warm text-muted"><span>@{{ item.departmentName }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.statTime.slice(0,10) }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.b2bck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.jyck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.qtck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.jitck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.hhck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.ptck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f4ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f21ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f11ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f1ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.xnck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.bfck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.dbck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.cgth }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.xsck }}</span></td>
+
+                <td class="td-warm text-muted"><span>@{{ item.cgrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.thrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.dbrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.xnrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f31rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f10rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f21rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f32rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.hhrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.cskc }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.qtrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.b2brk }}</span></td>
+
+                <td class="td-warm text-muted"><span>@{{ item.rejectedOrder }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.rejectedCommodity }}</span></td>
+            </tr>
+        </table>
+        <nav aria-label="...">
+            <ul class="pagination">
+                <li class="page-item" :class="current===1?'disabled':''">
+                    <button class="page-link" @click="pagination('pre')">上一页</button>
+                </li>
+                <li class="page-item" :class="current===details.pages?'disabled':''">
+                    <button class="page-link" @click="pagination('next')">下一页</button>
+                </li>
+            </ul>
+        </nav>
+    </div>
+</div>
+
+
+@endsection
+
+@section('lastScript')
+<script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+<script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+<script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>{{--新版2--}}
+<script>
+    let vue = new Vue({
+        el: "#list",
+        data: {
+            selectTr: '',
+            details: {
+                data: [],
+                total: null,
+                current: null,
+                pages: null,
+                size: null
+            },
+            size: 50,
+            current: 1
+        },
+        created() {
+            let url = this.getBaseUrl();
+            url += `/api/deliver/getDayDetailPage?size=${this.size}&current=${this.current}`;
+            axios.get(url).then(res => {
+                this.details.data = res.data.data.list;
+                this.details.total = res.data.data.page.total;
+                this.details.current = res.data.data.page.pageNum;
+                this.details.pages = res.data.data.page.pages
+                this.details.size = res.data.data.page.pageSize;
+            });
+        },
+        mounted: function () {
+            $('#list').removeClass('d-none');
+            let data = [
+                [
+                    {name: 'date_start', type: 'time', tip: '选择显示指定日期的起始时间'},
+                ]
+            ];
+            this.form = new query({
+                el: "#form_div",
+                condition: data,
+            });
+            this.form.init();
+            this.rendingHeader();
+
+        },
+        methods: {
+            cal_deliver_percentage(item) {
+                if (item.workTimes == 0) return 0;
+                return Math.round(item.totalDeliveryQty / item.workTimes * 100);
+            },
+
+            //根据环境获取不同的url
+            getBaseUrl() {
+                let url = '';
+                let env = "{{ config('app.env') }}";
+                if (env === 'local') {
+                    url = 'http://127.0.0.1:8111'
+                } else if (env === 'production') {
+                    url = 'https://stat.baoshi56.com'
+                }
+                return url;
+            },
+            pagination(flag) {
+                if (flag === 'pre' && this.current > 1) {
+                    this.current--;
+                } else if (flag === 'next' && this.current < this.details.pages) {
+                    this.current++;
+                }
+                let env = "{{ config('env') }}";
+                console.log(env);
+                let url = this.getBaseUrl();
+
+                url += `/api/deliver/getDayDetailPage?size=${this.size}&current=${this.current}`;
+                axios.get(url).then(res => {
+                    this.details.data = res.data.data.list;
+                    this.details.total = res.data.data.page.total;
+                    this.details.current = res.data.data.page.pageNum;
+                    this.details.pages = res.data.data.page.pages
+                    this.details.size = res.data.data.page.pageSize;
+                });
+            },
+            rendingHeader() {
+                let column = [
+                    {name: 'departmentName', value: '工作组', neglect: true, class: "td-cool"},
+                    {name: 'statTime', value: '统计日期', neglect: true, class: "td-cool"},
+
+                    {name: 'b2bck', value: 'B2B出库', neglect: true, class: "td-cool"},
+                    {name: 'jyck', value: '一般交易出库', neglect: true, class: "td-cool"},
+                    {name: 'qtck', value: '其他出库', neglect: true, class: "td-cool"},
+                    {name: 'jitck', value: '唯品出库', neglect: true, class: "td-cool"},
+                    {name: 'hhck', value: '换货出库', neglect: true, class: "td-cool"},
+                    {name: 'ptck', value: '普通出库', neglect: true, class: "td-cool"},
+                    {name: 'f4ck', value: '笕尚移仓出库单', neglect: true, class: "td-cool"},
+                    {name: 'f21ck', value: '笕尚调整出库单', neglect: true, class: "td-cool"},
+                    {name: 'f11ck', value: '笕尚退仓出库单', neglect: true, class: "td-cool"},
+                    {name: 'f1ck', value: '笕尚配货出库单', neglect: true, class: "td-cool"},
+                    {name: 'xnck', value: '虚拟出库', neglect: true, class: "td-cool"},
+                    {name: 'bfck', value: '补发出库', neglect: true, class: "td-cool"},
+                    {name: 'dbck', value: '调拨出库', neglect: true, class: "td-cool"},
+                    {name: 'cgth', value: '采购退货', neglect: true, class: "td-cool"},
+                    {name: 'xsck', value: '销售出库', neglect: true, class: "td-cool"},
+
+
+                    {name: 'cgrk', value: '采购入库', neglect: true, class: "td-warm"},
+                    {name: 'thrk', value: '退货入库', neglect: true, class: "td-warm"},
+                    {name: 'dbrk', value: '调拨入库', neglect: true, class: "td-warm"},
+                    {name: 'xnrk', value: '虚拟入库', neglect: true, class: "td-warm"},
+                    {name: 'f31rk', value: '笕尚退货入库单', neglect: true, class: "td-warm"},
+                    {name: 'f10rk', value: '笕尚进仓入库单', neglect: true, class: "td-warm"},
+                    {name: 'f21rk', value: '笕尚调整入库单', neglect: true, class: "td-warm"},
+                    {name: 'f32rk', value: '笕尚移仓入库单', neglect: true, class: "td-warm"},
+                    {name: 'hhrk', value: '换货入库', neglect: true, class: "td-warm"},
+                    {name: 'cskc', value: '初始化库存', neglect: true, class: "td-warm"},
+                    {name: 'qtrk', value: '其他入库', neglect: true, class: "td-warm"},
+                    {name: 'b2brk', value: 'B2B入库', neglect: true, class: "td-warm"},
+
+                    {name: 'rejectedOrder', value: '退货单数', neglect: true, class: "td-cool"},
+                    {name: 'rejectedCommodity', value: '退货商品数', neglect: true, class: "td-cool"},
+
+                ];
+                new Header({
+                    el: "table",
+                    name: "details",
+                    column: column,
+                    data: this.details.data,
+                    restorationColumn: 'id',
+                    fixedTop: ($('#form_div').height()) + ($('#btn').height()) + 2,
+                    before: [
+                        {colspan: '18', value: '出库', class: "table-header-layer-1"},
+
+                        {colspan: '12', value: '入库', class: "table-header-layer-1"},
+
+                        {colspan: '2', value: '退货', class: "table-header-layer-1"},
+                    ],
+                }).init();
+            },
+        },
+    });
+</script>
+@endsection

+ 263 - 0
resources/views/kpi/dayDetailCustomer/index.blade.php

@@ -0,0 +1,263 @@
+@extends('layouts.app')
+@section('title')KPI-日报表@endsection
+@section('content')
+    <div class="d-none" id="list">
+        <!--查询            -->
+        <div class="row m-3" style="background-color: #fff;">
+
+            <div class="form-group m-2">
+                <select class="form-control selectpicker" title="分页大小" v-model="size">
+                    <option value="50">50</option>
+                    <option value="100">100</option>
+                    <option value="200">200</option>
+                    <option value="500">500</option>
+                    <option value="1000">1000</option>
+                </select>
+            </div>
+
+            <div class="form-group m-2" style="max-width: 200px !important;">
+                <select v-model="search.customerCodeList" class="selectpicker form-control" multiple title="选择货主"
+                        data-actions-box="true"
+                        data-live-search="true"
+                        data-live-search-placeholder="搜索"
+                >
+                    <option v-for="(v,k) of owners" :value="v.id" :key="v.id">@{{ v.name }}</option>
+                </select>
+            </div>
+            <div class="form-group m-2" data-toggle="tooltip" data-placement="top" title="起始日期">
+                <input v-model="search.startDate" class="form-control" type="date">
+            </div>
+
+            <div class="form-group m-2" data-toggle="tooltip" data-placement="top" title="截止日期">
+                <input v-model="search.endDate" class="form-control" type="date">
+            </div>
+
+            <div class="form-group m-2">
+                <button class="form-control btn btn-sm btn-info" @click="searchData()">查询</button>
+            </div>
+
+            <div class="form-group m-2">
+                <button class="form-control btn btn-sm btn-success" @click="resetSearch()">重置</button>
+            </div>
+        </div>
+
+        <!--            导出-->
+        <span class="dropdown"></span>
+    {{--            <h3>2021</h3>--}}
+    <!--            表格-->
+        <table class="table table-striped table-bordered table-hover text-nowrap waybill-table td-min-width-80"
+               style="background: #fff;" id="table">
+            <tr v-for="(item,i) in details.data" :key="i">
+                <td><input class="checkItem" type="checkbox" :value="item.id"></td>
+                <td class="td-warm text-muted"><span>@{{ item.customerName }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.statTime.slice(0,10) }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.b2bck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.jyck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.qtck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.jitck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.hhck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.ptck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f4ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f21ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f11ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f1ck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.xnck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.bfck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.dbck }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.cgth }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.xsck }}</span></td>
+
+                <td class="td-warm text-muted"><span>@{{ item.cgrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.thrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.dbrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.xnrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f31rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f10rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f21rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.f32rk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.hhrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.cskc }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.qtrk }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.b2brk }}</span></td>
+
+                <td class="td-warm text-muted"><span>@{{ item.rejectedOrder }}</span></td>
+                <td class="td-warm text-muted"><span>@{{ item.rejectedCommodity }}</span></td>
+            </tr>
+        </table>
+        <nav aria-label="...">
+            <ul class="pagination">
+                <li class="page-item" :class="current===1?'disabled':''">
+                    <button class="page-link" @click="pagination('pre')">上一页</button>
+                </li>
+                <li class="page-item" :class="current===details.pages?'disabled':''">
+                    <button class="page-link" @click="pagination('next')">下一页</button>
+                </li>
+            </ul>
+        </nav>
+    </div>
+
+
+@endsection
+
+@section('lastScript')
+    <script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>{{--新版2--}}
+    <script>
+        let vue = new Vue({
+            el: "#list",
+            data: {
+                owners: [
+                        @foreach($owners as $owner)
+                    {
+                        name: '{{$owner->name}}', id: '{{$owner->id}}', code: '{{$owner->code}}'
+                    },
+                    @endforeach
+                ],
+                selectTr: '',
+                details: {
+                    data: [],
+                    total: null,
+                    current: null,
+                    pages: null,
+                    size: null
+                },
+                size: 50,
+                current: 1,
+                search: {
+                    startDate: '',
+                    endDate: '',
+                    customerCodeList: [],
+                }
+            },
+            created() {
+                let url = this.getBaseUrl();
+                url += `/api/deliver/getDayDetailCustomerPage?size=${this.size}&current=${this.current}`;
+                axios.post(url, this.search).then(res => {
+                    this.details.data = res.data.data.list;
+                    this.details.total = res.data.data.page.total;
+                    this.details.current = res.data.data.page.pageNum;
+                    this.details.pages = res.data.data.page.pages
+                    this.details.size = res.data.data.page.pageSize;
+                });
+            },
+            mounted: function () {
+                $('#list').removeClass('d-none');
+                this.rendingHeader();
+
+            },
+            methods: {
+                resetSearch() {
+                    this.current = 1;
+                    this.size = 50;
+                    this.search = {
+                        startDate: '',
+                        endDate: '',
+                        customerCodeList: [],
+                    }
+                },
+
+                searchData() {
+                    this.current = 1;
+                    this.pagination();
+                },
+                cal_deliver_percentage(item) {
+                    if (item.workTimes == 0) return 0;
+                    return Math.round(item.totalDeliveryQty / item.workTimes * 100);
+                },
+
+                //根据环境获取不同的url
+                getBaseUrl() {
+                    let url = '';
+                    let env = "{{ config('app.env') }}";
+                    if (env === 'local') {
+                        url = 'http://127.0.0.1:8111'
+                    } else if (env === 'production') {
+                        url = 'https://stat.baoshi56.com'
+                    }
+                    return url;
+                },
+                pagination(flag) {
+                    if (flag === 'pre' && this.current > 1) {
+                        this.current--;
+                    } else if (flag === 'next' && this.current < this.details.pages) {
+                        this.current++;
+                    }
+                    let env = "{{ config('env') }}";
+                    console.log(env);
+                    let url = this.getBaseUrl();
+
+                    url += `/api/deliver/getDayDetailCustomerPage?size=${this.size}&current=${this.current}`;
+                    axios.post(url, this.search).then(res => {
+                        if (res.data.data === undefined) {
+                            this.details.data = [];
+                            this.details.total = 0
+                            this.details.current = 1
+                            this.details.pages = 0
+                            this.details.size = 50;
+                        } else {
+                            this.details.data = res.data.data.list;
+                            this.details.total = res.data.data.page.total;
+                            this.details.current = res.data.data.page.pageNum;
+                            this.details.pages = res.data.data.page.pages
+                            this.details.size = res.data.data.page.pageSize;
+                        }
+                    });
+                },
+                rendingHeader() {
+                    let column = [
+                        {name: 'ownerName', value: '货主', neglect: true, class: "td-cool"},
+                        {name: 'statTime', value: '统计日期', neglect: true, class: "td-cool"},
+
+                        {name: 'b2bck', value: 'B2B出库', neglect: true, class: "td-cool"},
+                        {name: 'jyck', value: '一般交易出库', neglect: true, class: "td-cool"},
+                        {name: 'qtck', value: '其他出库', neglect: true, class: "td-cool"},
+                        {name: 'jitck', value: '唯品出库', neglect: true, class: "td-cool"},
+                        {name: 'hhck', value: '换货出库', neglect: true, class: "td-cool"},
+                        {name: 'ptck', value: '普通出库', neglect: true, class: "td-cool"},
+                        {name: 'f4ck', value: '笕尚移仓出库单', neglect: true, class: "td-cool"},
+                        {name: 'f21ck', value: '笕尚调整出库单', neglect: true, class: "td-cool"},
+                        {name: 'f11ck', value: '笕尚退仓出库单', neglect: true, class: "td-cool"},
+                        {name: 'f1ck', value: '笕尚配货出库单', neglect: true, class: "td-cool"},
+                        {name: 'xnck', value: '虚拟出库', neglect: true, class: "td-cool"},
+                        {name: 'bfck', value: '补发出库', neglect: true, class: "td-cool"},
+                        {name: 'dbck', value: '调拨出库', neglect: true, class: "td-cool"},
+                        {name: 'cgth', value: '采购退货', neglect: true, class: "td-cool"},
+                        {name: 'xsck', value: '销售出库', neglect: true, class: "td-cool"},
+
+
+                        {name: 'cgrk', value: '采购入库', neglect: true, class: "td-warm"},
+                        {name: 'thrk', value: '退货入库', neglect: true, class: "td-warm"},
+                        {name: 'dbrk', value: '调拨入库', neglect: true, class: "td-warm"},
+                        {name: 'xnrk', value: '虚拟入库', neglect: true, class: "td-warm"},
+                        {name: 'f31rk', value: '笕尚退货入库单', neglect: true, class: "td-warm"},
+                        {name: 'f10rk', value: '笕尚进仓入库单', neglect: true, class: "td-warm"},
+                        {name: 'f21rk', value: '笕尚调整入库单', neglect: true, class: "td-warm"},
+                        {name: 'f32rk', value: '笕尚移仓入库单', neglect: true, class: "td-warm"},
+                        {name: 'hhrk', value: '换货入库', neglect: true, class: "td-warm"},
+                        {name: 'cskc', value: '初始化库存', neglect: true, class: "td-warm"},
+                        {name: 'qtrk', value: '其他入库', neglect: true, class: "td-warm"},
+                        {name: 'b2brk', value: 'B2B入库', neglect: true, class: "td-warm"},
+
+                        {name: 'rejectedOrder', value: '退货单数', neglect: true, class: "td-cool"},
+                        {name: 'rejectedCommodity', value: '退货商品数', neglect: true, class: "td-cool"},
+
+                    ];
+                    new Header({
+                        el: "table",
+                        name: "details",
+                        column: column,
+                        data: this.details.data,
+                        restorationColumn: 'id',
+                        fixedTop: ($('#form_div').height()) + ($('#btn').height()) + 2,
+                        before: [
+                            {colspan: '18', value: '出库', class: "table-header-layer-1"},
+
+                            {colspan: '12', value: '入库', class: "table-header-layer-1"},
+
+                            {colspan: '2', value: '退货', class: "table-header-layer-1"},
+                        ],
+                    }).init();
+                },
+            },
+        });
+    </script>
+@endsection

+ 3 - 3
resources/views/kpi/month/index.blade.php

@@ -71,7 +71,7 @@
                     pages: null,
                     size: null
                 },
-                size: 10,
+                size: 50,
                 current: 1
             },
             created() {
@@ -105,9 +105,9 @@
                     let url = '';
                     let env = "{{ config('app.env') }}";
                     if (env === 'local') {
-                        url = ' http://127.0.0.1:8111'
+                        url = 'http://127.0.0.1:8111'
                     } else if (env === 'production') {
-                        url = ' http://101.133.135.193'
+                        url = 'https://stat.baoshi56.com'
                     }
                     return url;
                 },

+ 21 - 26
resources/views/order/index/_workOrkerInfoModal.blade.php → resources/views/order/index/_work_order_info_modal.blade.php

@@ -17,40 +17,32 @@
                         </div>
                         <div>
                             <span class="text-monospace">工单类型:</span>
-                            <span v-text="workOrderInfo.type"></span>
+                            <span v-text="workOrderInfo.issue_name"></span>
                         </div>
                         <div>
                             <span class="text-monospace">内容:</span>
                             <span v-text="workOrderInfo.remark"></span>
                         </div>
                     </div>
-
-                    <div class="">
-                        <span class="text-monospace">当前工单号:</span>
-                        <span v-text="workOrderInfo.id"></span>
-                    </div>
-
                     <div class=""
-                         v-if="workOrderInfo?.logistic_numbers.length >0 ">
+                         v-if="workOrderInfo ? (workOrderInfo.logistic_numbers.length > 0) : false">
                         <span class="text-monospace">快递单号:</span>
-                        <span v-for="logistic_number in (workOrderInfo?.logistic_numbers || [])"
+                        <span v-for="logistic_number in (workOrderInfo.logistic_numbers ?  workOrderInfo.logistic_numbers : [])"
                               v-text="logistic_number"></span>
                     </div>
 
-                    <div class="" v-if="workOrderInfo?.details.length > 0">
-                        <div class="" v-for="detail in (workOrderInfo?.details || [])">
-                            <div>
-                                <span class="text-monospace">价值:</span>
-                                <span v-text="detail.price"></span>
-                            </div>
-                            <div v-if="detail.return_logistic_number">
-                                <span class="text-monospace">退回单号:</span>
-                                <span v-text="detail.return_logistic_number"></span>
-                            </div>
-                            <div v-if="detail.reissue_logistic_number">
-                                <span class="text-monospace">补发单号:</span>
-                                <span v-text="detail.reissue_logistic_number"></span>
-                            </div>
+                    <div>
+                        <div v-if="Number(workOrderInfo.detail.price) !== 0">
+                            <span class="text-monospace">价值:</span>
+                            <span v-text="workOrderInfo.detail.price"></span>
+                        </div>
+                        <div v-if="workOrderInfo.detail.return_logistic_number">
+                            <span class="text-monospace">退回单号:</span>
+                            <span v-text="workOrderInfo.detail.return_logistic_number"></span>
+                        </div>
+                        <div v-if="workOrderInfo.detail.reissue_logistic_number">
+                            <span class="text-monospace">补发单号:</span>
+                            <span v-text="workOrderInfo.detail.reissue_logistic_number"></span>
                         </div>
                     </div>
 
@@ -124,8 +116,11 @@
                                 <td>订单数量</td>
                                 <td>异常数量</td>
                                 <td>核实数量</td>
-                                <td>核实原因</td>
-                                <td>处理结果</td>
+                                <td>
+                                    <span v-if="'快递异常'=== workOrderInfo.issue_name">快递处理结果</span>
+                                    <span v-else>核实原因</span>
+                                </td>
+                                <td v-if="'快递异常'!== workOrderInfo.issue_name">处理结果</td>
                             </tr>
                             </thead>
                             <tbody>
@@ -137,7 +132,7 @@
                                 <td v-text="commodity.abnormal_amount"></td>
                                 <td v-text="commodity.check_amount"></td>
                                 <td v-text="commodity.check_result"></td>
-                                <td v-text="commodity.process_result"></td>
+                                <td v-if="'快递异常'!== workOrderInfo.issue_name" v-text="commodity.process_result"></td>
                             </tr>
                             </tbody>
                         </table>

+ 50 - 14
resources/views/order/index/_work_order_modal.blade.php

@@ -1,6 +1,6 @@
 <div class="modal fade " id="intercept-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
      aria-hidden="true">
-    <div class="modal-dialog modal-xl modal-dialog-centered">
+    <div class="modal-dialog modal-xl modal-dialog-centered ">
         <div class="modal-content">
             <div class="modal-header">
                 <h5 class="modal-title" id="checkModalLabel">创建工单</h5>
@@ -8,7 +8,7 @@
                     <span aria-hidden="true">&times;</span>
                 </button>
             </div>
-            <div class="modal-body">
+            <div class="modal-body pd-0">
                 {{--工单类型--}}
                 <div class="form-group row">
                     <label for="order_issue_type" class="col-sm-2 col-form-label text-right">工单类型</label>
@@ -33,10 +33,12 @@
 
                 {{--破损商品价格--}}
                 <div class="form-group row" v-if="'破损' === workOrder.orderIssueType">
-                    <label for="work-order-price" class="col-sm-2 col-form-label text-right text-primary">破损商品价格</label>
+                    <label for="work-order-price" class="col-sm-2 col-form-label text-right text-primary">
+                        破损商品价值
+                    </label>
                     <div class="col-sm-10">
                         <input type="number" id="work-order-price" class="form-control" v-model="workOrder.price"
-                               placeholder="破损商品价格">
+                               placeholder="破损商品价值自动计算" disabled>
                     </div>
                 </div>
                 {{--快递单号--}}
@@ -108,6 +110,7 @@
                 <div class="form-group row" v-if="['破损','快递异常'].includes(workOrder.orderIssueType) ">
                     <label for="deal-image" class="col-sm-2 col-form-label text-right text-primary">交易截图</label>
                     <div class="col-sm-10">
+                        <div><span class="text-primary">需带有付款时间,快递单号,内物详情和实付款的交易截图</span></div>
                         <div class="border border-secondary h-auto" id="deal-image" style="min-height: 75px"
                              contenteditable="true"
                              @paste="pasteImage($event,workOrder.dealImages)">
@@ -139,24 +142,34 @@
                                 <td class="text-center" v-if="['破损',].includes(workOrder.orderIssueType)">异常类型</td>
                                 <td class="text-center">商品名称</td>
                                 <td class="text-center">订单数量</td>
-                                <td class="text-center">异常数量</td>
+                                <td class="text-center" v-if="'破损' === workOrder.orderIssueType">破损商品价值</td>
+                                <td v-if="'错漏发' === workOrder.orderIssueType">异常类型</td>
+                                <td class="text-center"><span
+                                        v-text="workOrder.orderIssueType === '错漏发' ? '客户实收数量' : '异常数量'"></span></td>
                                 <td></td>
                             </tr>
                             </thead>
                             <tbody>
                             <tr v-for="(commodity,i) in workOrder.commodities" class="text-center">
-                                <td><span v-text="commodity.logistic_number"></span></td>
-                                <td><span v-text="commodity.sku"></span></td>
+                                <td v-text="commodity.logistic_number"></td>
+                                <td v-text="commodity.sku"></td>
                                 <td v-if="['破损',].includes(workOrder.orderIssueType)">
                                     <span v-if="workOrder.orderIssueType === '破损'"
-                                          :data="commodity.abnormal_type = '破损'" >破损</span>
-{{--                                    <span v-if="workOrder.orderIssueType === '错漏发'"--}}
-{{--                                          :data="commodity.abnormal_type = '错漏发'"  >错漏发</span>--}}
+                                          :data="commodity.abnormal_type = '破损'">破损</span>
+                                </td>
+                                <td v-text="commodity.name"></td>
+                                <td v-text="commodity.amount"></td>
+                                <td class="text-center" v-if="'破损' === workOrder.orderIssueType">
+                                    <input type="number" class="form-control form-control-sm" v-model="commodity.price"
+                                           v-show="commodity.abnormal_amount !== '0'"
+                                           @input="sunPrice">
+                                </td>
+                                <td v-if="'错漏发' === workOrder.orderIssueType" v-text="commodity.abnormal_type">
                                 </td>
-                                <td><span v-text="commodity.name"></span></td>
-                                <td><span v-text="commodity.amount"></span></td>
                                 <td>
-                                    <input type="number" class="form-control form-control-sm" v-model="commodity.abnormal_amount">
+                                    <input type="number" class="form-control form-control-sm"
+                                           v-model="commodity.abnormal_amount"
+                                           @input="computeAbnormalType(commodity)">
                                 </td>
                                 <td>
                                     <button type="button" class="close" @click="workOrder.commodities.splice(i,1)">
@@ -166,6 +179,30 @@
                             </tr>
                             </tbody>
                         </table>
+                        <div v-if="workOrder.orderIssueType === '错漏发'">
+                            <table class="table table-sm table-grid-row table-hover mb-0">
+                                <tr>
+                                    <td>
+                                        <input type="text" class="form-control" id="add-commodity-logistic-number"
+                                               ref="add-commodity-logistic-number" placeholder="快递单号">
+                                    </td>
+                                    <td>
+                                        <input type="text" class="form-control" id="add-commodity-sku"
+                                               ref="add-commodity-sku" placeholder="商品条码">
+                                    </td>
+                                    <td>
+                                        <input type="number" class="form-control" id="add-commodity-number"
+                                               ref="add-commodity-number" placeholder="客户实收数量">
+                                    </td>
+                                    <td>
+                                        <button type="button" class="btn btn-sm btn-outline-success"
+                                                @click="addWorkOrderCommodity">
+                                            添加
+                                        </button>
+                                    </td>
+                                </tr>
+                            </table>
+                        </div>
                     </div>
                 </div>
             </div>
@@ -173,7 +210,6 @@
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭
                 </button>
-                {{--生成工单--}}
                 <button type="button" class="btn btn-outline-primary" @click="buildWorkOrder">提交
                 </button>
             </div>

+ 132 - 35
resources/views/order/index/delivering.blade.php

@@ -325,7 +325,7 @@
                 </div>
                 @can('订单管理-订单-生成工单')
                     @include('order.index._work_order_modal')
-                    @include('order.index._workOrkerInfoModal')
+                    @include('order.index._work_order_info_modal')
                 @endcan
                 <textarea id="clipboardDiv" style="opacity:0"></textarea>
             </div>
@@ -419,13 +419,18 @@
                     type:'',
                     clientCode:'',
                     logistic_numbers:[],
-                    details:[],
+                    detail:{
+                        price:'',
+                        return_logistic_number:'',
+                        reissue_logistic_number:'',
+                    },
                     commodities:[],
                     packagesImages:[],
                     commodityImages:[],
                     dealImages:[],
                     refundImages:[],
                     remark:'',
+                    issue_name:'',
                 },
             },
             mounted: function () {
@@ -1244,7 +1249,7 @@
                                 $('#work-order-info').modal('show');
                             },()=>{
                                 this.showInterceptModel();
-                            },'查看','跳过');
+                            },'查看','重新生成工单');
                         } else {
                             this.showInterceptModel();
                         }
@@ -1333,7 +1338,7 @@
                     checkData.forEach(e=>{
                         formData.append('orderNos[]',e);
                     });
-                    formData.append('remark',this.workOrder?.remark?.info || '');
+                    formData.append('remark',this.workOrder ? (this.workOrder.remark ? this.workOrder.remark.info : '') : '');
                     let url = "{{route('workOrder.interceptApi')}}";
                     this.createWorkOrder(formData,url);
                 },
@@ -1355,11 +1360,12 @@
                     this.createWorkOrder(formData,url);
                 },
                 createExpressAbnormalWorkOrder(){ // 快递异常
+                    if (!this.checkExpressAbnormalWorkOrder()) return;
                     let url = "{{route('workOrder.expressAbnormalApi')}}";
                     let data = this.getCreateWorkOrderData();
                     let formData = new FormData();
                     formData.append('order_no', data[0]['order_no']);
-                    formData.append('remark', this.workOrder.remark.info);
+                    formData.append('remark', this.workOrder.remark ?  this.workOrder.remark.info : '');
                     let dealImages = this.getImages(this.workOrder.dealImages);
                     this.setFormDataImagePrefix(formData, 'dealImages', dealImages);
                     this.setFormDataCommodities(formData);
@@ -1421,9 +1427,10 @@
                              sku:commodity.sku,
                              amount:commodity.amount,
                              commodity_id:commodity['commodity_id'],
-                             abnormal_type:commodity['abnormal_type'],
                              logistic_number:commodity['logistic_number'],
                              abnormal_amount:commodity['abnormal_amount'],
+                             abnormal_type:commodity['abnormal_type'],
+                             price:commodity['price'],
                          };
                          formData.append('commodities[]',JSON.stringify(item)) ;
                     });
@@ -1621,9 +1628,13 @@
                     let data = {orderNo:checkData[0]};
                     window.axios.post(url,data).then(res=>{
                         if (res.data.success){
-                            this.workOrder.commodities = res.data.data;
+                            this.workOrder.commodities =  res.data.data.map(item=>{
+                                item.abnormal_amount = item.amount;
+                                item.abnormal_type = this.workOrder.orderIssueType === '错漏发' ? '未错漏发' :'';
+                                item.price = 0;
+                                return item;
+                            });
                         } else {
-
                         }
                     }).catch(err=>{
                     })
@@ -1662,18 +1673,16 @@
                         let url = '{{route('workOrder.checkApi')}}';
                         window.axios.post(url,{no:no}).then(res=>{
                             if (res.data.success){
-                                if (res.data.data.length > 0){
-                                    res.data.data.forEach((e,i)=>{
-                                        this.workOrderInfos[i] = this.conversionWorkOrder(e);
-                                    });
-                                    resolve(true) ;
-                                } else{
-                                    this.workOrderInfos = [];
-                                    resolve(false);
-                                }
-
+                                this.workOrderInfos = [];
+                                res.data.data.forEach(e=>{
+                                    let array = this.conversionWorkOrder(e);
+                                    this.workOrderInfos.push(...array);
+                                });
+                                if (this.workOrderInfos.length>0)resolve(true) ;
+                                else resolve(false);
                             } else {
                                 this.workOrderInfos = [];
+                                resolve(false);
                             }
                         }).catch(err=>{
                             reject(err);
@@ -1681,31 +1690,43 @@
                     });
                 },
                 conversionWorkOrder(workOrder){
+                    let items = [];
+                    workOrder.details.forEach(detail=>{
+                        let item = this.conversionDetail(detail);
+                        item.logistic_numbers = this.getLogisticNumbers(workOrder);
+                        item.clientCode = workOrder.order ? workOrder.order.client_code : '';
+                        items.push(item);
+                    });
+                    return items;
+                },
+                conversionDetail(detail){
                     return {
-                        id:workOrder?.id,
-                        type:workOrder?.issue_type?.name,
-                        clientCode:workOrder?.order?.client_code,
-                        logistic_numbers:this.getLogisticNumbers(workOrder),
-                        details:this.getDetails(workOrder),
-                        commodities:this.getCommodities(workOrder),
-                        packagesImages:this.getImageList(workOrder.images,'1'),
-                        commodityImages:this.getImageList(workOrder.images,'2'),
-                        dealImages:this.getImageList(workOrder.images,'3'),
-                        refundImages:this.getImageList(workOrder.images,'4'),
-                        remark:workOrder.remark,
+                        type: detail.issue_type ? detail.issue_type.name : '',
+                        detail:{
+                            price:detail.price,
+                            return_logistic_number:detail.return_logistic_number,
+                            reissue_logistic_number:detail.reissue_logistic_number,
+                        },
+                        commodities:this.getCommodities(detail),
+                        packagesImages:this.getImageList(detail.images,'外包装图片'),
+                        commodityImages:this.getImageList(detail.images,'内物破碎图片'),
+                        dealImages:this.getImageList(detail.images,'交易截图'),
+                        refundImages:this.getImageList(detail.images,'退款成功截图'),
+                        remark:detail.remark,
+                        issue_name : detail.issue_type ? detail.issue_type.name : '',
                     };
                 },
                 getLogisticNumbers(workOrder){
-                    let packages = workOrder?.order?.packages || [];
+                    let packages = workOrder? (workOrder.order ? workOrder.order.packages : []) : [] ;
                     return packages.map(e=>{return e.logistic_number});
                 },
                 getDetails(workOrder){
-                    let details = workOrder?.details;
+                    let details = workOrder ? workOrder.details : [];
                     return details.map(e=>{return e;});
                 },
-                getCommodities(workOrder){
-                    return (workOrder?.commodities ||[]).map(item=>{
-                        item.name = item?.commodity?.name;
+                getCommodities(detail){
+                    return (detail ? detail.commodities : []).map(item=>{
+                        item.name =item.commodity ? item.commodity.name :'';
                         return item;
                     });
                 },
@@ -1716,7 +1737,7 @@
                     });
                     return imageList.map(e=>{
                         return {
-                            src:filePrefix+e?.upload_file?.url+'.'+e?.upload_file?.type,
+                            src:filePrefix+(e.upload_file ? e.upload_file.url : '')+'.'+(e.upload_file? e.upload_file.type : ''),
                         };
                     });
                 },
@@ -1733,6 +1754,82 @@
                 showNextWorkOrder(){
                     if (parseInt(this.workOrderIndex) === (this.workOrderInfos.length -1)) return false;
                     return this.workOrderIndex  < this.workOrderInfos.length -1;
+                },
+                addWorkOrderCommodity(){
+                    window.tempTip.setIndex(1999);
+                    window.tempTip.setDuration(1500);
+                    let sku = this.$refs['add-commodity-sku'].value;
+                    let logistic_number = this.$refs['add-commodity-logistic-number'].value;
+                    if (logistic_number.trim().length === 0){
+                        window.tempTip.show('填写快递单号');
+                        return ;
+                    }
+                    let {customerid} = this.orders.find(item=>{
+                        return item.orderno === checkData[0];
+                    });
+                    this.getCommodity(customerid,sku).then(res => {
+                        if (res===null){
+                            window.tempTip.show('请检查商品条码');
+                        } else {
+                            this.workOrder.commodities.push({
+                                logistic_number:logistic_number,
+                                commodity_id:res.id,
+                                name:res.name,
+                                abnormal_type:"多发",
+                                amount:0,
+                                sku:this.$refs['add-commodity-sku'].value,
+                                abnormal_amount:this.$refs['add-commodity-number'].value,
+                            });
+                            this.$refs['add-commodity-logistic-number'].value = "";
+                            this.$refs['add-commodity-sku'].value = "";
+                            this.$refs['add-commodity-number'].value = "";
+                            window.tempTip.showSuccess("添加成功");
+                        }
+                    }).catch(err=>{
+                        window.tempTip.show("获取商品信息异常");
+                    });
+                },
+                getCommodity(owner,code){
+                    return new Promise((resolve, reject) => {
+                        let url = "{{route('commodity.getCommodityApi')}}";
+                        let data = {owner_code:owner,sku:code};
+                        console.log(data);
+                        window.axios.post(url,data).then(res=>{
+                            if (res.data.success){
+                               resolve(res.data.data);
+                            } else {
+                                resolve(null);
+                            }
+                        }).catch(err=>{
+                            reject(null);
+                        });
+                    });
+                },
+                computeAbnormalType(item){
+                    if (this.workOrder.orderIssueType !=='错漏发') return;
+                    let abnormal_amount = Number(item.abnormal_amount);     // 客户实收数量
+                    let amount = Number(item.amount);
+                    item.abnormal_type = abnormal_amount === amount ? '未错漏发' : (amount < abnormal_amount ? '多发' : '少发')
+                },
+                sunPrice(){
+                    this.workOrder.price = this.workOrder.commodities.reduce((prev,cur)=>{
+                        return prev +  Number(cur.price);
+                    },0);
+                },
+                checkExpressAbnormalWorkOrder(){    // 校验 快递异常问题
+                    window.tempTip.setIndex(1999);
+                    window.tempTip.setDuration(1500);
+                    let message = null
+                    let items = this.workOrder.commodities.filter(item=>{
+                        return Number(item.abnormal_amount) === 0;
+                    });
+                    if (items.length > 0)message = '请填写快递异常数量!';
+                    if (this.workOrder.dealImages.length === 0) message = '交易截图为必须项!';
+                    if (message){
+                        window.tempTip.show(message);
+                        return false;
+                    }
+                    return true;
                 }
             },
         });

+ 26 - 0
resources/views/order/issue/_batchUpdateFinalStatus.blade.php

@@ -0,0 +1,26 @@
+<div class="modal fade " id="batch-update-final-status" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
+     aria-hidden="true">
+    <div class="modal-dialog modal-md modal-dialog-centered">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="update-final-status">修改最终状态</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="">
+                    <select name="" id="update-final-status-select" class="form-control ">
+                        <option v-for="statues in finalStatus" :value="statues.value" v-text="statues.value"></option>
+                    </select>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭
+                </button>
+                <button type="button" class="btn btn-outline-primary" @click="batchUpdateRejectingStatus">提交
+                </button>
+            </div>
+        </div>
+    </div>
+</div>

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

@@ -76,6 +76,12 @@
                                     @click="archiveOrderIssue">批量归档
                             </button>
                         @endcan
+                            <button type="button"
+                                    class="btn btn-outline-primary btn-sm form-control-sm tooltipTarget ml-1"
+                                    data-toggle="modal" data-target="#batch-update-final-status"
+                                    v-show="checkData.length > 0"
+                                    >批量修改最终状态
+                            </button>
                     @endcannot
                 </div>
                 <table class="table table-sm table-striped table-bordered table-hover card-body p-0 m-0"
@@ -1107,6 +1113,7 @@
                 </div>
             </div>
         </div>
+        @include('order.issue._batchUpdateFinalStatus')
         <textarea id="clipboardDiv" style="opacity:0"></textarea>
     </div>
 
@@ -2429,6 +2436,32 @@
                         tempTip.show("网络异常:" + error);
                     });
                 },
+                batchUpdateRejectingStatus(){
+                    let url = "{{route('orderIssue.batchUpdate.finalStatusApi')}}";
+                    let data = {
+                        ids:this.checkData,
+                        final_status:document.getElementById('update-final-status-select').value
+                    };
+                    window.tempTip.waitingTip('修改中....');
+                    window.tempTip.setIndex(1999);
+                    window.axios.post(url,data).then(res=>{
+                        window.tempTip.cancelWaitingTip();
+                        if (res.data.success){
+                            $("#batch-update-final-status").modal('hide');
+                            this.orderIssues.forEach(item=>{
+                                if (this.checkData.includes(item.id)){
+                                    item.final_status= data.final_status
+                                }
+                            });
+                            window.tempTip.showSuccess("修改成功");
+                        } else {
+                            window.tempTip.show("修改失败:"+res.data.message);
+                        }
+                    }).catch(err=>{
+                        window.tempTip.cancelWaitingTip();
+                        window.tempTip.show("修改异常");
+                    });
+                },
                 listenTBodyResize() {
                     this.$set(this, 'toggleBtnHeight', document.getElementById('tbody').clientHeight);
                 },
@@ -2442,7 +2475,6 @@
                             item.tag = 1;
                         } else {
                             window.tempTip.show(res.data.message ? res.data.message : '标记出现异常');
-
                         }
                     }).catch(err => {
                         window.tempTip.show(err);

+ 29 - 21
resources/views/order/workOrder/_baoshi_fill_work_order.blade.php → resources/views/order/workOrder/_bao_shi_fill_work_order_modal.blade.php

@@ -1,17 +1,17 @@
 {{--快递处理丢件工单--}}
-<div class="modal fade " id="baoshi-fill-work-order-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
+<div class="modal fade " id="bao-shi-fill-work-order-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
      aria-hidden="true">
     <div class="modal-dialog modal-xl modal-dialog-centered">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title" id="baoshi-work-order-modal">错漏发信息填充(宝时)</h5>
+                <h5 class="modal-title" id="baoshi-work-order-modal">错漏发处理(宝时)</h5>
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                     <span aria-hidden="true">&times;</span>
                 </button>
             </div>
-            <div class="modal-body">
+            <div class="modal-body p-0">
                 <div>
-                    <table class="table">
+                    <table class="table text-center">
                         <thead>
                         <tr class="text-center">
                             <td>快递单号</td>
@@ -22,64 +22,72 @@
                             <td>宝时核实数量</td>
                             <td>核实结果</td>
                             <td>处理结果</td>
+                            <td v-if="'错漏发' === fillWorkOrder.issue_type_name "></td>
                         </tr>
                         </thead>
                         <tbody v-if="fillWorkOrder">
-                        <tr v-for="(item) in fillWorkOrder?.commodities || [] " class="text-center">
-                            <td>
-                                <span v-text="item.logistic_number"></span>
+                        <tr v-for="(item) in (fillWorkOrder ? fillWorkOrder.commodities : [])   " class="text-center">
+                            <td v-text="item.logistic_number">
                             </td>
                             <td>
-                                <span v-text="item?.commodity?.name || ''"></span>
+                                <span v-text="item.commodity ? item.commodity.name : ''"></span>
                             </td>
                             <td>
-                                <span v-text="item?.commodity?.sku || ''"></span>
+                                <span v-text="item.commodity? item.commodity.sku : ''"></span>
                             </td>
-                            <td>
-                                <span v-text="item.amount"></span>
+                            <td v-text="item.amount">
                             </td>
-                            <td>
-                                <span v-text="item.abnormal_amount"></span>
+                            <td v-text="item.abnormal_amount">
                             </td>
                             <td>
-                                <input type="number" class="form-control form-control-sm" v-model="item.bao_shi_check_amount">
+                                <input type="number" class="form-control form-control-sm"
+                                       v-model="item.bao_shi_check_amount"
+                                       @input="computeBaoShiCheckResult(item)">
                             </td>
                             <td>
                                 <select class="form-control form-control-sm"
                                         v-if="fillWorkOrder.issue_type_name === '破损'"
-                                        v-model="item.check_result" >
-                                    <option v-for="type in damagedResults"
-                                            :value="type" v-text="type"></option>
+                                        v-model="item.check_result">
+                                    <option v-for="type in damagedResults" :value="type" v-text="type"></option>
                                 </select>
 
                                 <select class="form-control form-control-sm"
                                         v-if="['快递异常','快递丢件'].includes(fillWorkOrder.issue_type_name)"
-                                        v-model="item.check_result" >
+                                        v-model="item.check_result">
                                     <option v-for="type in ['已拦截']" :value="type" v-text="type"></option>
                                 </select>
 
                                 <select class="form-control form-control-sm"
                                         v-if="'错漏发' === fillWorkOrder.issue_type_name"
-                                        v-model="item.check_result" >
+                                        v-model="item.check_result">
                                     <option v-for="type in mistakeResults"
                                             :value="type" v-text="type"></option>
                                 </select>
                             </td>
+
                             <td>
                                 <select class="form-control form-control-sm"
                                         v-if="'错漏发' === fillWorkOrder.issue_type_name"
                                         v-model="item.process_result">
                                     <option v-for="type in mistakeProcessResults"
-                                        :value="type" v-text="type"></option>
+                                            :value="type" v-text="type"></option>
                                 </select>
+
                                 <select class="form-control form-control-sm"
                                         v-else
-                                        v-model="item.process_result" >
+                                        v-model="item.process_result">
                                     <option
                                         v-for="type in processResults"
                                         :value="type" v-text="type"></option>
                                 </select>
                             </td>
+
+                            <td v-if="'错漏发' === fillWorkOrder.issue_type_name">
+                                <select class="form-control form-control-sm" v-model="item.process_result_info">
+                                    <option v-for="item in processResultInfo[item.process_result]" :value="item"
+                                            v-text="item"></option>
+                                </select>
+                            </td>
                         </tr>
                         </tbody>
                     </table>

+ 15 - 20
resources/views/order/workOrder/_bao_shi_review.blade.php → resources/views/order/workOrder/_bao_shi_review_modal.blade.php

@@ -4,52 +4,47 @@
     <div class="modal-dialog modal-xl modal-dialog-centered">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title" id="bao-shi-work-order-modal">终审(宝时)</h5>
+                <h5 class="modal-title" id="bao-shi-work-order-modal">终审(宝时)<span v-text="reviewWorkOrder ? reviewWorkOrder.issue_type_name :'' "></span></h5>
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                     <span aria-hidden="true">&times;</span>
                 </button>
             </div>
-            <div class="modal-body">
+            <div class="modal-body p-0">
                 <div>
-                    <table class="table">
+                    <table class="table text-center">
                         <thead>
-                        <tr class="text-center">
+                        <tr >
                             <td>快递单号</td>
                             <td>商品</td>
                             <td>商品条码</td>
                             <td>订单数量</td>
                             <td>异常数量</td>
-                            <td>核实数量</td>
+                            <td v-if="reviewWorkOrder.issue_type_name !== '快递丢件'">核实数量</td>
                             <td>宝时审核数量</td>
-                            <td>核实结果</td>
+                            <td v-if="reviewWorkOrder.issue_type_name !== '快递丢件'">核实结果</td>
                             <td>处理结果</td>
                         </tr>
                         </thead>
-                        <tbody v-if="fillWorkOrder">
-                        <tr v-for="(item) in reviewWorkOrder?.commodities || [] " class="text-center">
-                            <td>
-                                <span v-text="item.logistic_number"></span>
+                        <tbody v-if="reviewWorkOrder">
+                        <tr v-for="(item) in (reviewWorkOrder ? reviewWorkOrder.commodities :  []) " >
+                            <td v-text="item.logistic_number">
                             </td>
                             <td>
-                                <span v-text="item?.commodity?.name || ''"></span>
+                                <span v-text="item.commodity? item.commodity.name : ''"></span>
                             </td>
                             <td>
-                                <span v-text="item?.commodity?.sku || ''"></span>
+                                <span v-text="item.commodity? item.commodity.sku : ''"></span>
                             </td>
-                            <td>
-                                <span v-text="item.amount"></span>
+                            <td v-text="item.amount">
                             </td>
-                            <td>
-                                <span v-text="item.abnormal_amount"></span>
+                            <td v-text="item.abnormal_amount">
                             </td>
-                            <td>
-                                <span v-text="item.check_amount"></span>
+                            <td v-if="reviewWorkOrder.issue_type_name !== '快递丢件'" v-text="item.check_amount">
                             </td>
                             <td>
                                 <input type="number" class="form-control form-control-sm" v-model="item.bao_shi_check_amount">
                             </td>
-                            <td>
-                                <span v-text="item.check_result"></span>
+                            <td v-if="reviewWorkOrder.issue_type_name !== '快递丢件'" v-text="item.check_result">
                             </td>
                             <td>
                                  <select class="form-control form-control-sm"

+ 70 - 0
resources/views/order/workOrder/_issue_logs.blade.php

@@ -0,0 +1,70 @@
+<div class="alert alert-light m-0">
+    @can('订单管理-问题件-处理结果添加')
+    <div class="card-body border form-inline pl-0 mb-2"
+         v-if="item.order_issue"
+         v-show="selectCreateOrderIssueLog === item.id" >
+        <input type="text" class="form-control" :id="item.order_issue.id+'_log_text'">
+        <input type="checkbox" class="form-control form-control-sm float-right ml-1" value="true"
+               :id="item.order_issue.id + '_log_check'">
+        @cannot('订单管理-问题件-客户不可见')
+        <label :for="item.order_issue.id + '_log_check'" class="float-right ml-1">标</label>
+        @endcan
+        <button class="btn btn-sm btn-primary float-right ml-1" type="button"
+                @click="createOrderIssueLog(item.order_issue.id,item)">添加
+        </button>
+    </div>
+    <div class="header-alert" v-if="item.order_issue">
+        <button class="float-right btn btn-sm btn-primary"
+                @click="selectCreateOrderIssueLog === item.id ? selectCreateOrderIssueLog = null : selectCreateOrderIssueLog = item.id">新
+        </button>
+    </div>
+    @endcan
+    <div class="header-alert">
+        <span class="text-monospace">处理结果</span>
+        <button type="button" class="btn btn-sm btn-outline-primary float-right "
+                v-show="selectOrderIssueLog !== item.id"
+                v-if="item.issue_logs && item.issue_logs.length > 0"
+                @click="selectOrderIssueLog = item.id">显示
+        </button>
+        <button type="button" class="btn btn-sm btn-outline-primary float-right"
+                v-show="selectOrderIssueLog === item.id"
+                @click="selectOrderIssueLog = null">隐藏
+        </button>
+    </div>
+</div>
+<transition name="fade">
+    <div class="alert alert-light m-0 border-top p-0"
+         v-show="selectOrderIssueLog === item.id"
+         v-if="item.issue_logs && item.issue_logs.length > 0">
+        <div class="alert alert-light mb-0 border-top"
+             v-for="(log,logIndex) in item.issue_logs">
+            @can('订单管理-问题件-处理结果删除')
+            <div class="float-right">
+                <button class="btn btn-sm btn-outline-danger" @click="destroyLog(log,logIndex,i)">删</button>
+                <button class="btn btn-sm btn-outline-primary" @click="tagIssueLog(log)" v-show="log.tag === 0">标</button>
+            </div>
+            @endcan
+            <div>
+                <span class="mr-3">处理人:</span>
+                <span class="text-truncate"
+                      v-text="log.user ? log.user.name : ''"></span>
+            </div>
+            <div>
+                <span class="mr-3">类型:</span>
+                <span class="text-truncate"
+                      v-text="log.type"></span>
+            </div>
+            <div v-if="log.content">
+                <span class="mr-3">内容:</span>
+                <span class="text-truncate"
+                      v-text="log.content"></span>
+            </div>
+            <div>
+                <span class="mr-3">处理时间:</span>
+                <span class="text-truncate"
+                      v-text="log.created_at"></span>
+            </div>
+        </div>
+    </div>
+</transition>
+

+ 17 - 27
resources/views/order/workOrder/_logistic_fill_work_order.blade.php → resources/views/order/workOrder/_logistic_fill_work_order_modal.blade.php

@@ -1,5 +1,6 @@
 {{--快递处理丢件工单--}}
-<div class="modal fade " id="logistic-fill-work-order-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
+<div class="modal fade " id="logistic-fill-work-order-modal" tabindex="-1" role="dialog"
+     aria-labelledby="checkModalLabel"
      aria-hidden="true">
     <div class="modal-dialog modal-xl modal-dialog-centered">
         <div class="modal-content">
@@ -12,11 +13,11 @@
                     <span aria-hidden="true">&times;</span>
                 </button>
             </div>
-            <div class="modal-body">
+            <div class="modal-body p-0">
                 <div>
                     <table class="table">
                         <thead>
-                        <tr>
+                        <tr class="text-center">
                             <td>快递单号</td>
                             <td>商品</td>
                             <td>商品条码</td>
@@ -24,50 +25,39 @@
                             <td>异常数量</td>
                             <td>核实数量</td>
                             <td>核实结果</td>
-{{--                            <td>处理结果</td>--}}
                         </tr>
                         </thead>
-                        <tbody v-if="fillWorkOrder">
-                        <tr v-for="(item) in fillWorkOrder?.commodities || [] ">
-                            <td>
-                                <span v-text="item.logistic_number"></span>
+                        <tbody v-if="fillWorkOrder" class="text-center">
+                        <tr v-for="(item) in (fillWorkOrder.commodities ?  fillWorkOrder.commodities : []) ">
+                            <td v-text="item.logistic_number">
                             </td>
                             <td>
-                                <span v-text="item?.commodity?.name || ''"></span>
+                                <span v-text="item.commodity ? item.commodity.name : ''"></span>
                             </td>
                             <td>
-                                <span v-text="item?.commodity?.sku || ''"></span>
+                                <span v-text="item.commodity ? item.commodity.sku : ''"></span>
                             </td>
-                            <td>
-                                <span v-text="item.amount"></span>
+                            <td v-text="item.amount">
                             </td>
-                            <td>
-                                <span v-text="item.abnormal_amount"></span>
+                            <td v-text="item.abnormal_amount">
                             </td>
                             <td>
                                 <input type="number" class="form-control form-control-sm" v-model="item.check_amount">
                             </td>
                             <td>
                                 <select class="form-control form-control-sm"
-                                        v-if="fillWorkOrder.issue_type_name === '破损'"
-                                        v-model="item.check_result" >
+                                        v-if="'破损' === fillWorkOrder.issue_type_name"
+                                        v-model="item.check_result">
                                     <option v-for="type in ['核实破损','核实未破损']"
                                             :value="type" v-text="type"></option>
                                 </select>
-
                                 <select class="form-control form-control-sm"
-                                        v-if="['快递异常','快递丢件'].includes(fillWorkOrder.issue_type_name)"
-                                        v-model="item.check_result" >
-                                    <option v-for="type in ['已拦截']" :value="type" v-text="type"></option>
+                                        v-if="'快递异常' === fillWorkOrder.issue_type_name"
+                                        v-model="item.check_result">
+                                    <option v-for="type in expressAbnormalLogisticProcessResults" :value="type"
+                                            v-text="type"></option>
                                 </select>
                             </td>
-{{--                            <td>--}}
-{{--                                <select class="form-control form-control-sm" v-model="item.process_result">--}}
-{{--                                    <option--}}
-{{--                                        v-for="type in (['赔偿','不赔偿'])"--}}
-{{--                                        :value="type" v-text="type"></option>--}}
-{{--                                </select>--}}
-{{--                            </td>--}}
                         </tr>
                         </tbody>
                     </table>

+ 14 - 12
resources/views/order/workOrder/_owner_fill_work_order.blade.php → resources/views/order/workOrder/_owner_fill_work_order_modal.blade.php

@@ -20,11 +20,12 @@
                     {{--破损商品价格--}}
                     <div class="form-group row">
                         <label for="work-order-price"
-                               class="col-sm-2 col-form-label text-right text-primary">丢件价值</label>
+                               class="col-sm-2 col-form-label text-right text-primary">丢件商品总价值</label>
                         <div class="col-sm-10">
                             <input type="number" id="work-order-price" class="form-control"
                                    v-model="fillWorkOrder.price"
-                                   placeholder="破损商品价格">
+                                   disabled
+                                   placeholder="填写丢件商品价值后自动计算">
                         </div>
                     </div>
                     {{--快递单号--}}
@@ -60,6 +61,7 @@
                     <div class="form-group row">
                         <label for="deal-image" class="col-sm-2 col-form-label text-right text-primary">交易截图</label>
                         <div class="col-sm-10">
+                            <div><span class="text-primary">需带有付款时间,快递单号,内物详情和实付款的交易截图</span></div>
                             <div class="border border-secondary h-auto" id="deal-image" style="min-height: 75px"
                                  contenteditable="true"
                                  @paste="pasteImage($event,fillWorkOrder.dealImages)">
@@ -99,30 +101,30 @@
                         </div>
                     </div>
                     <div>
-                        <table class="table">
+                        <table class="table text-center">
                             <thead>
-                            <tr class="text-center">
+                            <tr>
                                 <td>快递单号</td>
                                 <td>商品</td>
                                 <td>商品条码</td>
                                 <td>订单数量</td>
+                                <td>丢件商品价值</td>
                                 <td>异常数量</td>
                                 <td></td>
                             </tr>
                             </thead>
                             <tbody>
-                            <tr v-for="(item,i) in  fillWorkOrder.commodities" class="text-center">
-                                <td>
-                                    <span v-text="item.logistic_number"></span>
+                            <tr v-for="(item,i) in  fillWorkOrder.commodities">
+                                <td v-text="item.logistic_number">
                                 </td>
-                                <td>
-                                    <span v-text="item.name || ''"></span>
+                                <td v-text="item.name">
                                 </td>
-                                <td>
-                                    <span v-text="item.sku || ''"></span>
+                                <td v-text="item.sku">
+                                </td>
+                                <td v-text="item.amount">
                                 </td>
                                 <td>
-                                    <span v-text="item.amount"></span>
+                                    <input type="number" class="form-control form-control-sm" v-model="item.price" @input="sumPrice(fillWorkOrder)">
                                 </td>
                                 <td>
                                     <input type="number" class="form-control form-control-sm" v-model="item.abnormal_amount">

+ 115 - 50
resources/views/order/workOrder/_work_order_details.blade.php

@@ -1,9 +1,9 @@
 <div class="alert alert-light mb-0">
     <div class="header-alert">
         <span class="text-monospace">工单详情</span>
-        <button type="button" class="btn btn-sm btn-outline-primary float-right"
+        <button type="button" class="btn  btn-outline-primary float-right"
                 v-show="selectDetailId !== item.id"
-                v-if="(item.images && item.images.length > 0) || (item.commodities && item.commodities.length>0)"
+                v-if="(item.images && item.images.length > 0) || (item.commodities && item.commodities.length>0) || item.pending_detail"
                 @click="selectDetailId = item.id">显示
         </button>
         <button type="button" class="btn btn-sm btn-outline-primary float-right"
@@ -15,13 +15,16 @@
 <transition name="fade">
     <div class="alert alert-light mb-0 border border-top"
          v-show="selectDetailId === item.id"
-         v-if="item.details && item.details.length > 0 && selectDetailId === item.id">
-        <div>
-            <span class="text-monospace" v-text="'商品价值'"></span>
-        </div>
+         v-if="item.details && item.details.length > 0">
         <div class="card-body row col-12 mb-0 pb-0"
-             v-for="(detail) in item.details">
+             v-for="(detail) in item.details" >
             <div class="col-12">
+                <span v-text="'工单类型:'+(item.issue_type ? item.issue_type.name : '')"></span>
+            </div>
+            <div v-if="Number(detail.price) !== 0" class="col-12">
+                <span class="text-monospace" v-text="'商品价值'"></span>
+            </div>
+            <div class="col-12" v-if="!['完成','未完成历史标记'].includes(detail.status) && Number(detail.price) !== 0">
                 <span v-text="detail.price"></span>
             </div>
         </div>
@@ -34,9 +37,10 @@
         <div class="col-12">
             <span class="text-monospace" v-text="'交易截图'"></span>
         </div>
-        <div class="card-body col-sm-6"
-             v-for="(dealImage,i) in item.deal_images">
-            <div class="">
+        <div class="card-group">
+        <div class="col-sm-6"
+             v-for="dealImage in item.deal_images">
+            <div class="card-body">
                 <a  target="_blank"
                     v-if="dealImage.upload_file"
                     :href="filePrefix+dealImage.upload_file.url + '.'+dealImage.upload_file.type">
@@ -46,46 +50,27 @@
                 </a>
             </div>
         </div>
-    </div>
-</transition>
-
-<transition name="fade">
-    <div class="alert alert-light mb-0 border border-top"
-         v-show="selectDetailId === item.id"
-         v-if="item.refund_image && item.refund_image.length > 0">
-        <div class="col-12">
-           <span class="text-monospace" v-text="'交易截图'"></span>
-        </div>
-        <div class="card-body col-sm-6"
-             v-for="(refund_image,i) in item.refund_image">
-            <div class="">
-                <a  target="_blank"
-                    v-if="dealImage.upload_file"
-                    :href="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type">
-                    <img class="image-w"
-                         :src="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type"
-                         alt="交易截图">
-                </a>
-            </div>
         </div>
+
     </div>
 </transition>
 
+
 <transition name="fade">
     <div class="alert alert-light mb-0 border border-top"
          v-show="selectDetailId === item.id"
-         v-if="item.refund_image && item.refund_image.length > 0">
+         v-if="item.refund_images && item.refund_images.length > 0">
         <div class="col-12">
-           <span class="text-monospace" v-text="'交易截图'"></span>
+           <span class="text-monospace" v-text="'退款截图'"></span>
         </div>
         <div class="card-body col-sm-6"
-             v-for="(refund_image,i) in item.refund_image">
+             v-for="(refundImage,i) in item.refund_images">
             <div class="">
                 <a  target="_blank"
-                    v-if="dealImage.upload_file"
-                    :href="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type">
+                    v-if="refundImage.upload_file"
+                    :href="filePrefix+refundImage.upload_file.url + '.'+refundImage.upload_file.type">
                     <img class="image-w"
-                         :src="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type"
+                         :src="filePrefix+refundImage.upload_file.url + '.'+refundImage.upload_file.type"
                          alt="交易截图">
                 </a>
             </div>
@@ -133,15 +118,14 @@
     </div>
 </transition>
 <transition name="fade">
-    {{-- 破损商品详情 --}}
     <div class="alert alert-light mb-0  border border-top"
         v-show="selectDetailId === item.id"
         v-if="item.commodities && item.commodities.length > 0">
 
         <div class="col-12">
-           <div class="text-monospace">异常商品详情</div>
+           <div class="text-monospace">商品详情</div>
         </div>
-        <div class="card-body col-12"
+        <div class="card-body col-12 pb-0"
              v-for="(commodity,i) in item.commodities">
             <div>
                 <span class="mr-3">SKU:</span>
@@ -150,38 +134,119 @@
             <div>
                 <span class="mr-3">商品名称:</span>
                 <span class="text-truncate"
-                      v-text="commodity.commodity ?.name || '' "></span>
+                      v-text="commodity.commodity ? commodity.commodity.name : '' "></span>
             </div>
             <div>
                 <span class="mr-3">数量:</span>
                 <span class="text-truncate"
                       v-text="commodity.amount"></span>
             </div>
-
-            <div v-if="item.issue_type_name !== '错漏发'">
+            <div v-if="commodity.price > 0">
+                <span class="mr-3">商品价值:</span>
+                <span class="text-truncate"
+                      v-text="commodity.price"></span>
+            </div>
+            <div v-if="'错漏发' === commodity.issue_type">
+                <span class="mr-3">客户实收数量:</span>
+                <span class="text-truncate"
+                      v-text="commodity.abnormal_amount"></span>
+            </div>
+            <div v-if="'错漏发' !== commodity.issue_type && commodity.check_amount">
                 <span class="mr-3">核实数量:</span>
                 <span class="text-truncate"
                       v-text="commodity.check_amount"></span>
             </div>
-
-            <div >
+            <div v-if="'错漏发' === commodity.issue_type">
+                <span class="mr-3">问题类型:</span>
+                <span class="text-truncate"
+                      v-text="commodity.abnormal_type"></span>
+            </div>
+            <div v-if="commodity.bao_shi_check_amount || commodity.check_result">
                 <span class="mr-3">宝时核实数量:</span>
                 <span class="text-truncate"
                       v-text="commodity.bao_shi_check_amount"></span>
             </div>
-
-            <div>
-                <span class="mr-3">核实:</span>
+            <div v-if="commodity.check_result">
+                <span class="mr-3">核实结果:</span>
                 <span class="text-truncate"
                       v-text="commodity.check_result"></span>
             </div>
-
-
+            <div v-if="commodity.process_result">
+                <span class="mr-3">处理结果:</span>
+                <span class="text-truncate"
+                      v-text="commodity.process_result"></span>
+            </div>
+            <div v-if="'错漏发' === commodity.issue_type && commodity.process_result_info">
+                <span class="mr-3">处理详情:</span>
+                <span class="text-truncate"
+                      v-text="commodity.process_result_info"></span>
+            </div>
+        </div>
+    </div>
+</transition>
+<transition name="fade">
+    <div class="alert alert-light mb-0  border border-top"
+         v-show="selectDetailId === item.id"
+         v-if="item.pending_detail && item.pending_detail.commodities.length > 0">
+        <div class="col-12">
+            <div class="text-monospace">商品详情</div>
+        </div>
+        <div class="card-body col-12 pb-0"
+             v-for="(commodity,i) in item.pending_detail.commodities">
             <div>
+                <span class="mr-3">SKU:</span>
+                <span class="text-truncate" v-text="commodity.sku"></span>
+            </div>
+            <div>
+                <span class="mr-3">商品名称:</span>
+                <span class="text-truncate"
+                      v-text="commodity.commodity ? commodity.commodity.name : '' "></span>
+            </div>
+            <div>
+                <span class="mr-3">数量:</span>
+                <span class="text-truncate"
+                      v-text="commodity.amount"></span>
+            </div>
+            <div v-if="commodity.price > 0">
+                <span class="mr-3">商品价值:</span>
+                <span class="text-truncate"
+                      v-text="commodity.price"></span>
+            </div>
+            <div v-if="'错漏发' === commodity.issue_type">
+                <span class="mr-3">客户实收数量:</span>
+                <span class="text-truncate"
+                      v-text="commodity.abnormal_amount"></span>
+            </div>
+            <div v-if="'错漏发' !== commodity.issue_type && commodity.check_amount">
+                <span class="mr-3">核实数量:</span>
+                <span class="text-truncate"
+                      v-text="commodity.check_amount"></span>
+            </div>
+            <div v-if="'错漏发' === commodity.issue_type">
+                <span class="mr-3">问题类型:</span>
+                <span class="text-truncate"
+                      v-text="commodity.abnormal_type"></span>
+            </div>
+            <div v-if="commodity.bao_shi_check_amount || commodity.check_result">
+                <span class="mr-3">宝时核实数量:</span>
+                <span class="text-truncate"
+                      v-text="commodity.bao_shi_check_amount"></span>
+            </div>
+            <div v-if="commodity.check_result">
+                <span class="mr-3">核实结果:</span>
+                <span class="text-truncate"
+                      v-text="commodity.check_result"></span>
+            </div>
+            <div v-if="commodity.process_result">
                 <span class="mr-3">处理结果:</span>
                 <span class="text-truncate"
                       v-text="commodity.process_result"></span>
             </div>
+            <div v-if="'错漏发' === commodity.issue_type && commodity.process_result_info">
+                <span class="mr-3">处理详情:</span>
+                <span class="text-truncate"
+                      v-text="commodity.process_result_info"></span>
+            </div>
         </div>
     </div>
 </transition>

+ 333 - 278
resources/views/order/workOrder/index.blade.php

@@ -8,21 +8,17 @@
                 <div class="form-inline mt-1" id="btn">
                     @can('订单管理-订单问题件生成')
                         <button type="button"
-                                class="ml-1 btn btn-outline-dark btn-sm form-control-sm  tooltipTarget"
+                                class="ml-1 btn btn-outline-dark btn-sm form-control-sm tooltipTarget"
                                 @click="createOrderIssue(null,false)" style="background: #dad7e8;">生成问题件
                         </button>
                     @endcan
                     @can('订单管理-订单问题件生成')
                         <button type="button"
-                                class="ml-1 btn btn-outline-primary btn-sm form-control-sm  tooltipTarget"
+                                class="ml-1 btn btn-outline-primary btn-sm form-control-sm tooltipTarget"
                                 @click="exportText()">导出文本
                         </button>
                     @endcan
                     @can('订单管理-工单处理-审核')
-{{--                        <button type="button"--}}
-{{--                                class="ml-1 btn btn-outline-success btn-sm form-control-sm tooltipTarget"--}}
-{{--                                @click="batchReview">批量审核--}}
-{{--                        </button>--}}
                     @endcan
                     <button type="button"
                             class="ml-1 btn btn-outline-dark btn-sm form-control-sm tooltipTarget"
@@ -30,7 +26,7 @@
                     </button>
                     @can('订单管理-工单处理-审核')
                         <button type="button"
-                                class="ml-1 btn btn-outline-success btn-sm form-control-sm  tooltipTarget"
+                                class="ml-1 btn btn-outline-success btn-sm form-control-sm tooltipTarget"
                                 @click="showEditIssueType">批量修改问题件类型
                         </button>
                     @endcan
@@ -46,7 +42,10 @@
                                 </td>
                                 <td>
                                     <span v-text="item.id"></span>
-                                    <span v-show="item.is_issue_order" class="badge badge-primary">问题件</span>
+                                    <a :href="'{{url("order/issue/index")}}'+'?orderCode='+item.orderno"
+                                       target="order/issue/index?addtime=15">
+                                        <span v-show="item.is_issue_order" class="badge badge-primary">问题件</span>
+                                    </a>
                                 </td>
                                 <td>
                                     @can('订单管理-订单问题件生成')
@@ -56,46 +55,40 @@
                                         </button>
                                     @endcan
                                     @can('订单管理-工单处理-货主编辑')
-                                        <button class="btn btn-sm btn-outline-primary"
+                                        <button class="btn btn-sm"
+                                                style="background-color: #42a887;color: #FFFFFF;border-color: #378d72"
                                                 v-if="item.issue_type_name === '快递丢件' && item.status === '货主处理'"
                                                 @click="ownerFillWorkOrder(item,i)">
-                                            信息填充
+                                            商家处理
                                         </button>
                                     @endcan
                                     @can('订单管理-工单处理-承运商编辑')
-                                        <button class="btn btn-sm btn-outline-primary"
-                                                v-if="['快递丢件','破损','快递异常'].includes(item.issue_type_name) && item.status ==='承运商处理'"
+                                        <button class="btn btn-sm"
+                                                style="background-color:#e06538;color: #FFFFFF;border-color: #9a3d23"
+                                                v-if="['破损','快递异常'].includes(item.issue_type_name) && item.status ==='承运商处理'"
                                                 @click="logisticFillWorkOrder(item,i)">
                                             快递处理
                                         </button>
-                                        <button class="btn btn-sm btn-outline-primary"
+                                        <button class="btn btn-sm"
+                                                style="background-color:#e06538;color: #FFFFFF;border-color: #9a3d23"
                                                 v-if="['拦截','信息更改'].includes(item.issue_type_name) && item.status ==='承运商处理'"
                                                 @click="logisticEndWorkOrder(item,i)">
                                             快递处理
                                         </button>
                                     @endcan
                                     @can('订单管理-工单处理-宝时编辑')
-                                        <button class="btn btn-sm btn-outline-primary"
-                                                v-if="['错漏发'].includes(item.issue_type_name) && item.status ==='宝时处理'"
+                                        <button class="btn btn-sm"
+                                                style="background-color: #38b1e0;color: #FFFFFF;border-color:#90acb6;"
+                                                v-if="['错漏发','快递丢件','破损'].includes(item.issue_type_name) && item.status ==='宝时处理'"
                                                 @click="baoShiFillWorkOrder(item,i)">
                                             宝时处理
                                         </button>
-                                        <button class="btn btn-sm btn-outline-secondary"
-                                                v-if="['快递丢件','破损'].includes(item.issue_type_name) && item.status ==='宝时处理'"
-                                                @click="baoShiFillWorkOrder(item,i)">
-                                            宝时处理
-                                        </button>
-                                        <button class="btn btn-sm btn-outline-primary"
+                                        <button class="btn btn-sm "
+                                                style="background-color: #54c337;color: #FFFFFF;border-color:#90acb6;"
                                                 v-if="'宝时终审' === item.status"
                                                 @click="baoShiReview(item,i)">
                                             终审
                                         </button>
-
-                                        {{--                                        <button class="btn btn-sm btn-outline-secondary"--}}
-                                        {{--                                                v-if="['快递丢件','破损'].includes(item.issue_type_name)">--}}
-                                        {{--                                            宝时处理--}}
-                                        {{--                                        </button>--}}
-
                                     @endcan
                                 </td>
                                 <td>
@@ -121,25 +114,28 @@
                                     <span v-text="item.status"></span>
                                 </td>
                                 <td>
-                                    <span v-text="item?.owner?.name || ''"></span>
+                                    <span v-text="item.owner? item.owner.name : ''"></span>
                                 </td>
                                 <td>
-                                    <span v-text="item?.order?.client_code || ''"></span>
+                                    <span v-text="item.order? item.order.client_code : ''"></span>
                                 </td>
                                 <td>
-                                    <div v-for="data in (item?.order?.packages || [])">
+                                    <div v-for="data in (item.order? item.order.packages : [])">
                                         <span v-text="data.logistic_number"></span>
                                     </div>
                                 </td>
                                 <td>
-                                    <span v-text="item?.logistic?.name || ''"></span>
+                                    <span v-text="item.logistic ? item.logistic.name : ''"></span>
                                 </td>
 
                                 <td>
-                                    <span v-text="item?.creator?.name || ''"></span>
+                                    <span v-text="item.creator ? item.creator.name : ''"></span>
+                                </td>
+                                <td>
+                                    <span v-text="item.result_explain ? item.result_explain: item.remark"></span>
                                 </td>
                                 <td>
-                                    <span v-text="item.remark"></span>
+                                    @include('order.workOrder._issue_logs')
                                 </td>
                                 <td class="container">
                                     <div class="row">
@@ -176,17 +172,19 @@
                                                 <div class="alert alert-light mb-0  border-top"
                                                      v-show="selectLog === item.id"
                                                      v-for="(log,index) in item.logs" v-bind:key="item.id+':'+index">
-                                                    <div>
-                                                        <span class="text-monospace">创建人:</span>
-                                                        <span v-text="log?.creator?.name"></span>
-                                                    </div>
-                                                    <div>
-                                                        <span class="text-monospace">创建时间:</span>
-                                                        <span v-text="log.created_at"></span>
-                                                    </div>
-                                                    <div>
-                                                        <span class="text-monospace">内容:</span>
-                                                        <span v-text="log.content"></span>
+                                                    <div class="card-body col-12 p-0">
+                                                        <div>
+                                                            <span class="text-monospace">创建人:</span>
+                                                            <span v-text="log.creator? log.creator.name : ''"></span>
+                                                        </div>
+                                                        <div>
+                                                            <span class="text-monospace">创建时间:</span>
+                                                            <span v-text="log.created_at"></span>
+                                                        </div>
+                                                        <div>
+                                                            <span class="text-monospace">内容:</span>
+                                                            <span v-text="log.content"></span>
+                                                        </div>
                                                     </div>
                                                 </div>
                                             </transition-group>
@@ -201,12 +199,12 @@
                 </div>
             </div>
             @can('订单管理-工单处理-审核')
-                @include('order.workOrder._edit_issue_type')
+{{--                @include('order.workOrder._edit_issue_type')--}}
             @endcan
-            @include('order.workOrder._bao_shi_review')
-            @include('order.workOrder._baoshi_fill_work_order')
-            @include('order.workOrder._logistic_fill_work_order')
-            @include('order.workOrder._owner_fill_work_order')
+            @include('order.workOrder._bao_shi_review_modal')
+            @include('order.workOrder._bao_shi_fill_work_order_modal')
+            @include('order.workOrder._logistic_fill_work_order_modal')
+            @include('order.workOrder._owner_fill_work_order_modal')
         </div>
     </div>
 @endsection()
@@ -221,11 +219,14 @@
         .fade-leave-active {
             transition: opacity .1s;
         }
+
         .fade-enter, .fade-leave-to {
             opacity: 0;
         }
+
         .image-div {
         }
+
         .image-w {
             width: 100%;
         }
@@ -235,7 +236,6 @@
             el: "#list",
             data: {
                 workOrders: {!! $workOrders->toJson() !!}['data'],
-
                 form: null,
                 logistics: [
                         @foreach($logistics as $logistic)
@@ -260,6 +260,7 @@
                 ],
                 workOrder: {
                     id: null,
+                    detail_id:null,
                     reissue_logistic_number: null, // 补发单号
                     logistic_number: null, // 丢件快递单号
                     refundImages: [], // 退款图
@@ -267,6 +268,7 @@
                 },
                 fillWorkOrder: {
                     id: null,
+                    detail_id:null,
                     reissue_logistic_number: null, // 补发单号
                     logistic_number: null, // 丢件快递单号
                     refundImages: [], // 退款图
@@ -274,27 +276,34 @@
                     commodities: [],
                 },
                 workOrderStatus: ['创建', '信息已填写', '快递已处理', '工单完成'],
-                reviewWorkOrder:{
-                    id:null,
-                    commodities:[],
-                    issue_type_name:null,
+                reviewWorkOrder: {
+                    id: null,
+                    detail_id:null,
+                    commodities: [],
+                    issue_type_name: null,
                 },
-                selectTr: null,
-                // selectOrderPackage: null,
-                // selectOrder: null,
-                // selectLogisticLogId: null,
-                // selectBaoShiLogId: null,
-                selectDetailId: null,
-                selectOrderIssue: null,
+                selectTr: null,                 // table 行
+                selectDetailId: null,           // 详情
+                selectCreateOrderIssueLog: null,// 创建问题件处理信息
+                selectOrderIssueLog: null,      // 问题件处理信息
+                selectOrderIssue: null,         // 问题件
                 selectIssueType: '',
-                selectLog: null,
-                selectIndex: null,  // 选中工单
+                selectLog: null,                // 工单日志
+                selectIndex: null,              // 选中工单
                 filePrefix: "{{asset("/storage")}}",
                 damagedResults: ['核实破损', '核实未破损'],
                 mistakeResults: ['核实少发', '核实多发', '核实未错漏发'],
                 processResults: ['核实破损', '核实未破损'],
                 mistakeProcessResults: ['少发', '多发,客户买下', '多发,客户退回', '少发,不补发', '核实未错漏发'],
-                damagedProcessResults: ['赔偿','不赔偿'],
+                damagedProcessResults: ['赔偿', '不赔偿'],
+                expressAbnormalLogisticProcessResults: ['已拦截', '已催件'],
+                processResultInfo: {
+                    "少发": {'0': '宝时补发(商家不做单)'},
+                    "多发,客户买下": {'0': '商家做出库单(物流选自提,宝时不发货)'},
+                    "多发,客户退回": {'0': '客户自行退回(提供退回单号)', '1': '宝时上门取件(提供寄件信息,地址,联系人,电话)'},
+                    '少发,不补发': {'0': '商家做入库单,选择明细和数量'},
+                    '核实未错漏发': {'0': ''},
+                },
             },
             mounted() {
                 let data = [[
@@ -331,6 +340,12 @@
                     {name: 'review_at_end', type: 'time', tip: ['终审结束日期', '时间']},
                     {name: 'order_issue_type', type: 'select', placeholder: '问题件类型', data: this.orderIssueTypes},
                     {name: 'client_code', type: 'input', placeholder: '客户订单号'},
+                    {
+                        name: 'status', type: 'select', placeholder: '工单当前处理人',
+                        data: [{name: '宝时处理', value: '宝时处理'},
+                            {name: '货主处理', value: '货主处理'},
+                            {name: '承运商处理', value: '承运商处理'},]
+                    },
                     {name: 'is_end', type: 'checkbox', tip: '是否已拦截', data: [{name: 'ture', value: '已完成'}]},
                 ]];
                 this.form = new query({
@@ -349,7 +364,8 @@
                     {name: 'logistic_numbers', value: '快递单号'},
                     {name: 'logistic', value: '承运商'},
                     {name: 'creator', value: '创建人'},
-                    {name: 'remark', value: '备注'},
+                    {name: 'remark', value: '情况说明'},
+                    {name: 'order_issue_log', value: '处理结果'},
                     {
                         name: 'ab_operation', type: 'multi', title: "其他操作", rows: [
                                 @can('订单管理-工单处理-删除')
@@ -392,44 +408,111 @@
                 },
             },
             methods: {
-                filterItem(items, name, value) {
-                    return items.filter(item => {
-                        return item[name].toString() === value.toString();
-                    })
+                sortOrder(workOrder) {
+                    workOrder.detail_infos = this.groupDetails(workOrder);                          // 工单详情
+                    workOrder.package_images = this.groupImages(workOrder, '外包装图片');            // 外包装图片
+                    workOrder.commodity_images = this.groupImages(workOrder, '内物破碎图片');        // 内物破碎图片
+                    workOrder.deal_images = this.groupImages(workOrder, '交易截图');                // 交易截图
+                    workOrder.refund_images = this.groupImages(workOrder, '退款成功截图');           //退款成功截图
+                    workOrder.issue_logs = this.groupOrderIssueLogs(workOrder);                    // 问题件日志
+                    workOrder.logs = this.groupLogs(workOrder);                                    // 工单日志
+                    workOrder.commodities = this.groupCommodities(workOrder);
+                    workOrder.issue_type_name = workOrder.issue_type ? workOrder.issue_type.name : '';  // 工单类型
+                    workOrder.pending_detail =this.groupPendingDetail(workOrder);
                 },
-                groupImages(workOrder) {
-                    if (!workOrder.images) return;
-                    workOrder.package_images = this.filterItem(workOrder.images, 'type', 1);
-                    workOrder.commodity_images = this.filterItem(workOrder.images, 'type', 2);
-                    workOrder.deal_images = this.filterItem(workOrder.images, 'type', 3);
-                    workOrder.refund_images = this.filterItem(workOrder.images, 'type', 4);
+                groupPendingDetail(workOrder){
+                    let detail = workOrder.details.find(item=>{
+                        return !['完成','标记'].includes(item.tag);
+                    });
+                    if (!detail) return null;
+                    return {
+                        id:workOrder.id,
+                        detail_id:detail.id,
+                        commodities:detail.commodities,
+                        issue_type_name:detail.issue_type ? detail.issue_type.name : '',
+                        status:detail.status,
+                        reissue_logistic_number:detail.reissue_logistic_number,
+                        logistic_number:detail.logistic_number,
+                        price:detail.price,
+                        return_logistic_number:detail.return_logistic_number,
+                        remark:detail.remark,
+                        tag:detail.tag,
+                    };
                 },
-                sortOrder(workOrder) {
-                    this.groupImages(workOrder);
-                    workOrder.issue_type_name = workOrder?.issue_type?.name || '';
-                    if (workOrder['order_issue']) {
-                        workOrder.result_explain = workOrder['order_issue'].result_explain;
-                        if (workOrder['order_issue']['issue_type']) {
-                            workOrder.issue_order_type = workOrder['order_issue']['issue_type']['name'];
-                        }
-                        if (workOrder['order_issue'].logs) {
-                            workOrder.issue_logs = this.mapLogs(workOrder['order_issue'].logs);
+                groupCommodities(workOrder,isCurrent = true){
+                    let commodities = [];
+                    workOrder.details.forEach(detail=>{
+                        commodities.push(...(detail.commodities ?? []))
+                    });
+                    commodities = commodities.filter(item=>{
+                        if (!isCurrent){
+                            return !['完成','标记'].includes(item.tag);
+                        } else {
+                            return ['完成','标记'].includes(item.tag);
                         }
-                    }
-                    if (!workOrder.order.packages) return;
-                    workOrder.order.packages.forEach(item => {
-                        this.sortTransfer(item)
                     })
+                    return commodities;
+                },
+                groupOrderIssueLogs(workOrder) {
+                    workOrder.current_issue_type = workOrder.issue_type ? workOrder.issue_type.name : '';
+                    let logs = workOrder.order_issue ? (workOrder.order_issue.logs ? workOrder.order_issue.logs : []) : [];
+                    return logs.sort((perv, cur) => {
+                        let prevT = new Date(perv.created_at), curT = new Date(cur.created_at);
+                        if (prevT > curT) {
+                            return -1;
+                        } else if (prevT === curT) {
+                            return 0;
+                        } else if (prevT < curT) {
+                            return 1;
+                        }
+                    });
                 },
-                mapLogs(logs) {
-                    return logs.map(item => {
+                groupDetails(workOrder) {
+                    return workOrder.details.map(item => {
                         return {
-                            username: item.user?.name || '',
-                            content: item.content,
-                            created_at: item.created_at
+                            id: item.id,
+                            issue_type: item.issue_type ? item.issue_type.name : '',  // 工单类型
+                            price: item.price,                                          // 商品价值总价
+                            reissue_logistic_number: item.reissue_logistic_number,      // 补发单号
+                            return_logistic_number: item.return_logistic_number,        // 退回单号
+                            logistic_number: item.logistic_number,                      // 快递单号
+                            status: item.status,                                        // 工单状态
+                            created_at: item.created_at,                                // 创建时间
                         };
                     });
                 },
+                groupDetailCommodities(detail) {
+                    return detail.commodities.map(item => {
+                        item.commodity_name = item.commodity ? item.commodity.name : '';
+                        return item;
+                    });
+                },
+                groupImages(workOrder, type) {
+                    let images = [];
+                    workOrder.details.forEach(detail => {
+                        let imageList = detail.images.filter(item => {
+                            return item.type === type;
+                        })
+                        images.push(...imageList);
+                    });
+                    return images;
+                },
+                groupLogs(workOrder) {
+                    let logs = [];
+                    workOrder.details.forEach(detail => {
+                        let logList = detail.logs.map(item => {
+                            return {
+                                id: item.id,                     // id
+                                created_at: item.created_at,     // 创建时间
+                                creator: item.creator,           // 创建人
+                                type: item.type,                 // 类型
+                                content: item.content,           // 内容
+                            };
+                        });
+                        logs.push(...logList);
+                    });
+                    return logs;
+                },
                 sortTransfer(item) {
                     if (!("transfer_status" in item)) return;
                     if (item.transfer_status == null || !(item.transfer_status instanceof Array)) return;
@@ -441,28 +524,12 @@
                         return 0;
                     });
                 },
-                {{--review(item, i) {--}}
-                {{--    let url = '{{route('workOrder.reviewApi')}}';--}}
-                {{--    let data = {id: item.id};--}}
-                {{--    window.axios.post(url, data).then(res => {--}}
-                {{--        if (res.data.success) {--}}
-                {{--            res.data.data.is_issue_order = item.is_issue_order;--}}
-                {{--            this.sortOrder(res.data.data);--}}
-                {{--            this.$set(this.workOrders, i, res.data.data);--}}
-                {{--            window.tempTip.showSuccess("审核完成");--}}
-                {{--        } else {--}}
-                {{--            window.tempTip.show(res.data.message ? res.data.message : '审核异常');--}}
-                {{--        }--}}
-                {{--    }).catch(err => {--}}
-                {{--        window.tempTip.show(err)--}}
-                {{--    })--}}
-                {{--},--}}
                 createOrderIssue(item, tag) { // 生成问题件
                     let url = '{{route('workOrder.buildOrderIssueApi')}}';
                     let data = {};
                     if (tag) data.ids = [item.id];
                     else data.ids = checkData;
-                    window.tempTip.confirm('是否生成对应的问题件',()=>{
+                    window.tempTip.confirm('是否生成对应的问题件', () => {
                         window.tempTip.waitingTip('生成中........');
                         window.axios.post(url, data).then(res => {
                             if (res.data.success) {
@@ -479,7 +546,6 @@
                             window.tempTip.show(err)
                         });
                     })
-
                 },
                 replaceWorkOrder(workOrders) {
                     let data = [];
@@ -518,7 +584,7 @@
                 getExportText(item) {
                     if (!item.order || !item.order.packages) return '';
                     let message = '';
-                    let issue_type = item['issue_type']?.name || '';
+                    let issue_type = item['issue_type'] ? item['issue_type'].name : '';
                     switch (issue_type) {
                         case '拦截':
                             message = this.interceptMessage(item);
@@ -535,9 +601,9 @@
                 interceptMessage(item) {
                     let message = '';
                     let order = item.order;
-                    let order_packages = item.order?.packages || [];
-                    let logistic_code = item.order ?.['logistic']?.code || ''; // 承运商编码
-                    let logistic_name = item.order ?.['logistic']?.name || ''; // 承运商名称
+                    let order_packages = item.order ? item.order.packages : [];
+                    let logistic_code = item.order ? (item.order['logistic'] ? item.order['logistic'].code : '') : ''; // 承运商编码
+                    let logistic_name = item.order ? (item.order['logistic'] ? item.order['logistic'].name : '') : ''; // 承运商名称
 
                     let {consignee_name, consignee_phone, address} = order;
                     let order_adder = `${consignee_name}  ${consignee_phone}  ${address}`;
@@ -550,14 +616,14 @@
                             if (item) message += `${logistic_name}  ${logistic_number}  ${order_adder}\n`;
                         }
                     });
-                    message = message.trim('\n') + ' ——拦截\n';
+                    message = message.trim() + ' ——拦截\n';
                     return message;
                 },
                 modificationMessage(item) {
                     let message = '';
                     let {remark, order} = item;
-                    let order_packages = item.order?.packages || [];
-                    let logistic_code = item.order ?.['logistic']?.code || '';
+                    let order_packages = item.order ? item.order.packages : [];
+                    let logistic_code = item.order ? (item.order['logistic'] ? item.order['logistic'].code : '') : '';
 
                     const {consignee_name, consignee_phone, province, city, district, address} = order;
                     let adder = `${consignee_name}  ${consignee_phone}  ${province}  ${city}  ${district}  ${address}`;
@@ -672,7 +738,7 @@
                     })
                 },
                 destroy(item, i) {
-                    window.tempTip.confirm('是否删除当前工单',()=>{
+                    window.tempTip.confirm('是否删除当前工单', () => {
                         let url = '{{url('apiLocal/workOrder/')}}' + '/' + item.id;
                         window.tempTip.waitingTip('删除.........');
                         window.axios.delete(url).then(res => {
@@ -691,17 +757,19 @@
                     })
                 },
                 spliceImage(i, images) {
-                    window.tempTip.confirm('是否取消选择该图片',()=>{
+                    window.tempTip.setIndex(1999);
+                    window.tempTip.confirm('是否取消选择该图片', () => {
                         images.splice(i, 1);
                     });
                 },
                 clearWorkOrder(item = null, index = null) {
                     this.fillWorkOrder.id = item ? item.id : null;
+                    this.fillWorkOrder.detail_id = item ? this.getCurrentWorkOrderDetailId(item) : null;
                     this.selectIndex = index ? index : null;
-                    this.fillWorkOrder.reissue_logistic_number = null; // 补发单号
-                    this.fillWorkOrder.logistic_number = null; // 补发单号
-                    this.fillWorkOrder.dealImages = []; // 交易图
-                    this.fillWorkOrder.refundImages = []; // 退款图
+                    this.fillWorkOrder.reissue_logistic_number = null;      // 补发单号
+                    this.fillWorkOrder.logistic_number = null;              // 补发单号
+                    this.fillWorkOrder.dealImages = [];                     // 交易图
+                    this.fillWorkOrder.refundImages = [];                   // 退款图
                     this.fillWorkOrder.commodities = [];
                 },
                 setFormDataImagePrefix(formData, prefix, images) {
@@ -714,136 +782,6 @@
                         return item.file;
                     })
                 },
-                // showEditLog(item, index, type) {
-                //     this.processLog.type = type;
-                //     this.processLog.index = index;
-                //     this.processLog.work_order_id = item.id;
-                //     this.processLog.indemnity = null;
-                //     this.processLog.is_indemnity = null;
-                //     this.processLog.remark = null;
-                //     this.processLog.indemnitor = null;
-                //     $("#work-order-process-log-modal").modal('show');
-                // },
-                {{--storeLogisticProcessLog() {--}}
-                {{--    let url = "{{route('workOrderProcessLog.logisticLogApi')}}";--}}
-                {{--    let data = {--}}
-                {{--        indemnity: this.processLog.indemnity,--}}
-                {{--        work_order_id: this.processLog.work_order_id,--}}
-                {{--        is_indemnity: this.processLog.is_indemnity,--}}
-                {{--        remark: this.processLog.remark,--}}
-                {{--    };--}}
-                {{--    if (!this.verifiedProcessLog()) return;--}}
-                {{--    window.tempTip.setDuration(9999);--}}
-                {{--    window.tempTip.setIndex(1999);--}}
-                {{--    window.tempTip.waitingTip('操作中请稍后');--}}
-                {{--    window.axios.post(url, data).then(res => {--}}
-                {{--        window.tempTip.cancelWaitingTip();--}}
-                {{--        window.tempTip.setIndex(1999);--}}
-                {{--        window.tempTip.setDuration(2000);--}}
-                {{--        if (res.data.success) {--}}
-                {{--            window.tempTip.showSuccess('创建成功');--}}
-                {{--            this.$set(this.workOrders[this.processLog.index], 'logistic_log', res.data.data);--}}
-                {{--            $('#work-order-process-log-modal').modal('hide');--}}
-                {{--        } else {--}}
-                {{--            window.tempTip.show(res.data.message ? res.data.message : '创建异常,刷新页面重试');--}}
-                {{--        }--}}
-                {{--    }).catch(err => {--}}
-                {{--        window.tempTip.setIndex(1999);--}}
-                {{--        window.tempTip.setDuration(2000);--}}
-                {{--        window.tempTip.show(err);--}}
-                {{--    });--}}
-                {{--},--}}
-                {{--storeProcessLog() {--}}
-                {{--    let url = "{{route('workOrderProcessLog.LogApi')}}";--}}
-                {{--    let data = {--}}
-                {{--        indemnity: this.processLog.indemnity,--}}
-                {{--        work_order_id: this.processLog.work_order_id,--}}
-                {{--        is_indemnity: this.processLog.is_indemnity,--}}
-                {{--        remark: this.processLog.remark,--}}
-                {{--        indemnitor: this.processLog.indemnitor,--}}
-                {{--    };--}}
-                {{--    if (!this.verifiedProcessLog()) return;--}}
-                {{--    window.tempTip.setDuration(9999);--}}
-                {{--    window.tempTip.setIndex(1999);--}}
-                {{--    window.tempTip.waitingTip('操作中请稍后');--}}
-                {{--    window.axios.post(url, data).then(res => {--}}
-                {{--        window.tempTip.cancelWaitingTip();--}}
-                {{--        window.tempTip.setDuration(2000);--}}
-                {{--        if (res.data.success) {--}}
-                {{--            window.tempTip.showSuccess('创建成功');--}}
-                {{--            this.$set(this.workOrders[this.processLog.index], 'process_log', res.data.data);--}}
-                {{--            $('#work-order-process-log-modal').modal('hide');--}}
-                {{--        } else {--}}
-                {{--            window.tempTip.show(res.data.message ? res.data.message : '创建异常,刷新页面重试');--}}
-                {{--        }--}}
-                {{--    }).catch(err => {--}}
-                {{--        window.tempTip.setDuration(2000);--}}
-                {{--        window.tempTip.show(err);--}}
-                {{--    });--}}
-                {{--},--}}
-                updateWorkOrderStatus(item, e, i) {
-                    let url = "{{route('workOrder.updateStatusApi')}}";
-                    let data = {
-                        id: item.id,
-                        work_order_status: e.target.value
-                    }
-                    window.tempTip.waitingTip('处理中......');
-                    window.tempTip.setDuration('1999');
-                    window.axios.post(url, data).then(res => {
-                        window.tempTip.cancelWaitingTip();
-                        window.tempTip.setDuration('1999');
-                        if (res.data.success) {
-                            item.work_order_status = data.work_order_status;
-                            window.tempTip.showSuccess('修改成功');
-                            return;
-                        }
-                        window.tempTip.show(res.data.message ? res.data.message : '修改失败');
-                    }).catch(err => {
-                        window.tempTip.show('修饰异常:' + err);
-                    });
-                },
-                verifiedProcessLog() {   // 校验处理信息
-                    window.tempTip.setIndex(1999);
-                    window.tempTip.setDuration(2000);
-                    if (this.processLog.is_indemnity === null) {
-                        window.tempTip.show('选择处理方式');
-                        return false;
-                    }
-                    if (parseInt(this.processLog.type) === 1 && this.processLog.indemnitor == null) {
-                        window.tempTip.show('指定赔偿方');
-                        return false;
-                    }
-                    if (this.processLog.is_indemnity === '1') {
-                        if (!this.processLog.indemnity) {
-                            window.tempTip.show('填写赔偿金额');
-                            return false;
-                        }
-                    } else if (this.processLog.is_indemnity === '2') {
-                        if (this.processLog.remark === null || this.processLog.remark.trim(' ').length === 0) {
-                            window.tempTip.show('填写不赔偿理由');
-                            return false;
-                        }
-                    }
-                    return true;
-                },
-                logisticUpdateWorkOrderStatus(item, e) {
-                    let url = "{{route('workOrder.logisticUpdateStatusApi')}}";
-                    let data = {id: item.id, work_order_status: e.target.value};
-                    window.tempTip.waitingTip('处理中......');
-                    window.tempTip.setDuration('1999');
-                    window.axios.post(url, data).then(res => {
-                        window.tempTip.cancelWaitingTip();
-                        window.tempTip.setDuration('1999');
-                        if (res.data.success) {
-                            item.work_order_status = data.work_order_status;
-                            window.tempTip.showSuccess('修改成功');
-                            return;
-                        }
-                        window.tempTip.show(res.data.message ? res.data.message : '修改失败');
-                    }).catch(err => {
-                        window.tempTip.show('修饰异常:' + err);
-                    });
-                },
                 pasteImage(event, imageArray) {
                     for (let i = 0; i < event.clipboardData.items.length; i++) {
                         let item = event.clipboardData.items[i];
@@ -873,7 +811,7 @@
                     });
                 },
                 logisticFillWorkOrder(item, index) {
-                    this.fillWorkOrder = JSON.parse(JSON.stringify(item));
+                    this.fillWorkOrder = JSON.parse(JSON.stringify(item.pending_detail));
                     this.selectIndex = index;
                     $("#logistic-fill-work-order-modal").modal('show');
                 },
@@ -881,6 +819,7 @@
                     let url = "{{route("workOrder.commodity.logisticUpdateApi")}}";
                     let formData = new FormData();
                     formData.append('id', this.fillWorkOrder.id);
+                    formData.append('detail_id', this.fillWorkOrder.detail_id);
                     this.fillWorkOrderCommodity(formData);
                     window.tempTip.setIndex(1999);
                     window.axios.post(url, formData, {'Content-Type': 'multipart/form-data'})
@@ -892,7 +831,7 @@
                                 $("#logistic-fill-work-order-modal").modal('hide');
 
                             } else {
-                                window.tempTip.show(res.data?.message || '');
+                                window.tempTip.show(res.data.message ? res.data.message : '修改异常');
                             }
                         }).catch(err => {
                         window.tempTip.show(err);
@@ -900,27 +839,32 @@
                 },
                 logisticEndWorkOrder(item, index) {
                     let url = "{{route("workOrder.logistic.endApi")}}";
-                    window.axios.post(url, {id: item.id}).then(res => {
+                    let data = {
+                        id:item.id,
+                        detail_id:this.getCurrentWorkOrderDetailId(item),
+                    };
+                    window.axios.post(url, data).then(res => {
                         if (res.data.success) {
                             window.tempTip.showSuccess('工单已处理');
                             this.sortOrder(res.data.data);
                             this.$set(this.workOrders, index, res.data.data);
                         } else {
-                            window.tempTip.show(res.data?.message || '工单处理异常刷新后重试');
+                            window.tempTip.show(res.data.message ? res.data.message : '工单处理异常刷新后重试');
                         }
                     }).catch(err => {
                         window.tempTip.show(err || '工单处理异常刷新后重试');
                     });
                 },
                 baoShiFillWorkOrder(item, index) {
-                    this.fillWorkOrder = JSON.parse(JSON.stringify(item));
+                    this.fillWorkOrder = JSON.parse(JSON.stringify(item.pending_detail));
                     this.selectIndex = index;
-                    $('#baoshi-fill-work-order-modal').modal('show');
+                    $('#bao-shi-fill-work-order-modal').modal('show');
                 },
                 baoShiUpdateCommodities() {
-                    let url = "{{route("workOrder.commodity.baoShiUpdateCommodities")}}";
+                    let url = "{{route("workOrder.commodity.baoShiUpdateApi")}}";
                     let formData = new FormData();
                     formData.append('id', this.fillWorkOrder.id);
+                    formData.append('detail_id', this.fillWorkOrder.detail_id);
                     this.fillWorkOrderCommodity(formData)
                     window.tempTip.setIndex(1999);
                     window.axios.post(url, formData, {'Content-Type': 'multipart/form-data'})
@@ -929,9 +873,9 @@
                                 this.sortOrder(res.data.data);
                                 this.$set(this.workOrders, this.selectIndex, res.data.data);
                                 window.tempTip.showSuccess('修改成功');
-                                $("#baoshi-fill-work-order-modal").modal('hide');
+                                $("#bao-shi-fill-work-order-modal").modal('hide');
                             } else {
-                                window.tempTip.show(res.data?.message || '');
+                                window.tempTip.show(res.data.message ? res.data.message : '修改异常');
                             }
                         }).catch(err => {
                         window.tempTip.show(err);
@@ -942,7 +886,11 @@
                     this.getOrderCommodity(item).then(res => {
                         window.tempTip.cancelWaitingTip();
                         this.clearWorkOrderWith(item, index);
-                        this.fillWorkOrder.commodities = res;
+                        this.fillWorkOrder.commodities = res.map(item => {
+                            item.abnormal_amount = item.amount;
+                            item.tag = 0;
+                            return item;
+                        });
                         $("#owner-fill-work-order-modal").modal('show');
                     }).catch(err => {
                         window.tempTip.cancelWaitingTip();
@@ -950,7 +898,8 @@
                     });
                 },
                 clearWorkOrderWith(item, index) {
-                    this.fillWorkOrder.id = item?.id;
+                    this.fillWorkOrder.id = item.id;
+                    this.fillWorkOrder.detail_id = this.getCurrentWorkOrderDetailId(item);
                     this.selectIndex = index;
                     this.fillWorkOrder.reissue_logistic_number = null; // 补发单号
                     this.fillWorkOrder.logistic_number = null; // 补发单号
@@ -960,7 +909,7 @@
                 getOrderCommodity(item) {
                     return new Promise((resolve, reject) => {
                         let url = '{{route('order.commodity.getCommoditiesApi')}}';
-                        let data = {orderNo: item?.order?.code};
+                        let data = {orderNo: item ? (item.order ? item.order.code : '') : ''};
                         window.axios.post(url, data).then(res => {
                             if (res.data.success) {
                                 resolve(res.data.data);
@@ -970,8 +919,10 @@
                     });
                 },
                 ownerUpdateWorkOrder() {
+                    if (!this.checkFillLossWorkOrder()) return;
                     let formData = new FormData();
                     formData.append('id', this.fillWorkOrder.id);
+                    formData.append('detail_id', this.fillWorkOrder.detail_id);
                     formData.append('reissue_logistic_number', this.fillWorkOrder.reissue_logistic_number);
                     formData.append('logistic_number', this.fillWorkOrder.logistic_number);
                     formData.append('price', this.fillWorkOrder.price);
@@ -982,6 +933,25 @@
                     this.fillWorkOrderCommodity(formData);
                     this.ownerFillLossWorkOrder(formData);
                 },
+                checkFillLossWorkOrder() {
+                    window.tempTip.setIndex(2000);
+                    window.tempTip.setDuration(1500);
+                    let message = null;
+                    let abnormal_amount_is_null = this.fillWorkOrder.commodities.filter(item => {
+                        return Number(item.abnormal_amount) === 0;
+                    }).length > 0;
+                    if (abnormal_amount_is_null) message = '异常数量不能为空';
+                    if (this.fillWorkOrder.refundImages.length === 0) message = '退款截图为必需项!';
+                    if (this.fillWorkOrder.reissue_logistic_number !== null) {
+                    } else if (this.fillWorkOrder.dealImages.length === 0) {
+                        message = '交易截图为必需项!';
+                    }
+                    if (message) {
+                        window.tempTip.show(message);
+                        return false;
+                    }
+                    return true;
+                },
                 fillWorkOrderCommodity(formData) {
                     this.fillWorkOrder.commodities.forEach(e => {
                         formData.append("commodities[]", JSON.stringify(e));
@@ -1004,33 +974,40 @@
                         window.tempTip.show(err);
                     });
                 },
-                baoShiReview(item,i){ // 宝时终审
-                    this.reviewWorkOrder.commodities = JSON.parse(JSON.stringify(item.commodities));
-                    this.reviewWorkOrder.issue_type_name = item.issue_type_name;
-                    this.reviewWorkOrder.id = item.id;
+                baoShiReview(item, i) { // 宝时终审
+                    this.reviewWorkOrder = JSON.parse(JSON.stringify(item.pending_detail));
                     this.selectIndex = i;
                     $('#bao-shi-review-modal').modal('show');
                 },
-                review(){
+                getCurrentWorkOrderDetailId(workOrder){
+                    let items = workOrder.details.filter(item=>{
+                        return !['标记','完成'].includes(item.tag);
+                    });
+                    if (items.length === 0) return null;
+                    let item = items.shift();
+                    return item.id;
+                },
+                review() {
                     let formData = new FormData();
-                    formData.append('id',this.reviewWorkOrder.id);
+                    formData.append('id', this.reviewWorkOrder.id);
+                    formData.append('detail_id', this.reviewWorkOrder.detail_id);
                     this.reviewWorkOrderCommodity(formData);
                     let url = "{{route('workOrder.baoShi.reviewApi')}}";
                     window.tempTip.setIndex(1999);
                     window.tempTip.waitingTip('审核中');
-                    window.axios.post(url,formData).then(res=>{
+                    window.axios.post(url, formData).then(res => {
                         window.tempTip.cancelWaitingTip();
-                        if (res.data.success){
+                        if (res.data.success) {
                             this.sortOrder(res.data.data);
-                            this.$set(this.workOrders,this.selectIndex,res.data.data);
+                            this.$set(this.workOrders, this.selectIndex, res.data.data);
                             window.tempTip.setIndex(1999);
                             window.tempTip.showSuccess('审核完成');
                         } else {
                             window.tempTip.setIndex(1999);
-                            window.tempTip.show(res.data?.message || '审核异常刷新后重试');
+                            window.tempTip.show(res.data.message ? res.data.message : '审核异常刷新后重试');
                         }
                         $('#bao-shi-review-modal').modal('hide');
-                    }).catch(err=>{
+                    }).catch(err => {
                         window.tempTip.cancelWaitingTip();
                         window.tempTip.setIndex(1999);
                         window.tempTip.show(err);
@@ -1041,6 +1018,84 @@
                         formData.append("commodities[]", JSON.stringify(e));
                     });
                 },
+                computeBaoShiCheckResult(item) {
+                    let amount = Number(item.amount);
+                    let bao_shi_check_amount = Number(item['bao_shi_check_amount']);
+                    item.check_result = amount === bao_shi_check_amount ? '核实未错漏发' : (amount < bao_shi_check_amount ? '核实多发' : '核实少发')
+                },
+                sumPrice(workOrder) {
+                    workOrder.price = workOrder.commodities.reduce((prev, cur) => {
+                        return Number(prev) + Number(cur.price);
+                    }, 0);
+                },
+                createOrderIssueLog(orderIssueId,item){
+                    let log_text = document.getElementById(orderIssueId+'_log_text');
+                    let log_check = document.getElementById(orderIssueId+'_log_check');
+                    let data = {
+                        id:item.order_issue.id,
+                        order_issue_id:orderIssueId,
+                        content:log_text.value,
+                        tag:log_check.checked ? 1 : 0,
+                    };
+                    let url = "{{route("order.issue.log.storeApi")}}";
+                    window.tempTip.waitingTip("创建中");
+                    window.tempTip.setDuration(1500);
+                    window.axios.post(url,data).then(res=>{
+                        window.tempTip.cancelWaitingTip();
+                        if (res.data.success){
+                            item.issue_logs.unshift(res.data.data);
+                            window.tempTip.showSuccess('添加成功');
+                            this.selectCreateOrderIssueLog = null;
+                            log_text.value = null;
+                            log_check.checked = false;
+                        } else {
+                            window.tempTip.setDuration(2000);
+                            window.tempTip.show(res.data.fail_info);
+                        }
+                    }).catch(err=>{
+                        window.tempTip.cancelWaitingTip();
+                        tempTip.setDuration(4000);
+                        tempTip.show('网络异常:' + err);
+                    });
+                },
+                destroyLog(log,index,i){
+                    if (!confirm('是否删除当前记录')) return;
+                    if (log.type === '创建') {
+                        tempTip.show('创建记录不能删除');
+                        return;
+                    }
+                    let url = "{{route("order.issue.log.destroyApi")}}";
+                    let data = {id:log.id};
+                    window.tempTip.setIndex('1999');
+                    window.axios.post(url,data).then(res=>{
+                        if (res.data.success){
+                            this.$delete(this.workOrders[i].issue_logs,index);
+                            tempTip.setDuration(1500);
+                            tempTip.showSuccess('删除成功');
+                        } else {
+                            tempTip.setDuration(2000);
+                            tempTip.show('删除失败:' + res.data.fail_info);
+                        }
+                    }).catch(err=>{
+                        tempTip.setDuration(2500);
+                        tempTip.show('网络异常:' + err);
+                    });
+                },
+                tagIssueLog(log){
+                    let url = '{{route('order.issue.log.tagApi')}}';
+                    let data = {id: log.id};
+                    if (!confirm('是否标记当前记录客户不可见')) return;
+                    window.axios.post(url, data).then(res => {
+                        if (res.data.success) {
+                            window.tempTip.showSuccess('标记成功');
+                            log.tag = 1;
+                        } else {
+                            window.tempTip.show(res.data.message ? res.data.message : '标记出现异常');
+                        }
+                    }).catch(err => {
+                        window.tempTip.show(err);
+                    });
+                }
             },
         });
     </script>

+ 21 - 30
routes/apiLocal.php

@@ -83,6 +83,8 @@ Route::group(['prefix' => 'order'], function () {
         Route::post('archiveOrderIssue','OrderIssueController@archiveOrderIssueApi');
         Route::post('destroySecondLogisticNumber','OrderIssueController@destroySecondLogisticNumberApi');
 
+        Route::post('batchUpdate/finalStatus','OrderIssueController@batchUpdateFinalStatusApi')->name('orderIssue.batchUpdate.finalStatusApi');
+
         Route::match(['get','post'],'disposeImport','OrderIssueController@disposeImportApi');
         Route::post('financeConfirm','OrderIssueController@financeConfirmApi');
 
@@ -272,44 +274,33 @@ Route::group(['prefix' => 'print'],function (){
 });
 
 Route::prefix('workOrder')->group(function(){
+    Route::post('intercept','WorkOrderController@interceptApi')->name('workOrder.interceptApi');                            // 拦截
+    Route::post('informationChange','WorkOrderController@informationChangeApi')->name('workOrder.informationChangeApi');    // 改信息
+    Route::post('loss','WorkOrderController@lossApi')->name('workOrder.lossApi');                                           // 快递丢件
+    Route::post('fillLoss','WorkOrderController@fillLossApi')->name('workOrder.fillLossApi');                               // 快递丢件填充
+    Route::post('damaged','WorkOrderController@damagedApi')->name('workOrder.damagedApi');                                  // 快递破损
+    Route::post('expressAbnormal','WorkOrderController@expressAbnormalApi')->name('workOrder.expressAbnormalApi');          // 快递异常
+    Route::post('mistake','WorkOrderController@mistakeApi')->name('workOrder.mistakeApi');                                  // 错漏发
 
-    Route::post('intercept','WorkOrderController@interceptApi')->name('workOrder.interceptApi');                        // 拦截
-    Route::post('informationChange','WorkOrderController@informationChangeApi')->name('workOrder.informationChangeApi'); // 改信息
-    Route::post('loss','WorkOrderController@lossApi')->name('workOrder.lossApi');                        // 快递丢件
-    Route::post('fillLoss','WorkOrderController@fillLossApi')->name('workOrder.fillLossApi');            // 快递丢件填充
-    Route::post('damaged','WorkOrderController@damagedApi')->name('workOrder.damagedApi');               // 快递破损
-    Route::post('expressAbnormal','WorkOrderController@expressAbnormalApi')->name('workOrder.expressAbnormalApi');            // 快递异常
-    Route::post('mistake','WorkOrderController@mistakeApi')->name('workOrder.mistakeApi');               // 错漏发
-
-
-    Route::post('updateLoss','WorkOrderController@updateLossApi')->name('workOrder.updateLossApi'); // 客户提供丢件信息
-    Route::post('status','WorkOrderController@updateWorkOrderStatusApi')->name('workOrder.updateStatusApi');        // 修改状态
-    Route::post('status/logistic','WorkOrderController@logisticUpdateWorkOrderStatusApi')->name('workOrder.logisticUpdateStatusApi');
-
+    Route::post('updateLoss','WorkOrderController@updateLossApi')->name('workOrder.updateLossApi');                         // 商家提供丢件信息
 
-    Route::post('review','WorkOrderController@reviewApi')->name('workOrder.reviewApi'); // 审核
-    Route::post('review/baoShi','WorkOrderController@baoShiReviewApi')->name('workOrder.baoShi.reviewApi');
+    Route::post('review/baoShi','WorkOrderController@baoShiReviewApi')->name('workOrder.baoShi.reviewApi');                 // 宝时审核
 
-    Route::post('batchReview','WorkOrderController@batchReviewApi')->name('workOrder.batchReviewApi');  // 批量审核
-    Route::post('buildOrderIssue','WorkOrderController@buildOrderIssueApi')->name('workOrder.buildOrderIssueApi');  // 生成问题件
-    Route::post('updateIssueType','WorkOrderController@updateIssueTypeApi')->name('workOrder.updateIssueTypeApi'); // 修改问题类型
+    Route::post('updateIssueType','WorkOrderController@updateIssueTypeApi')->name('workOrder.updateIssueTypeApi');          // 修改问题类型
     Route::post('batchUpdateIssueType','WorkOrderController@batchUpdateIssueTypeApi')->name('workOrder.batchUpdateIssueTypeApi'); // 修改问题类型
-    Route::delete('/{id}','WorkOrderController@destroyApi')->name('workOrder.destroyApi');
 
-    Route::post('check','WorkOrderController@checkWorkOrderApi')->name('workOrder.checkApi');
+    Route::post('batchReview','WorkOrderController@batchReviewApi')->name('workOrder.batchReviewApi');                      // 批量审核
+    Route::post('buildOrderIssue','WorkOrderController@buildOrderIssueApi')->name('workOrder.buildOrderIssueApi');          // 生成问题件
+    Route::delete('/{id}','WorkOrderController@destroyApi')->name('workOrder.destroyApi');                                  // 工单删除
 
-    Route::post('logistic/end',"WorkOrderController@logisticEndApi")->name('workOrder.logistic.endApi');
+    Route::post('check','WorkOrderController@checkWorkOrderApi')->name('workOrder.checkApi');                               // 检查订单是否存在工单
+    Route::post('logistic/end',"WorkOrderController@logisticEndApi")->name('workOrder.logistic.endApi');                    // 承运商 完结工单
     Route::prefix('commodity')->group(function(){
-        Route::post("updateCommodities/owner","WorkOrderController@ownerUpdateCommoditiesApi")->name("workOrder.commodity.ownerUpdateApi");
-        Route::post("updateCommodities/logistic","WorkOrderController@logisticUpdateCommoditiesApi")->name("workOrder.commodity.logisticUpdateApi");
-        Route::post("updateCommodities/baoshi","WorkOrderController@baoShiUpdateCommoditiesApi")->name("workOrder.commodity.baoShiUpdateCommodities");
+        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::prefix('process')->group(function (){
-        Route::post('log/logistic','WorkOrderProcessLogController@logisticStoreApi')->name('workOrderProcessLog.logisticLogApi');
-        Route::post('log','WorkOrderProcessLogController@storeApi')->name('workOrderProcessLog.LogApi');
-    });
- });
+});
 /*出库*/
 Route::group(['prefix'=>'storeOut'],function(){
     /*复核*/

+ 2 - 0
routes/web.php

@@ -1129,6 +1129,8 @@ Route::group(['prefix'=>'package'],function(){
     Route::group(['prefix' => 'kpi'], function () {
         Route::get( 'month', 'KpiController@monthIndex');
         Route::get( 'day', 'KpiController@dayIndex');
+        Route::get( 'dayDetail', 'KpiController@dayDetailIndex');
+        Route::get( 'dayDetailCustomer', 'KpiController@dayDetailCustomer');
     });
 });