Explorar el Código

Merge branch 'master' into turnaround

# Conflicts:
#	resources/views/rejected/edit.blade.php
haozi hace 4 años
padre
commit
2ece196618
Se han modificado 91 ficheros con 4331 adiciones y 1307 borrados
  1. 1 1
      app/Components/ApiResponse.php
  2. 5 2
      app/Console/Commands/SyncWMSOrderTask.php
  3. 1 1
      app/Console/Kernel.php
  4. 1 1
      app/Filters/OrderIssueFilters.php
  5. 13 0
      app/Filters/WorkOrderFilters.php
  6. 11 2
      app/Http/ApiControllers/WaybillController.php
  7. 15 0
      app/Http/Controllers/CommodityController.php
  8. 32 24
      app/Http/Controllers/CustomerController.php
  9. 0 1
      app/Http/Controllers/InventoryAccountController.php
  10. 15 14
      app/Http/Controllers/LaborApplyController.php
  11. 36 3
      app/Http/Controllers/LaborCompanyDispatchController.php
  12. 12 99
      app/Http/Controllers/ProcessController.php
  13. 0 1
      app/Http/Controllers/SettlementBillExpressFeeDetailController.php
  14. 82 191
      app/Http/Controllers/TestController.php
  15. 85 0
      app/Http/Controllers/WorkOrderCommoditiesController.php
  16. 59 17
      app/Http/Controllers/WorkOrderController.php
  17. 85 0
      app/Http/Controllers/WorkOrderDetailController.php
  18. 85 0
      app/Http/Controllers/WorkOrderImageController.php
  19. 49 0
      app/Http/Controllers/WorkOrderProcessLogController.php
  20. 29 0
      app/Http/Controllers/api/thirdPart/syrius/producer/BinLocation.php
  21. 36 0
      app/Http/Controllers/api/thirdPart/syrius/producer/Controller.php
  22. 2 2
      app/Http/Requests/Api/WaybillDispatch.php
  23. 76 0
      app/Http/Requests/WorkOrder/WorkOrderRequest.php
  24. 1 1
      app/Imports/StoreCheckingReceiveImport.php
  25. 44 0
      app/Jobs/CalculationArrivedManNumJob.php
  26. 1 1
      app/LaborApply.php
  27. 35 2
      app/LaborCompanyDispatch.php
  28. 3 5
      app/OrderIssue.php
  29. 8 0
      app/Providers/AppServiceProvider.php
  30. 12 0
      app/Services/CommodityService.php
  31. 1 0
      app/Services/ForeignHaiRoboticsService.php
  32. 58 1
      app/Services/LaborApplyService.php
  33. 5 5
      app/Services/OrderPackageReceivedSyncService.php
  34. 9 9
      app/Services/OrderPackageService.php
  35. 3 1
      app/Services/OwnerFeeTotalService.php
  36. 1 1
      app/Services/OwnerPriceExpressService.php
  37. 42 10
      app/Services/OwnerStoreFeeReportService.php
  38. 7 0
      app/Services/UserService.php
  39. 13 2
      app/Services/WaybillService.php
  40. 31 0
      app/Services/WorkOrderCommoditiesService.php
  41. 20 0
      app/Services/WorkOrderDetailService.php
  42. 113 0
      app/Services/WorkOrderImageService.php
  43. 102 0
      app/Services/WorkOrderProcessLogService.php
  44. 158 90
      app/Services/WorkOrderService.php
  45. 16 3
      app/User.php
  46. 196 17
      app/WorkOrder.php
  47. 33 0
      app/WorkOrderCommodities.php
  48. 31 0
      app/WorkOrderDetail.php
  49. 132 0
      app/WorkOrderImage.php
  50. 118 0
      app/WorkOrderProcessLog.php
  51. 214 147
      composer.lock
  52. 15 0
      config/api.php
  53. 1 1
      config/sync.php
  54. 12 0
      database/factories/WorkOrderCommoditiesFactory.php
  55. 18 0
      database/factories/WorkOrderDetailFactory.php
  56. 12 0
      database/factories/WorkOrderImageFactory.php
  57. 12 0
      database/factories/WorkOrderProcessLogFactory.php
  58. 38 0
      database/migrations/2021_09_22_135941_create_work_order_details_table.php
  59. 35 0
      database/migrations/2021_09_22_160325_create_work_order_commodities_table.php
  60. 34 0
      database/migrations/2021_09_22_162827_create_work_order_images_table.php
  61. 38 0
      database/migrations/2021_09_24_110630_create_work_order_process_logs_table.php
  62. 32 0
      database/migrations/2021_09_27_092709_add_cloumn_to_workk_orders.php
  63. 32 0
      database/migrations/2021_10_09_164021_drop_current_timestamp_to_labor_company_dispatches_table.php
  64. 32 0
      database/migrations/2021_10_11_104946_add_column_status_to_labor_company_dispatches_table.php
  65. 16 0
      database/seeds/WorkOrderCommoditiesSeeder.php
  66. 17 0
      database/seeds/WorkOrderDetailSeeder.php
  67. 16 0
      database/seeds/WorkOrderImageSeeder.php
  68. 16 0
      database/seeds/WorkOrderProcessLogSeeder.php
  69. 6 4
      resources/views/finance/instantBill.blade.php
  70. 13 3
      resources/views/finance/settlementBills/totalFee/index.blade.php
  71. 9 6
      resources/views/layouts/app.blade.php
  72. 159 18
      resources/views/order/index/_work_order_modal.blade.php
  73. 489 302
      resources/views/order/index/delivering.blade.php
  74. 44 39
      resources/views/order/issue/index.blade.php
  75. 77 0
      resources/views/order/workOrder/_edit_process_log.blade.php
  76. 90 0
      resources/views/order/workOrder/_fill_loss_work_order.blade.php
  77. 165 0
      resources/views/order/workOrder/_work_order_details.blade.php
  78. 503 181
      resources/views/order/workOrder/index.blade.php
  79. 19 14
      resources/views/personnel/laborApply/create.blade.php
  80. 3 2
      resources/views/personnel/laborApply/dispatch/detail/create.blade.php
  81. 3 2
      resources/views/personnel/laborApply/dispatch/detail/edit.blade.php
  82. 52 0
      resources/views/personnel/laborApply/dispatch/edit.blade.php
  83. 62 20
      resources/views/personnel/laborApply/dispatch/index.blade.php
  84. 4 3
      resources/views/personnel/laborApply/edit.blade.php
  85. 1 37
      resources/views/personnel/laborApply/index.blade.php
  86. 6 6
      resources/views/rejected/edit.blade.php
  87. 14 1
      routes/apiLocal.php
  88. 13 9
      routes/web.php
  89. 0 2
      tests/Services/LogisticAliJiSuApiService/FormatTest.php
  90. 31 3
      tests/Services/OrderPackageReceivedSyncService/TestUpdate.php
  91. 55 0
      文档/SystemHandBook.md

+ 1 - 1
app/Components/ApiResponse.php

@@ -9,7 +9,7 @@ trait ApiResponse
     public function response($data, int $code = 200,string $message = null)
     {
         $response = ["status_code"=>$code,"data"=>$data,"message"=>$message];
-        header("Content-Type","application/json;charset=utf-8");
+        header("Content-Type","application/json; charset=UTF-8");
         echo json_encode($response,JSON_UNESCAPED_UNICODE);
         exit();
     }

+ 5 - 2
app/Console/Commands/SyncWMSOrderTask.php

@@ -9,6 +9,7 @@ use App\ValueStore;
 use Carbon\Carbon;
 use Illuminate\Console\Command;
 use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Log;
 
 class SyncWMSOrderTask extends Command
 {
@@ -61,11 +62,13 @@ class SyncWMSOrderTask extends Command
         $start = (string)$start;
         Cache::put($this->last_start_key,$start);
         ValueStore::query()->where('name',$this->last_start_key)->update(['value'=>$start]);
+        Log::info("订单同步开始时间",['date' => $start]);
         $this->syncCreatedOrder();
         $this->syncUpdatedOrder();
         $end = (string)Carbon::now();
         Cache::put($this->last_end_key,$end);
         ValueStore::query()->where('name',$this->last_end_key)->update(['value'=>$end]);
+        Log::info("订单同步结束时间",['date' => $end]);
     }
 
     public function syncCreatedOrder()
@@ -89,7 +92,7 @@ class SyncWMSOrderTask extends Command
             ->orderBy('DOC_Order_Header.addTime')->get();
 
         if($orderHeaders->count()==0)return;
-        $orderHeaderList = $orderHeaders->chunk(1000);
+        $orderHeaderList = $orderHeaders->chunk(200);
         foreach ($orderHeaderList as $item) {
             $item = $oracleDOCOrderHeaderService->loadMissing($item);
             $last_order = $item->last();                                                               // 时间点靠后的
@@ -126,7 +129,7 @@ class SyncWMSOrderTask extends Command
 
         if($orderHeaders->count()==0)return;
 
-        $orderHeaderList = $orderHeaders->chunk(1000);
+        $orderHeaderList = $orderHeaders->chunk(200);
         foreach ($orderHeaderList as $item) {
             $item  = $oracleDOCOrderHeaderService->loadMissing($item);
             $renewal_order = $item->last();                                                            // 时间点靠后的

+ 1 - 1
app/Console/Kernel.php

@@ -64,7 +64,7 @@ class  Kernel extends ConsoleKernel
         $schedule->command('LogExpireDelete')->dailyAt('00:01');
         $schedule->command('InventoryDailyLoggingOwner')->dailyAt('08:00');
         $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);

+ 1 - 1
app/Filters/OrderIssueFilters.php

@@ -248,7 +248,7 @@ class OrderIssueFilters
     public function log_content($log_content)
     {
         $order_issue_process_log_query = OrderIssueProcessLog::query()->selectRaw('order_issue_id')->where('content', 'like', $log_content);
-        if (!$this->params['addtime']) {
+        if (!array_key_exists('addtime',$this->params) ) {
             $order_issue_process_log_query->where('created_at', '>=', Carbon::now()->subDays(31));
         } else {
             $order_issue_process_log_query->where('created_at', '>=', Carbon::now()->subDays($this->params['addtime']));

+ 13 - 0
app/Filters/WorkOrderFilters.php

@@ -73,6 +73,19 @@ class WorkOrderFilters
         if (!isset($this->params['owner'])){
             $this->getOrderQuery()->whereIn('owner_id', app('UserService')->getPermittingOwnerIds(Auth::user())??[]);
         }
+
+        $user = Auth::user();
+        $logistic_ids = App('UserService')->getPermittingLogisticIds($user);
+        $owner_id = app('UserService')->getPermittingOwnerIds($user);
+        if (count($logistic_ids)>=0 && count($owner_id) == 0){
+            $orderIssueIds = OrderIssue::query()->select('id')->whereIn('name',['破损','快递丢件'])->get()->toArray();
+            $orderIssueIds = array_intersect($orderIssueIds,$this->array_filter['order_issue_type']);
+            if (count($orderIssueIds) == 0) unset($this->array_filter['order_issue_type']);
+            else $this->array_filter['order_issue_type'] = $orderIssueIds;
+        }
+        $this->getOrderQuery()->where(function($query)use ($owner_id,$logistic_ids){
+            $query->whereIn('owner_id',$owner_id)->orWhereIn('logistic_id',$logistic_ids);
+        });
     }
 
     public function beforeApply()

+ 11 - 2
app/Http/ApiControllers/WaybillController.php

@@ -9,6 +9,7 @@ use App\Http\Requests\AndroidGateRequest;
 use App\Http\Requests\Api\WaybillDispatch;
 use App\Services\WaybillService;
 use App\Waybill;
+use Illuminate\Database\Eloquent\Collection;
 
 class WaybillController
 {
@@ -63,13 +64,21 @@ class WaybillController
 
         /** @var WaybillService $service */
         $service = app("WaybillService");
-        $query = $service->getDispatchQuery();
+        $query = $service->getDispatchQuery()->orderByDesc("deliver_at");
         if ($search)$query->where(function ($query)use($search){
             $query->where("waybill_number","like","%{$search}%")
                 ->orWhere("carrier_bill","like","%{$search}%");
         });
         if ($deliverAt)$query->where("deliver_at","like",$deliverAt."%");
-        $this->response($query->paginate($paginate,'*', 'page',$page)->append(["carrier_name","amount_unit_name","remove_relation"]));
+        /** @var Collection $waybills */
+        $waybills = $query->paginate($paginate,'*', 'page',$page)->append(["carrier_name","amount_unit_name","remove_relation"]);
+        $result = null;
+        if ($waybills->count()>0){
+            $startDate = substr($waybills->first()->deliver_at,0,10);
+            $endDate = substr($waybills->last()->deliver_at,0,10);
+            $result = ["2021-10-08"=>2];
+        }
+        $this->response(["waybills"=>$waybills,"mapping"=>$result]);
     }
 
     /**

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

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
 
 use App\Commodity;
 use App\Imports\CommodityImport;
+use App\Owner;
 use App\Services\CommodityBarcodeService;
 use App\Services\CommodityService;
 use App\Services\OracleBasSkuService;
@@ -394,4 +395,18 @@ class CommodityController extends Controller
             app('LogService')->log(__METHOD__,"同步商品-录入条码",json_encode($barcodeInsert));
         }
     }
+
+    public function getCommodityApi(Request $request,CommodityService $service): array
+    {
+        $owner = Owner::query()->where('name',$request['owner_name'])->first();
+        if (!$owner){
+            return ['success' => false ,'message' => '货主未找到'];
+        }
+        $commodity = $service->getCommodityBy($owner,$request->input('sku'));
+        if ($commodity){
+            return ['success' => true,'data' => $commodity];
+        }
+        return ['success' => false,'message' => '请校验sku是否正确'];
+    }
+
 }

+ 32 - 24
app/Http/Controllers/CustomerController.php

@@ -11,6 +11,7 @@ use App\Owner;
 use App\OwnerAreaReport;
 use App\OwnerBillReport;
 use App\OwnerFeeDetail;
+use App\OwnerFeeExpress;
 use App\OwnerFeeLogistic;
 use App\OwnerFeeOperation;
 use App\OwnerFeeOperationDetail;
@@ -521,32 +522,39 @@ class CustomerController extends Controller
         $endDate = request("endDate");
         $owner = request("owner");
         if (!$startData)$this->error("非法参数");
-        $details = OwnerFeeDetail::query()->where("worked_at",">=",$startData." 00:00:00");
-        if ($endDate)$details->where("worked_at","<=",$endDate." 23:59:59");
-        if (count($owner)>0)$details->whereIn("owner_id",$owner);
-
-        $fee = OwnerFeeDetail::query()->where("created_at",">=",$startData." 00:00:00");
-        if ($endDate)$fee->where("created_at","<=",$endDate." 23:59:59");
-        if (count($owner)>0)$fee->whereIn("owner_id",$owner);
-        $fee->delete();
-
-        $feeQuery = OwnerFeeOperation::query()->where("worked_at",">=",$startData);
-        if ($endDate)$feeQuery->where("worked_at","<=",$endDate);
-        if (count($owner)>0)$feeQuery->whereIn("owner_id",$owner);
-        OwnerFeeOperationDetail::query()->whereIn("owner_fee_operation_id",$feeQuery)->delete();
-        $feeQuery->delete();
-
-        $fee = OwnerFeeLogistic::query()->where("created_at",">=",$startData." 00:00:00");
-        if ($endDate)$fee->where("created_at","<=",$endDate." 23:59:59");
-        if (count($owner)>0)$fee->whereIn("owner_id",$owner);
-        $fee->delete();
-
-        $details->get()->each(function ($detail){
-            dispatch(new ResetInstantBill($detail));
-        });
+        DB::beginTransaction();
+        try {
+            $details = OwnerFeeDetail::query()->where("worked_at",">=",$startData." 00:00:00");
+            if ($endDate)$details->where("worked_at","<=",$endDate." 23:59:59");
+            if (count($owner)>0)$details->whereIn("owner_id",$owner);
+
+            $fee = OwnerFeeExpress::query()->where("created_at",">=",$startData." 00:00:00");
+            if ($endDate)$fee->where("created_at","<=",$endDate." 23:59:59");
+            if (count($owner)>0)$fee->whereIn("owner_id",$owner);
+            $fee->delete();
+
+            $feeQuery = OwnerFeeOperation::query()->select("id")->where("worked_at",">=",$startData);
+            if ($endDate)$feeQuery->where("worked_at","<=",$endDate);
+            if (count($owner)>0)$feeQuery->whereIn("owner_id",$owner);
+            OwnerFeeOperationDetail::query()->whereIn("owner_fee_operation_id",$feeQuery)->delete();
+            $feeQuery->delete();
+
+            $fee = OwnerFeeLogistic::query()->where("created_at",">=",$startData." 00:00:00");
+            if ($endDate)$fee->where("created_at","<=",$endDate." 23:59:59");
+            if (count($owner)>0)$fee->whereIn("owner_id",$owner);
+            $fee->delete();
+
+            $details->get()->each(function ($detail){
+                dispatch(new ResetInstantBill($detail));
+            });
+            DB::commit();
+            $this->success();
+        }catch (\Exception $e){
+            DB::rollBack();
+            $this->error("失败");
+        }
         //$this->restoreResetInstantBillOrder($startData,$endDate);
         //$this->restoreResetInstantBillStore($startData,$endDate);
-        $this->success();
     }
     private function restoreResetInstantBillOrder($startData,$endDate)
     {

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

@@ -158,7 +158,6 @@ class InventoryAccountController extends Controller
         $goodses = $request->input('goodses');
         if (!$location) return ['success' => false, 'fail_info' => '盘点库位不存在!'];
         if (count($goodses) < 1) return ['success' => false, 'fail_info' => '盘点商品不存在!'];
-        //dd($location,$owner_code,$goodses,$inventoryId,$owner_id);
         /** @var InventoryAccountService $inventoryAccountMission */
         $inventoryAccountService = app('inventoryAccountService');
         $inventoryAccountMissions = $inventoryAccountService->baseOnBlindReceive($location, $owner_code, $goodses, $inventoryId);

+ 15 - 14
app/Http/Controllers/LaborApplyController.php

@@ -17,7 +17,7 @@ use Illuminate\Support\Facades\Gate;
 
 class LaborApplyController extends Controller
 {
-    public function index(Request $request,\App\Filters\LaborApplyFilters $filters)
+    public function index(Request $request, \App\Filters\LaborApplyFilters $filters)
     {
         $builder = LaborApply::query()
             ->filter($filters)
@@ -44,6 +44,14 @@ class LaborApplyController extends Controller
 
     public function store(LaborApplyRequest $request, LaborApply $laborApply)
     {
+
+        $user_workgroup_applied = LaborApply::query()
+            ->whereDate('created_at', now()->toDateString())
+            ->where('user_workgroup_id', $request->user_workgroup_id)
+            ->exists();
+        if ($user_workgroup_applied) {
+            return redirect()->back()->with('warning', '该仓库小组今日已申请过,请修改申请人数,不要重复申请!');
+        }
         $laborApply->fill($request->all());
         $laborApply->apply_user_id = Auth::id();
         $laborApply->status = '创建';
@@ -72,18 +80,10 @@ class LaborApplyController extends Controller
 
     public function update(Request $request, LaborApply $laborApply)
     {
-        $laborApply->actual_num = $request->input('actual_num');
-        $laborApply->status = '任务完结';
-        $laborApply->save();
-        return redirect(route('laborApply.index'))->with('success', '填写实到人数成功!');
+        $laborApply->update($request->all());
+        return redirect(route('laborApply.index'))->with('success', '申请更新成功!');
     }
 
-    /**
-     * Remove the specified resource from storage.
-     *
-     * @param \App\LaborApply $laborApply
-     * @return \Illuminate\Http\Response
-     */
     public function destroy(LaborApply $laborApply)
     {
         $laborApply->delete();
@@ -113,10 +113,11 @@ class LaborApplyController extends Controller
         /** @var LaborApplyService $laborApplyService */
         $laborApplyService = app('LaborApplyService');
         $response = $laborApplyService->allocationLaborToLaborCompany();
+        $route = 'laborCompanyDispatch.index';
         if ($response['success']) {
-            return redirect(route('laborApplyDispatch.index'))->with('success', '重新生成劳务派遣数据成功!');
-        }else{
-            return redirect(route('laborApplyDispatch.index'))->with('danger', $response['error_message']);
+            return redirect(route('' . $route . ''))->with('success', '重新生成劳务派遣数据成功!');
+        } else {
+            return redirect(route($route))->with('danger', $response['error_message']);
         }
     }
 }

+ 36 - 3
app/Http/Controllers/LaborCompanyDispatchController.php

@@ -36,6 +36,17 @@ class LaborCompanyDispatchController extends Controller
         return view('personnel.laborApply.dispatch.index', compact('labor_company_dispatches'));
     }
 
+    public function edit(LaborCompanyDispatch $laborCompanyDispatch)
+    {
+        return view('personnel.laborApply.dispatch.edit', compact('laborCompanyDispatch'));
+    }
+
+    public function update(LaborCompanyDispatch $laborCompanyDispatch, Request $request)
+    {
+        $laborCompanyDispatch->update($request->all());
+        return redirect(route('laborCompanyDispatch.index'))->with('success', '更新成功!');
+    }
+
     public function createDetail(Request $request, LaborCompanyDispatch $laborCompanyDispatch)
     {
         return view('personnel.laborApply.dispatch.detail.create', compact('laborCompanyDispatch'));
@@ -53,15 +64,37 @@ class LaborCompanyDispatchController extends Controller
         $laborCompanyDispatch->laborCompanyDispatchDetails()->createMany(
             $request->input('users')
         );
+        return redirect(route('laborCompanyDispatch.index'))->with('success', '添加临时工详情成功!');
+    }
+
+    /**
+     * 劳务接单
+     * @param LaborCompanyDispatch $laborCompanyDispatch
+     * @param Request $request
+     * @return \Illuminate\Http\RedirectResponse
+     */
+    public function laborCompanyReceivingOrder(LaborCompanyDispatch $laborCompanyDispatch, Request $request)
+    {
         /** @var Carbon $dispatch_date */
         $dispatch_date = $laborCompanyDispatch->dispatch_date;
-
+        //更新创建日期为 分配日期前一天的全部申请状态为 劳务接单
         LaborApply::query()
             ->whereDate('created_at', $dispatch_date->subDay()->toDateString())
             ->where('warehouse_id', $laborCompanyDispatch->laborCompany->warehouse_id)
             ->update([
-                'status' => 3, //劳务接单
+                'status' => $request->status, //劳务接单
             ]);
-        return redirect(route('laborApplyDispatch.index'))->with('success', '添加临时工详情成功!');
+        $laborCompanyDispatch->status = '劳务接单';
+        $laborCompanyDispatch->save();
+        return redirect()->back()->with('success', '接单成功!');
     }
+
+    public function personnelCheck(LaborCompanyDispatch $laborCompanyDispatch, Request $request)
+    {
+        $laborCompanyDispatch->status = $request->status;
+        $laborCompanyDispatch->save();
+        return redirect()->back()->with('success', '人事确认成功!');
+
+    }
+
 }

+ 12 - 99
app/Http/Controllers/ProcessController.php

@@ -66,75 +66,9 @@ class ProcessController extends Controller
                 $processDailies=ProcessDaily::with(['processDailyParticipants','process'])
                     ->orderBy('date','DESC')->where('process_id',$id)->get();
             }
-            //$processDailies=$this->countManHour($processDailies);
         }
         return $processDailies;
     }
-
-    /*//根据参与人查找打卡记录计算工时信息
-    public function countManHour($processDailies){
-        foreach ($processDailies as $processDaily){
-            $date=$processDaily->date;
-            foreach ($processDaily->processDailyParticipants as $processDailyParticipant){
-                $processDailyParticipant->started_at=Carbon::parse($processDailyParticipant->started_at)->format('H:i');
-                $processDailyParticipant->ended_at=Carbon::parse($processDailyParticipant->ended_at)->format('H:i');
-                $processDailyParticipant=$this->countParticipantManHour($processDailyParticipant,$date);
-            }
-        }
-        return $processDailies;
-    }*/
-
-    /*//计算单参与人工时信息
-    public function countParticipantManHour($processDailyParticipant,$date){
-        $user_id=$processDailyParticipant->user_id;
-        $userDutyCheckStart=UserDutyCheck::select('id','checked_at')->where('user_id',$user_id)
-            ->where('checked_at','like',$date.'%')->where('type','登入')->orderBy('id')->first();
-        $userDutyCheckEnd=UserDutyCheck::select('id','checked_at')->where('user_id',$user_id)
-            ->where('checked_at','like',$date.'%')->where('type','登出')->orderBy('id','desc')->first();
-        //跨日情况寻找下一天
-        if (!$userDutyCheckEnd){
-            $date=date("Y-m-d",strtotime("+1 day",strtotime($date)));
-            $userDutyCheckEnd=UserDutyCheck::select('id','checked_at')->where('user_id',$user_id)
-                ->where('checked_at','like',$date.'%')->where('type','登出')->orderBy('id','desc')->first();
-        }
-        if (!$userDutyCheckStart || !$userDutyCheckEnd){
-            return $processDailyParticipant;
-        }
-        $dateStart=Carbon::parse($userDutyCheckStart->checked_at);
-        $dateEnd=Carbon::parse($userDutyCheckEnd->checked_at);
-        $hour=($dateEnd->diffInSeconds($dateStart))/3600; //打卡工时
-        if ($processDailyParticipant->dinner_duration)$hour=$hour-(($processDailyParticipant->dinner_duration)/60); //减晚饭时间
-        $hour=$this->isHour($userDutyCheckStart,$hour); //去除休息时间
-        $processDailyParticipant->hour=round($hour,2);
-        if ($hour&&$processDailyParticipant->hour_count){
-            $diff=abs(round($processDailyParticipant->hour_count-$hour,2));
-            $processDailyParticipant->diff=$diff;
-        }
-
-        //计件工 保留
-        // if ($processDailyParticipant->unit_count){
-        //   return $processDailyParticipant;
-        //}
-        if ($hour&&$hour>8){
-            $processDailyParticipant->billingHour=8;
-            return $processDailyParticipant;
-        }
-        if ($hour&&$hour<=8){
-            $processDailyParticipant->billingHour=round($hour,2);
-        }
-        return $processDailyParticipant;
-    }*/
-
-/*    //打卡工时减休息时间
-    private function isHour($userDutyCheckStart,$hour){
-
-        $date=$userDutyCheckStart->checked_at;
-        $date=Carbon::parse($date)->format('H');
-        if ((int)$date<=11){
-            $hour=$hour-1;
-        }
-        return $hour;
-    }*/
     //生成二次加工单缺失时间记录及本日记录
     private function createDeficiencyData($processDailies,$today){
         $processDailiesArr=[];
@@ -202,15 +136,15 @@ class ProcessController extends Controller
         if(!Gate::allows('二次加工管理-交接完成')){ return ['success'=>false,'data'=>'您无权进行该操作!'];  }
         $process=Process::with('processDailies')->find($request->id);
         if (!$process || $process->status == '交接完成')return ['success'=>false];
-        $result=$this->statistic($process);
+        $this->statistic($process);
         $process->update(['status'=>'交接完成']);
         $process->createOperatorLog('交接完成');
-        $processStatistic=$result['data'];
-        app('LogService')->log(__METHOD__,"完成二次加工单_".__FUNCTION__,json_encode($process)." || ".json_encode($processStatistic),Auth::user()['id']);
         app('ProcessService')->createInstantBill($process);
         return ['success'=>true,'data'=>'交接完成'];
     }
     private function statistic($process, $sign_end = false){
+        $processStatistic=ProcessStatistic::query()->find($process->id);
+        if (!$processStatistic)return ['success'=>true];
         if (count($process->processDailies)>0){
             $completed_amount=0;
             foreach ($process->processDailies as $processDaily){
@@ -235,7 +169,6 @@ class ProcessController extends Controller
                 $total_cost += ($processDailyParticipant->hour_count)*($processDailyParticipant->hour_price);
             }
         };
-        $processStatistic=ProcessStatistic::query()->find($process->id);
         $processStatistic->revenue=$revenue;
         $processStatistic->duration_days=$duration_days;
         $processStatistic->duration_man_hours=$duration_man_hours;
@@ -369,7 +302,7 @@ class ProcessController extends Controller
         }]);
 
         // 重置统计开始时间
-        event(new ResetProcessStatisticStartDateEvent($processDailyParticipant->processDaily->process));
+        //event(new ResetProcessStatisticStartDateEvent($processDailyParticipant->processDaily->process));
 
 
         if ($processDailyParticipant->processDaily && $processDailyParticipant->processDaily->process &&
@@ -378,8 +311,6 @@ class ProcessController extends Controller
         }
         $result=[];
         $processDaily=ProcessDaily::with('process')->select('process_id','date')->find($daily_id);
-        //$date=$processDaily->date;
-        //$processDailyParticipant=$this->countParticipantManHour($processDailyParticipant,$date);
         if ($processDaily->process && $processDaily->process->status=="待加工"){
             $process=Process::find($processDaily->process_id);
             $process->status="加工中";
@@ -389,7 +320,6 @@ class ProcessController extends Controller
             if (!$processStatistic){
                 Log::warning("二次加工统单不存在2",["user"=>Auth::id(),"param"=>$processDaily->process_id]);
             }else {
-                //$processStatistic->started_at=date('Y-m-d H:i:s');
                 $processStatistic->started_at=$processDaily->date.' '.$started_at;
                 $processStatistic->update();
                 app('LogService')->log(__METHOD__,"二次加工单加工中".__FUNCTION__,json_encode($process)." || ".json_encode($processStatistic),Auth::user()['id']);
@@ -452,7 +382,7 @@ class ProcessController extends Controller
         if (!$processDailyParticipant || !$processDailyParticipant->processDaily
             || !$processDailyParticipant->processDaily->process || !$processDailyParticipant->userLabor) return ['success'=>false,'data'=>"修改失败,该信息不存在"];
         if ($processDailyParticipant->userLabor->isOccupiedAt($processDailyParticipant->processDaily->date,$request->started_at)){
-            ['success'=>false,'data'=>"该临时工此时间段已存在工作记录"];
+            return ['success'=>false,'data'=>"该临时工此时间段已存在工作记录"];
         }
         $processDailyParticipant->user_id=$request->input('user_id');
         $processDailyParticipant->started_at=$request->input('started_at');
@@ -468,19 +398,8 @@ class ProcessController extends Controller
         if ($processDailyParticipant->processDaily->process->status=='交接完成'){
             $this->statistic($processDailyParticipant->processDaily->process);
         }
-        //$processDailyParticipant=$this->countParticipantManHour($processDailyParticipant,$processDailyParticipant->processDaily->date);
         return ['success'=>true,'data'=>$processDailyParticipant];
     }
-    /*//参与人审核
-    public function processDailyParticipantAudit($id){
-        if(!Gate::allows('人事管理-任务审核')){ return redirect(url('/'));  }
-        $processDailyParticipant=ProcessDailyParticipant::select('id','status')->find($id);
-        if (!$processDailyParticipant) return ['success'=>false];
-        $processDailyParticipant->status='已审核';
-        $processDailyParticipant->update();
-        app('LogService')->log(__METHOD__,"登记工时参与人审核".__FUNCTION__,json_encode($processDailyParticipant),Auth::user()['id']);
-        return ['success'=>true,'processDailyParticipant'=>$processDailyParticipant];
-    }*/
     //获取全部教程
     public function getTutorials($id){
         $process=Process::with('tutorials')->find($id);
@@ -519,7 +438,7 @@ class ProcessController extends Controller
     /**
      * Show the form for creating a new resource.
      *
-     * @return \Illuminate\Http\Response
+     * @return Application|Factory|\Illuminate\Http\Response|View
      */
     public function create()
     {
@@ -565,6 +484,9 @@ class ProcessController extends Controller
             'status'=>'待审核',
         ]);
         $process->save();
+        ProcessStatistic::query()->create([
+            'process_id'=>$process->id,
+        ]);
         $process->createOperatorLog('创建');
         $processContents=[];
         foreach ($request->input('processContents') as $processContent){
@@ -614,12 +536,6 @@ class ProcessController extends Controller
         }
         $process->code='P'.date ("Ymd").str_pad($process->id,3,"0",STR_PAD_LEFT);
         $process->update();
-        $processStatistic=new ProcessStatistic([
-            'process_id'=>$process->id,
-        ]);
-        $processStatistic->save();
-        app('LogService')->log(__METHOD__,"录入二次加工单".__FUNCTION__,json_encode($request->input()),Auth::user()['id']);
-        //if ($request->input('tutorials'))$process->tutorials()->sync($request->input('tutorials'));
         return ['success'=>true];
     }
     //修改价格
@@ -701,7 +617,7 @@ class ProcessController extends Controller
      * Show the form for editing the specified resource.
      *
      * @param  int  $id
-     * @return \Illuminate\Http\Response
+     * @return Application|Factory|\Illuminate\Http\Response|View
      */
     public function edit($id)
     {
@@ -884,8 +800,7 @@ class ProcessController extends Controller
             $query->where('type','成品单');
         }]);
         if (count($process->processesContents) == 0)return ['success'=>false,'data'=>'没有成本单不得验收!'];
-        $result=$this->statistic($process, true);
-        //if (!$result['success'])return $result;
+        $this->statistic($process, true);
         $process->update([
             'status'=>'待交接'
         ]);
@@ -1001,9 +916,7 @@ class ProcessController extends Controller
             $query->with("process");
         }])->find($id);
         if ($pro->delete()) {
-
-            event(new ResetProcessStatisticStartDateEvent($pro->processDaily->process));
-
+            //event(new ResetProcessStatisticStartDateEvent($pro->processDaily->process));
             return ['success'=>true];
         }
         return ['success'=>false , 'data'=>'记录不存在!'];

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

@@ -42,7 +42,6 @@ class SettlementBillExpressFeeDetailController extends Controller implements Set
             'counting_month' => $counting_month,
             'paginateParams' => $paginateParams,
         ]);
-//        dd($details);
         $owners = Owner::query()->selectRaw("id,name")->whereIn('id', $permittingOwnerIds)->get();
         $owner = Owner::query()->selectRaw("name,id")->find($owner_id);
         $this->archiveService = app('OwnerBillReportArchiveService');

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

@@ -25,6 +25,7 @@ use App\Jobs\WeightUpdateInstantBill;
 use App\LaborCompanyDispatch;
 use App\LaborReport;
 use App\LaborReportStatus;
+use App\Logistic;
 use App\MaterialBox;
 use App\MaterialBoxModel;
 use App\Notifications\RoutineNotification;
@@ -45,6 +46,7 @@ use App\OwnerFeeLogistic;
 use App\OwnerFeeOperation;
 use App\OwnerFeeOperationDetail;
 use App\OwnerFeeStorage;
+use App\OwnerPriceExpress;
 use App\OwnerPriceOperation;
 use App\OrderPackageCountingRecord;
 use App\ProcurementCheckSheet;
@@ -55,6 +57,7 @@ use App\Services\BatchService;
 use App\Services\CacheShelfService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Services\NotificationService;
+use App\Services\OracleDOCOrderHeaderService;
 use App\Services\OrderPackageReceivedSyncService;
 use App\Services\OrderPackageService;
 use App\Services\OrderService;
@@ -85,6 +88,7 @@ use Carbon\CarbonPeriod;
 use Decimal\Decimal;
 use Doctrine\DBAL\Exception;
 use Firebase\JWT\JWT;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Database\Eloquent\HigherOrderBuilderProxy;
 use Illuminate\Foundation\Http\FormRequest;
@@ -107,7 +111,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Web\Service;
 use Ramsey\Uuid\Uuid;
 use Symfony\Component\ErrorHandler\Error\FatalError;
 
-class TestController extends Controller
+class TestController extends \App\Http\Controllers\api\thirdPart\syrius\producer\Controller
 {
     use AsyncResponse, ErrorPush, Database;
 
@@ -118,7 +122,7 @@ class TestController extends Controller
         $this->data["active_test"] = "active";
     }
 
-    public function method(AndroidGateRequest $request, $method)
+    public function method(Request $request, $method)
     {
         try {
             return call_user_func([$this, $method], $request);
@@ -197,195 +201,17 @@ class TestController extends Controller
         }
         app("BatchService")->assignTasks($batches);
     }
-    public function test(AndroidGateRequest $request)
+    public function test()
     {
-        dd(Waybill::query()->with(["order:id,address","logistic:id,name","amountUnit:id,name"])
-            ->select("id","order_id","logistic_id","amount_unit_id",
-                "waybill_number","destination","recipient","recipient_mobile",
-                "carrier_bill","warehouse_weight","carrier_weight","inquire_tel",
-                "warehouse_weight_other","carrier_weight_other","amount","origination")
-            ->paginate(15)->append(["carrier_name","amount_unit_name","remove_relation"])->toJson());
-        $url = config('api_logistic.collectUpload.ZTO.prod.url');
-        $xAppKey =  config('api_logistic.collectUpload.ZTO.prod.x-appKey');
-        $appSecret = config('api_logistic.collectUpload.ZTO.prod.appSecret');
-        $appId = config('api_logistic.collectUpload.ZTO.prod.appId');
-        dd(env('APP_ENV'));
-        //中通接口请求body
-        $collectUploadDTOS = [[
-            'billCode' => "75811463670235",
-            'weight' => 0,
-            'appId' => $appId,
-            'importDate' => now()->toDateTimeString(),
-        ]];
-        $body = json_encode([
-            'collectUploadDTOS' => $collectUploadDTOS,
-        ], JSON_UNESCAPED_UNICODE);
-        $data_digest = base64_encode(md5($body . $appSecret, TRUE));
-        $headers = [
-            'Content-Type' => 'application/json; charset=UTF-8',
-            'x-companyid' => $xAppKey,
-            'x-datadigest' => $data_digest,
-        ];
-        dd(Http::withHeaders($headers)->withBody($body, 'application/json')->post($url)->body());
-
-       $stores = Store::query()->whereIn("id",[490692,492252,492405,493259,491290,491758,492252,492989,493522,
-           496079,490702,491173,491780,493522,488622,490891,491020,491173,493308,489448,491020,491184,493573,493977,
-           496105,492086,493714,493977,496118,492593,492592,492591,492590,493011,493979,490721,492192,493429,493978,
-           496106,490721,491460,493165,496114,489319,489436,490703,491190,493957,496115,496114,489436,491147,
-           491695,492395,490711,491461,491695,492079,494533,496099,496096,490711,491458,491797,492244,
-           492422,496098,496097,496100,491458,491798,493572,493752,490443,491457,492394,493531,493572,491687,
-           492394,492968,493782,490431,490994,493782,488570,489103,490616,490994,493966,489862,490616,
-           490629,495645,490629,491455,488793])->get();
-       $this->dispatch(new StoreCreateInstantBill($stores));
-       dd(1);
-
-        /** @var StationTaskMaterialBox $stationTaskMaterialBox */
-        $stationTaskMaterialBox = app("StorageService")->createWarehousingTask($stationService->getStation_byType('立库')["id"],$station->materialBox->id);
-        app("CacheShelfService")->lightUp($station->code,'3','0',['title'=>"等待机器人拿走,请勿操作"]);
-        Cache::forever("CACHE_SHELF_OCCUPANCY_{$station->id}",true);
-        dd($ForeignHaiRoboticsService->putBinToStore_fromCacheShelf($stationTaskMaterialBox, $station));
-        $user = Auth::user();
-        $remark = "zengjunlj";
-        $ownerName = 'zengjunlj' ?? '';
-        $clientCode = 'zengjunljljlj' ?? '';
-        $msg = $user["name"]."建立了新工单<br/>".$ownerName.":".$clientCode."<br/>".$remark;
-        NotificationService::SingleRegister($msg,$clientCode,"订单管理-问题件");
-        dd(1);
-        $seeLog = SeeLog::query()->find(9);
-        Notification::send(Auth::user(),new RoutineNotification($seeLog->toArray()));
-        dd(1);
-        Broadcast::channel('notification', function ($user, $id) {
-            return (int) $user->id === (int) $id;
-        });
-        dd(1);
-        Notification::send(Auth::user(),new RoutineNotification($seeLog->toArray()));
-        dd(1);
-        $username = config('database.connections.oracle.username');
-        $password = config('database.connections.oracle.password');
-        $host = config('database.connections.oracle.host');
-        $service_name = config('database.connections.oracle.service_name');
-        $conn = oci_connect($username, $password, $host . '/' . $service_name,"utf8");
-        $sql = <<<sql
-BEGIN
-    SPSO_HardAllocation_Process('WH01','Allocation','By OrderNO',
-                                 null,'SO21090100007','0',null,
-    'zhouzhendong',:CODE);
-END;
-sql;
-
-        $stmt = oci_parse($conn, $sql);
-        $code = "";
-        oci_bind_by_name($stmt, ':CODE', $code,300);
-        oci_execute($stmt);
-        oci_close($conn);
-        dd($code);
-        //
-
-        $no = "SO21090900001";
-
-
-        $db = DB::connection("oracle");
-        //$order = $db->selectOne(DB::raw("select * from DOC_ORDER_HEADER where orderno = ?"),[$no]);
-        dd($db->select($sql,[
-        ]));
-        $db->select("CALL SPSO_HardAllocation_Process(?,'Allocation','By OrderNO',null,?,'0',null,'zhouzhendong',@code)",[
-            $order->warehouseid,$no
-        ]);
-        //SPSO_HardAllocation_Process
-        dd($db->selectOne("select @code"));
-        $date = "2021-09-14 15:47:00";
-        dispatch(new TestJob("1"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("2"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("3"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("4"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("5"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("6"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("7"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("8"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("9"))->delay(Carbon::parse($date));
-        dispatch(new TestJob("10"))->delay(Carbon::parse($date));
-        dd(1);
-
-
-        Station::query()->where("station_type_id", 5)->update(["status" => 1]);
-        Cache::forget("CACHE_SHELF_AVAILABLE");
-        $station = ["HAIB1-01-01", "HAIB1-02-01"];
-        $material = ["IDE0001824", "IDE0001740", "IDE0002710"];
-        Station::query()->whereIn("code", $station)->update(["status" => 0]);
-        $stations = Station::query()->whereIn("code", $station)->get();
-        $materials = MaterialBox::query()->whereIn("code", $material)->get();
-        $dateTime = date("Y-m-d H:i:s");
-        $task1 = StationTaskMaterialBox::query()->create([
-            'station_id' => $stations[0]->id,
-            'material_box_id' => $materials[0]->id,
-            'station_task_batch_id' => 1,
-            'status' => '待处理'
-        ]);
-        $task2 = StationTaskMaterialBox::query()->create([
-            'station_id' => $stations[1]->id,
-            'material_box_id' => $materials[1]->id,
-            'station_task_batch_id' => 1,
-            'status' => '待处理'
-        ]);
-        $task3 = StationTaskMaterialBox::query()->create([
-            'station_id' => 6,
-            'material_box_id' => $materials[2]->id,
-            'station_task_batch_id' => 1,
-            'status' => '待处理'
-        ]);
-        TaskTransaction::query()->insert([[
-            "doc_code" => "test",
-            "bar_code" => "test",
-            "to_station_id" => $stations[0]->id,
-            "material_box_id" => $materials[0]->id,
-            "task_id" => $task1->id,
-            "commodity_id" => 505012,//XUNI03
-            "amount" => 1,
-            "type" => "出库",
-            "status" => 0,
-            "mark" => 2,
-            "bin_number" => 1,
-            "created_at" => $dateTime,
-            "updated_at" => $dateTime,
-        ], [
-            "doc_code" => "test",
-            "bar_code" => "test",
-            "to_station_id" => $stations[1]->id,
-            "material_box_id" => $materials[1]->id,
-            "task_id" => $task2->id,
-            "commodity_id" => 505012,//XUNI03
-            "amount" => 1,
-            "type" => "出库",
-            "status" => 0,
-            "mark" => 2,
-            "bin_number" => 1,
-            "created_at" => $dateTime,
-            "updated_at" => $dateTime,
-        ], [
-            "doc_code" => "test",
-            "bar_code" => "test",
-            "to_station_id" => 6,
-            "material_box_id" => $materials[2]->id,
-            "task_id" => $task3->id,
-            "commodity_id" => 505012,//XUNI03
-            "amount" => 1,
-            "type" => "出库",
-            "status" => 3,
-            "mark" => 2,
-            "bin_number" => 1,
-            "created_at" => $dateTime,
-            "updated_at" => $dateTime,
-        ]]);
-        $foreignHaiRoboticsService = new ForeignHaiRoboticsService();
-        $toLocation = collect($station);
-        $taskMaterialBoxes = collect([$task1, $task2]);
-        $foreignHaiRoboticsService->
-        fetchGroup_multiLocation($toLocation, $taskMaterialBoxes, '', '立架出至缓存架', 20, false);
-        foreach ($toLocation as $index => $value) {
-            app("CacheShelfService")->lightUp($value, '3', '0', ["title" => "机器人取箱中,禁止操作"]);
-            Cache::forever("CACHE_SHELF_OCCUPANCY_{$stations[$index]->id}", true);
-        }
-        app("StationService")->locationOccupyMulti($toLocation->toArray());
+        dd(app("MenuService")->getVisibleFunctionList());
+        dd($this->response("德玛西亚",[]));
+       $st = '[{"taskMode":1,"bins":[{"taskCode":"102876_1632099648.1379","binCode":"IDE0000686","fromLocCode":"BIN-IN1","toLocCode":""}],"groupCode":"_1632099648.1379","priority":10,"sequenceFlag":1}]';
+       $st = json_decode($st,true);
+       $st[0]["sequenceFlag"] = 0;
+       dd(json_encode($st));
+       $order = Order::query()->find(4367620);
+       $s = new OrderService();
+       $s->createInstantBill($order);
     }
 
     public function update_order_packages_is_manual_update()
@@ -656,7 +482,7 @@ sql;
 
     public function init_SettlementBillReportTask()
     {
-        $this->dispatch(new SettlementBillReportJob('2021-08-01',[]));
+        $this->dispatch(new SettlementBillReportJob('2021-09-01',[]));
     }
     public function test2(){
         $source_file ="E:\OneDrive\桌面\工作目录\文件库\\5.jpg";
@@ -744,4 +570,69 @@ sql;
 
         \App\LaborCompanyDispatchDetail::query()->truncate();
     }
+
+    public function testChange()
+    {
+        $last_start_key = config('sync.order_sync.cache_prefix.last_start_at');
+        $last_end_key = config('sync.order_sync.cache_prefix.last_end_at');
+        Cache::put($last_start_key,Carbon::make('2021-10-12 06:23:37'));
+        Cache::put($last_end_key,Carbon::make('2021-10-12 06:23:38'));
+        ValueStore::query()->where('name','order_last_created_sync_at')->update(['value' => '2021-10-12 06:23:37']);
+        ValueStore::query()->where('name','order_last_updated_sync_at')->update(['value' => '2021-10-12 06:23:37']);
+        ValueStore::query()->where('name','last_order_sync_task_start_at')->update(['value' => '2021-10-12 06:23:37']);
+        ValueStore::query()->where('name','last_order_sync_task_end_at')->update(['value' => '2021-10-12 06:23:38']);
+    }
+
+    public function syncOrders()
+    {
+        $last_start_key = config('sync.order_sync.cache_prefix.last_start_at');
+        $last_end_key = config('sync.order_sync.cache_prefix.last_end_at');
+        ini_set('max_execution_time',2500);
+        ini_set('memory_limit','1526M');
+        $service = new OracleDOCOrderHeaderService();
+        $orderService = new OrderService();
+        $start_data = Carbon::make('2021-10-12 06:23:37');
+        for ($i = 0;$i < 7;$i++){
+            $last_start_data=  Carbon::now();
+            $end_data = Carbon::parse($start_data)->addHours(1);
+            $editHeaders =  $service->getQuery()->where('DOC_Order_Header.EditTime','>=',$start_data)
+                ->where('DOC_Order_Header.EditTime',"<=",$end_data)
+                ->orderByDesc('DOC_Order_Header.EditTime')
+                ->get();
+            $editHeaderArray = $editHeaders->chunk(200);
+            foreach ($editHeaderArray as &$array){
+                $orderService->syncOrder($array);
+            }
+            $addHeaders =  $service->getQuery()->where('DOC_Order_Header.addTime','>=',$start_data)
+                ->where('DOC_Order_Header.addTime',"<=",$end_data)
+                ->orderByDesc('DOC_Order_Header.addTime')
+                ->get();
+
+            $addHeadersArray = $addHeaders->chunk(200);
+            foreach ($addHeadersArray as &$array){
+                $orderService->syncOrder($array);
+            }
+
+            $start_data = $end_data;
+            $last_end_data  = Carbon::now();
+
+            Cache::put($last_start_key,$last_start_data);
+            ValueStore::query()->where('name','order_last_created_sync_at')->update(['value' => $addHeaders->first()->addtime]);
+            ValueStore::query()->where('name','last_order_sync_task_start_at')->update(['value' => $last_start_data]);
+            Cache::put($last_end_key,$last_end_data);
+            ValueStore::query()->where('name','order_last_updated_sync_at')->update(['value' => $editHeaders->first()->edittime]);
+            ValueStore::query()->where('name','last_order_sync_task_end_at')->update(['value' => $last_end_data]);
+            unset($editHeaderArray,$editHeaders);
+            unset($addHeadersArray,$addHeaders);
+        }
+    }
+
+    public function syncOrder()
+    {
+        $code = \request("code");
+        $service = new OracleDOCOrderHeaderService();
+        $orderService = new OrderService();
+        $orderHeaders = $service->getQuery()->where('DOC_Order_Header.WaveNo',$code)->get();
+        $orderService->syncOrder($orderHeaders);
+    }
 }

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

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\WorkOrderCommodities;
+use Illuminate\Http\Request;
+
+class WorkOrderCommoditiesController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\WorkOrderCommodities  $workOrderCommodities
+     * @return \Illuminate\Http\Response
+     */
+    public function show(WorkOrderCommodities $workOrderCommodities)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\WorkOrderCommodities  $workOrderCommodities
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(WorkOrderCommodities $workOrderCommodities)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\WorkOrderCommodities  $workOrderCommodities
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, WorkOrderCommodities $workOrderCommodities)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\WorkOrderCommodities  $workOrderCommodities
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(WorkOrderCommodities $workOrderCommodities)
+    {
+        //
+    }
+}

+ 59 - 17
app/Http/Controllers/WorkOrderController.php

@@ -3,13 +3,11 @@
 namespace App\Http\Controllers;
 
 use App\Filters\WorkOrderFilters;
+use App\Http\Requests\WorkOrder\WorkOrderRequest;
 use App\Logistic;
 use App\OrderIssue;
-use App\OrderIssueType;
-use App\Services\OwnerService;
 use App\Services\WorkOrderService;
 use App\WorkOrder;
-use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Gate;
 
@@ -56,18 +54,11 @@ class WorkOrderController extends Controller
         if (OrderIssue::query()->whereIn('order_id',$work_orders->map(function($item){return $item['order_id'];}))->exists()){
             return ['success' => false, 'message' => '已有对应的问题件'];
         }
-        try {
-            $result = $service->buildOrderIssue($work_orders);
-            if (!$result['success']) return $result;
-            $workOrders = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
-                /** @var $query Builder */
-                $query->with('packages', 'issue', 'logistic');
-            }, 'reviewer', 'issueType'])->whereIn('id', $request['ids'])->get();
-            $service->tags($workOrders);
-            return ['success' => true, 'data' => $workOrders];
-        } catch (\Exception $e) {
-            return  ['success' => true, 'message' => '创建问题件失败,检查对应问题件是否存在,刷新重试'];
-        }
+        $result = $service->buildOrderIssue($work_orders);
+        if (!$result['success']) return $result;
+        $workOrders = WorkOrder::query()->defaultWith()->whereIn('id',$request['ids'])->get();
+        $service->tags($workOrders);
+        return ['success' => true ,'data' => $workOrders];
     }
 
     // 创建工单 api
@@ -75,12 +66,43 @@ class WorkOrderController extends Controller
     {
         if (Gate::denies('订单管理-订单-生成工单'))
             return ['success' => false, 'message' => '没有对应权限'];
-        $params = $request['params'];
+        $params = $request->all();
         if (count($params) == 0) return ['success' => false,'message' => '参数异常'];
         app('OrderService')->syncOrderByCodes(array_map(function($param){
             return $param['order_no'];
         },$params));
-        return  $service->build($request['params']);
+        return  $service->build($params);
+    }
+
+    // 破损工单
+    public function damagedApi(WorkOrderRequest $request, WorkOrderService $service): array
+    {
+        if (Gate::denies('订单管理-订单-生成工单'))
+            return ['success' => false, 'message' => '没有对应权限'];
+        app('OrderService')->syncOrderByCodes([$request->input('order_no')]);
+
+        $workOrder =  $service->createDamagedWorkOrder($request->all());
+
+        if ($workOrder) return ['success' => true];
+        else return  ['success' => false];
+    }
+
+    // 遗失工单信息 填充
+    public function updateLossApi(Request $request, WorkOrderService $service): array
+    {
+        if (Gate::denies('订单管理-工单处理-货主编辑'))
+            return ['success' => false, 'message' => '没有对应权限'];
+
+        /** @var WorkOrder $workOrder */
+        $workOrder = WorkOrder::query()->where('id',$request->input('id'))->first();
+
+        if (!$workOrder) return ['success' => false,'message' => '参数异常'];
+
+        $workOrder = $service->fillLossWorkOrder($workOrder,$request->all());
+
+        if(!$workOrder) return ['success' => false,'message' => '创建异常'];
+
+        return ['success' => true, 'data' => $workOrder];
     }
 
     // 修改问题类型
@@ -109,8 +131,28 @@ class WorkOrderController extends Controller
     {
         if (Gate::denies('订单管理-工单处理-删除'))
             return ['success' => false,'message' => '没有对应权限'];
+        $workOrder = WorkOrder::query()->where('id',$id)->first();
+        if (! $workOrder)
+            return ['success' => false,'message' => '对应工单信息未找到'];
+        if ($workOrder->status == '已处理'){
+            return ['success' => false,'message' => '对应工单已处理,拒绝删除'];
+        }
         WorkOrder::query()->where('id',$id)->Delete();
         return ['success' => true];
     }
 
+    public function updateWorkOrderStatusApi(Request $request): array
+    {
+        if (Gate::denies('订单管理-工单处理-宝时编辑'))
+            return  ['success' => false,'message' => '没有对应权限'];
+        try {
+            $workOrder = WorkOrder::query()->find($request['id']);
+            $workOrder->work_order_status = $request['work_order_status'];
+            $workOrder->update();
+        } catch (\Exception $e) {
+            return ['success' => false,'message' => '编辑工单状态失败'];
+        }
+        return ['success' => true];
+    }
+
 }

+ 85 - 0
app/Http/Controllers/WorkOrderDetailController.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\WorkOrderDetail;
+use Illuminate\Http\Request;
+
+class WorkOrderDetailController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\WorkOrderDetail  $workOrderDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function show(WorkOrderDetail $workOrderDetail)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\WorkOrderDetail  $workOrderDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(WorkOrderDetail $workOrderDetail)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\WorkOrderDetail  $workOrderDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, WorkOrderDetail $workOrderDetail)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\WorkOrderDetail  $workOrderDetail
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(WorkOrderDetail $workOrderDetail)
+    {
+        //
+    }
+}

+ 85 - 0
app/Http/Controllers/WorkOrderImageController.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\WorkOrderImage;
+use Illuminate\Http\Request;
+
+class WorkOrderImageController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\WorkOrderImage  $workOrderImage
+     * @return \Illuminate\Http\Response
+     */
+    public function show(WorkOrderImage $workOrderImage)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\WorkOrderImage  $workOrderImage
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(WorkOrderImage $workOrderImage)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\WorkOrderImage  $workOrderImage
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, WorkOrderImage $workOrderImage)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\WorkOrderImage  $workOrderImage
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(WorkOrderImage $workOrderImage)
+    {
+        //
+    }
+}

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

@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\WorkOrderProcessLogService;
+use App\WorkOrderProcessLog;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+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];
+    }
+}

+ 29 - 0
app/Http/Controllers/api/thirdPart/syrius/producer/BinLocation.php

@@ -0,0 +1,29 @@
+<?php
+
+
+namespace App\Http\Controllers\api\thirdPart\syrius\producer;
+
+class BinLocation extends Controller
+{
+    /**
+     * @param string $locationId
+     * @param \stdClass $warehouse  {id:"",name:""}
+     * @param \stdClass $attribute  {id:"",layer:0,num:0}
+     *
+     */
+    public function createBinLocation(string $locationId, \stdClass $warehouse, \stdClass $attribute)
+    {
+        $url = config("api.syrius.request.bin_location");
+        $body = [[
+            "binLocationId"     => $locationId,     //库位ID
+            "warehouseId"       => $warehouse->id,  //仓库ID
+            "warehouseName"     => $warehouse->name,//仓库名
+            "attributes"        => [
+                "shelfId"    => $attribute->id,     //架ID
+                "shelfLayer" => $attribute->layer,  //架层
+                "numOfLayer" => $attribute->num,    //架层数
+            ],
+        ]];
+        $this->response($url,$body);
+    }
+}

+ 36 - 0
app/Http/Controllers/api/thirdPart/syrius/producer/Controller.php

@@ -0,0 +1,36 @@
+<?php
+
+
+namespace App\Http\Controllers\api\thirdPart\syrius\producer;
+
+
+use Illuminate\Http\Client\ConnectionException;
+use Illuminate\Http\Client\Response;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Http;
+use Illuminate\Support\Facades\Log;
+
+class Controller
+{
+    public function response($url, $data): ?Response
+    {
+        $logInfo = [
+            "param" =>  $data,
+            "user"  =>  Auth::id(),
+            "ip"    =>  request()->ip(),
+        ];
+
+        $token = "";
+        try {
+            return Http::withHeaders([
+                'Accept' => 'application/json',
+                'Authorization' => 'Bearer '.$token,
+            ])->post($url,$data);
+        }catch (ConnectionException $e){
+            Log::warning("syrius:连接异常",$logInfo);
+        }catch (\Exception $e){
+            Log::warning("syrius:请求异常",$logInfo);
+        }
+        return null;
+    }
+}

+ 2 - 2
app/Http/Requests/Api/WaybillDispatch.php

@@ -19,8 +19,8 @@ class WaybillDispatch extends AndroidGateRequest
             "inquire_tel"           => ["required","string","max:20"],
             "amount"                => ["required","integer","min:1"],
             "amount_unit_name"      => ["required",Rule::in(["件","托"])],
-            "carrier_weight_other"  => ["required_without:carrier_weight","numeric","min:0.01"],
-            "carrier_weight"        => ["required_without:carrier_weight_other","numeric","min:0.01"],
+            "carrier_weight_other"  => ["required_without:carrier_weight","nullable","numeric","min:0.01"],
+            "carrier_weight"        => ["required_without:carrier_weight_other","nullable","numeric","min:0.01"],
             "subjoin_fee"           => ["nullable","string"],
         ];
     }

+ 76 - 0
app/Http/Requests/WorkOrder/WorkOrderRequest.php

@@ -0,0 +1,76 @@
+<?php
+
+namespace App\Http\Requests\WorkOrder;
+
+use App\Traits\RequestApiFormValidation;
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Route;
+
+class WorkOrderRequest extends FormRequest
+{
+
+    use RequestApiFormValidation;
+    /**
+     * Determine if the user is authorized to make this request.
+     *
+     * @return bool
+     */
+    public function authorize()
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        $routeName = Route::currentRouteName();
+        switch ($routeName ){
+            case 'workOrder.damagedApi':
+                return $this->damagedApiRule();
+            default:
+                return [];
+        }
+    }
+
+    public function messages(): array
+    {
+        $routeName = Route::currentRouteName();
+        switch ($routeName ){
+            case 'workOrder.damagedApi':
+                return $this->damagedApiMessage();
+            default:
+                return [];
+        }
+    }
+
+    public function damagedApiRule(): array
+    {
+        return [
+            'type' => 'required|string',
+            'order_no' => 'required|string',
+            'packageImages' => 'required|array',
+            'commodityImages' => 'required|array',
+            'dealImages' => 'required|array',
+            ];
+    }
+
+    public function damagedApiMessage(): array
+    {
+        return [
+            'type.required' => '未指定工单类型',
+            'type.string' => '工单类型格式不正确',
+            'order_no.required' => '未指定订单',
+            'order_no.string' => '订单数据格式不正确',
+            'packageImages.required' => '未上传外包装图片',
+            'packageImages.array' => '外包装图片按数组格式上传',
+            'commodityImages.required' => '未上传内物图片',
+            'commodityImages.array' => '内物图片按数组格式上传',
+            'dealImages.required' => '未上传交易图片',
+            'dealImages.array' => '交易图片按数组格式上传',
+        ];
+    }
+}

+ 1 - 1
app/Imports/StoreCheckingReceiveImport.php

@@ -96,7 +96,7 @@ class StoreCheckingReceiveImport implements ToCollection,WithHeadingRow
                 "unique_code" => $item["唯一码"],
                 "SKU" => $item["SKU"],
                 "商品名称" => $item["商品名称"],
-                "条码" => $item["条码"],
+                "条码" => rtrim(ltrim($item["条码"])),
             ]);
             if ($isUniqueCommodity){
                 array_push($commodities[$item["条码"]], count($items)-1);

+ 44 - 0
app/Jobs/CalculationArrivedManNumJob.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Services\LaborApplyService;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Carbon;
+
+/**
+ * 按照给定的申请日期计算到岗人数
+ */
+class CalculationArrivedManNumJob implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+    /** @var $service LaborApplyService */
+    private $service;
+
+    /** @var $apply_date Carbon */
+    private $apply_date;
+
+    /**
+     * @param Carbon $apply_date
+     */
+    public function __construct(Carbon $apply_date)
+    {
+        $this->service = app('LaborApplyService');
+        $this->apply_date = $apply_date;
+    }
+
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+       $this->service->calculationArrivedManNum($this->apply_date);
+    }
+}

+ 1 - 1
app/LaborApply.php

@@ -79,7 +79,7 @@ class LaborApply extends Model
     public function getArriveRateAttribute()
     {
         if (0 === $this->actual_num) {
-            return '';
+            return '0'.'%';
         }
         $apply_num = $this->man_num + $this->woman_num;
         $arrive_rate = $this->actual_num / $apply_num * 100;

+ 35 - 2
app/LaborCompanyDispatch.php

@@ -17,18 +17,51 @@ class LaborCompanyDispatch extends Model
 
     use ModelTimeFormat;
 
-    public $fillable = [
+    protected $fillable = [
         'labor_company_id',//劳务公司ID
         'man_num',//男工数量
         'woman_num',//女工数量
         'dispatch_date',//分配日期
         'exceed_max_labor_num_status',//是否超过最大允许值 1 未超过 2 超过
+        'status',//状态
     ];
 
-    public $dates = [
+
+    protected $dates = [
         'dispatch_date'
     ];
 
+    static public $enums = [
+        'status' => [
+            '' => 0,
+            '创建' => 1,
+            '人事确认' => 2,
+            '劳务接单' => 3,
+            '任务完结' => 4,
+        ],
+    ];
+
+    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 0;
+        $this->attributes['status'] = self::$enums['status'][$value];
+    }
+
     public function laborCompany(): BelongsTo
     {
         return $this->belongsTo(LaborCompany::class);

+ 3 - 5
app/OrderIssue.php

@@ -167,11 +167,9 @@ class OrderIssue extends Model
                 $code = $item->barcode_goods;
                 $exists = Commodity::query()->where("sku", $code)->where('owner_id',$owner_id)->exists();
                 if (!$exists) {
-                    $commodityBarcode = CommodityBarcode::query()->with(['commodity' => function ($query) use ($owner_id) {
-                        /** @var Builder $query */
-                        $query->where('owner_id', $owner_id)->whereNotNull('sku');
-                    }])->where('code', $code)->first();
-                    if($commodityBarcode && $commodityBarcode->commodity) $code = $commodityBarcode->commodity->sku;
+                    $commodityBarcodeQuery = CommodityBarcode::query()->select('commodity_id')->where('code',$code);
+                    $commodity = Commodity::query()->where('owner_id',$owner_id)->whereIn('id',$commodityBarcodeQuery)->first();
+                    if ($commodity)$code = $commodity->sku;
                 }
                 $qualityName = $item->quality->name;
                 if (empty($rejectedMap[$code]) || empty($rejectedMap[$code][$qualityName])) $rejectedMap[$code][$qualityName] = $item->amount;

+ 8 - 0
app/Providers/AppServiceProvider.php

@@ -184,6 +184,10 @@ use App\Services\WorkOrderTypeService;
 use App\Services\OrderPackageRemarkService;
 use App\Services\LaborCompanyService;
 use App\Services\NotificationService;
+use App\Services\WorkOrderDetailService;
+use App\Services\WorkOrderCommoditiesService;
+use App\Services\WorkOrderImageService;
+use App\Services\WorkOrderProcessLogService;
 use App\Services\LaborApplyService;
 
 class AppServiceProvider extends ServiceProvider
@@ -379,6 +383,10 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('WaybillFinancialService', WaybillFinancialService::class);
         app()->singleton('WaybillService', WaybillService::class);
         app()->singleton('WeighExceptedService', WeighExceptedService::class);
+        app()->singleton('WorkOrderCommoditiesService',WorkOrderCommoditiesService::class);
+        app()->singleton('WorkOrderDetailService',WorkOrderDetailService::class);
+        app()->singleton('WorkOrderImageService',WorkOrderImageService::class);
+        app()->singleton('WorkOrderProcessLogService',WorkOrderProcessLogService::class);
         app()->singleton('WorkOrderService',WorkOrderService::class);
         app()->singleton('WorkOrderTypeService',WorkOrderTypeService::class);
     }

+ 12 - 0
app/Services/CommodityService.php

@@ -948,4 +948,16 @@ class CommodityService
        $sku = array_keys($map);
        if ($sku)$this->syncWMSOrderCode($ownerId,$sku);
     }
+
+    public function getCommodityBy($owner,$sku)
+    {
+        $commodity = Commodity::query()->where('owner_id',$owner->id)->where('sku',$sku)->first();
+        if ($commodity) return $commodity;
+        $barcode = CommodityBarcode::query()->with('commodity')->where('code',$sku)->whereHas('commodity',function ($query)use($owner){
+            /** @var Builder $query */
+            $query->where('id',$owner->id);
+        })->first();
+        if ($barcode) return $barcode->commodity;
+        return false;
+    }
 }

+ 1 - 0
app/Services/ForeignHaiRoboticsService.php

@@ -407,6 +407,7 @@ class ForeignHaiRoboticsService
      */
     public function controlHaiRobot(array $dataToPost,Collection $taskMaterialBoxes,$modeName): bool
     {
+        $dataToPost[0]["sequenceFlag"] = 0; //TODO 关闭组内有序
         LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1:'.json_encode($dataToPost));
         try{
             LogService::log('海柔请求','runMany','波次任务分配6.r5f2c1.51:');

+ 58 - 1
app/Services/LaborApplyService.php

@@ -9,8 +9,10 @@ use App\LaborApply;
 use App\Warehouse;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
+use function DeepCopy\deep_copy;
 
 class LaborApplyService
 {
@@ -18,6 +20,10 @@ class LaborApplyService
     const TIME_OUT_HOUR = 19;
     const LABOR_APPLY_STATUS = 'LABOR_APPLY_STATUS';
     const LABOR_APPLY_STATUS_TTL = 60 * 30;
+    //到岗日期是申请日期的前一天 为保证数据正确 计算实际人数的时间为到岗日期的后一天 故时间为2
+    const CALCULATION_ARRIVED_MAN_NUM_DEFAULT_SUB_DAYS = 2;
+    //临时工工作时长最小值 低于这个时间的不计入
+    const CALCULATION_ARRIVED_MAN_NUM_MIN_ONLINE_DURATION = 1;
     use ServiceAppAop;
 
     protected $modelClass = LaborApply::class;
@@ -68,7 +74,7 @@ class LaborApplyService
 
         //查询全部仓库
         $warehouses = Warehouse::all();
-        //按照仓库,
+        //给每个仓库计算分配数据 更改申请状态为指派成功
         foreach ($warehouses as $warehouse) {
             //查询当日的的申请,将申请的男女工分别加和
             $apply_man_nums = DB::table('labor_applies')
@@ -140,6 +146,7 @@ class LaborApplyService
                     'woman_num' => $dispatch_woman_num,
                     'dispatch_date' => $dispatch_date,
                     'exceed_max_labor_num_status' => LaborCompanyDispatch::NOT_EXCEED_MAX_LABOR_NUM,//没有超限额
+                    'status' => 1,//创建
                 ];
             }
 
@@ -168,4 +175,54 @@ class LaborApplyService
         }
         return $builder->get();
     }
+
+    /**
+     * 按照给定的申请日期计算到岗人数
+     *
+     * 查询指定日期的 每个小组的申请人数
+     * 遍历申请数据
+     *      根据申请数据的仓库小组id,日期(申请日期后一天)查询打卡数据,计算人数之和 更新申请表actual_num
+     * @param Carbon|null $apply_date
+     */
+    public function calculationArrivedManNum(Carbon $apply_date = null)
+    {
+        //查询的申请日期
+        if (empty($apply_date)) {
+            $apply_date = now()->subDays(self::CALCULATION_ARRIVED_MAN_NUM_DEFAULT_SUB_DAYS);
+        }
+        //查询指定日期的 每个小组的申请人数
+        $laborApplies = DB::table('labor_applies')
+            ->selectRaw('user_workgroup_id as user_workgroup_id , sum(man_num + woman_num) as apply_num , warehouse_id')
+            ->whereDate('created_at', $apply_date->toDateString())
+            ->groupBy('user_workgroup_id','warehouse_id')
+            ->get();
+        //根据申请数据的仓库小组id,日期(申请日期后一天)
+        $check_in_at = deep_copy($apply_date)->addDay()->toDateString();
+        //遍历申请数据
+        foreach ($laborApplies as $laborApply) {
+            //查询打卡数据,计算人数之和
+            $arrived_num =
+                DB::table('labor_reports')
+                    ->selectRaw("count( DISTINCT 'identity_number',identity_number) as num")//根据身份证号去重防止重复入组
+
+                    ->where('user_workgroup_id', $laborApply->user_workgroup_id)
+                    ->whereDate('check_in_at', $check_in_at)
+                    ->where('online_duration', '>=', self::CALCULATION_ARRIVED_MAN_NUM_MIN_ONLINE_DURATION)
+                    ->first()->num;
+            //更新申请表actual_num
+            LaborApply::query()
+                ->whereDate('created_at', deep_copy($apply_date)->toDateString())
+                ->where('user_workgroup_id', $laborApply->user_workgroup_id)
+                ->update([
+                    'actual_num' => $arrived_num,
+                    'status' => 4,//任务完结
+                ]);
+        }
+        //根据分配时间完结任务  $check_in_at:实际入场日期 就是 dispatch_date
+        LaborCompanyDispatch::query()
+            ->whereDate('dispatch_date', $check_in_at)
+            ->update([
+                'status' => 3//任务完结
+            ]);
+    }
 }

+ 5 - 5
app/Services/OrderPackageReceivedSyncService.php

@@ -148,22 +148,22 @@ class OrderPackageReceivedSyncService
         foreach ($logisticResponses as $logisticResponse) {
             if (empty($logisticResponse)) continue;
             $orderPackage = OrderPackage::query()->where('logistic_number', $logisticResponse['logistic_number'])->first();
-            if(empty($orderPackage)) continue;
+            if (empty($orderPackage)) continue;
             //如果已经收货,状态改为已签收
             if ($logisticResponse['received_at'] ?? false) {
                 $logisticResponse['status'] = '已签收';
             }
+            //设置异常信息
+            $logisticResponse = $this->setExceptionStatus($logisticResponse);
             //标记为手动更新的 status不更新
             if ($orderPackage->is_manual_update) {
                 //异常状态不更新
-                unset($logisticResponse['exception_status']);
+                if (isset($logisticResponse['exception_status'])) unset($logisticResponse['exception_status']);
                 //状态允许向后更新
                 if (OrderPackage::switchStatus($orderPackage->status) > OrderPackage::switchStatus($logisticResponse['status'] ?? '生成订单')) {
                     unset($logisticResponse['status']);
                 }
             }
-            //设置异常信息
-            $logisticResponse = $this->setExceptionStatus($logisticResponse);
             //标记为单号异常
             if (Str::contains($orderPackage->logistic_number, ['SO', '#', '-'])) {
                 $logisticResponse['exception_status'] = '单号异常';
@@ -183,7 +183,7 @@ class OrderPackageReceivedSyncService
             if (isset($logisticResponse['exception_status'])) $logisticResponse['exception_status'] = OrderPackage::switchExceptionStatus($logisticResponse['exception_status']);
             if (isset($logisticResponse['status'])) $logisticResponse['status'] = OrderPackage::switchStatus($logisticResponse['status']);
             if (isset($logisticResponse['routes_length'])) unset($logisticResponse['routes_length']);
-            if(empty($logisticResponse['transfer_status'])) unset($logisticResponse['transfer_status']);
+            if (empty($logisticResponse['transfer_status'])) unset($logisticResponse['transfer_status']);
             OrderPackage::query()->where('logistic_number', $logisticResponse['logistic_number'])
                 ->update($logisticResponse);
         }

+ 9 - 9
app/Services/OrderPackageService.php

@@ -26,6 +26,7 @@ class OrderPackageService
     const CACHE_COLLECT_FLAG = 'CACHE_COLLECT_FLAG';
     //揽收缓存的过期时间
     const CACHE_COLLECT_FLAG_TTL = 3600 * 24;
+    const ZT_COLLECT_UPLOAD_DEFAULT_WEIGHT = 0.01; //中通自动揽收默认重量
     protected $modelClass = OrderPackage::class;
 
     public function batchUpdate(array $params)
@@ -98,7 +99,7 @@ class OrderPackageService
 
     public function getByOrderNos($orderNos)
     {
-        return OrderPackage::query()->with('order')
+        return OrderPackage::query()->with('order.logistic')
             ->whereIn('order_id', function ($query) use ($orderNos) {
                 $query->from('orders')->select('id')->whereIn('code', $orderNos);
             })->get();
@@ -163,7 +164,7 @@ class OrderPackageService
         /** 批量添加 */
         if (count($inner_params) > 0) {
             try {
-                $inner_array = array_chunk($inner_params, 5000);
+                $inner_array = array_chunk($inner_params, 200);
                 foreach ($inner_array as $params) {
                     $bool = $this->insert($params);
                     $bool ? LogService::log(__METHOD__, __FUNCTION__, '批量添加 OrderPackage ' . count($inner_params) . ' || ' . json_encode($inner_params)) : null;
@@ -286,7 +287,7 @@ class OrderPackageService
         $update_params[] = ['id', 'sent_at'];
         foreach ($packages as $package) {
             if ($package->sent_at || !isset($map[$package->logistic_number])) continue;
-            list($allocation,$orderHeader) = $map[$package->logistic_number];
+            $allocation = $map[$package->logistic_number];
             try {
                 $checktime = $allocation->checktime;
             } catch (\Exception $e) {
@@ -294,7 +295,7 @@ class OrderPackageService
             }
             if ($checktime) {
                 //EDISENDFLAG
-                $this->checkingAndProcess($package,$allocation->orderlineno,$orderHeader); //检查和处理揽收
+                $this->checkingAndProcess($package,$allocation->orderlineno); //检查和处理揽收
                 $update_params[] = [
                     'id' => $package->id,
                     'sent_at' => $checktime,
@@ -309,13 +310,12 @@ class OrderPackageService
      *
      * @param OrderPackage|\stdClass $package
      * @param int $lineNo
-     * @param \stdClass|mixed $orderHeader
      */
-    public function checkingAndProcess(OrderPackage $package, int $lineNo, $orderHeader)
+    public function checkingAndProcess(OrderPackage $package, int $lineNo)
     {
         //校验快递商 订单状态 复核标记 揽收标记
-        $package->loadMissing("order.logistic");
         if ($package->collecting_status == '1' || !$package->logistic_number)return;
+        $package->loadMissing("order.logistic");
         if (strpos($package->order->logistic->code ?? '','ZTO') === false)return;
         $statusMapping = array_flip(Order::STATUS);
         if (($statusMapping[$package->order->wms_status] ?? 90) == 90){
@@ -341,7 +341,7 @@ class OrderPackageService
             $actAllocationDetails = $orderHeader->actAllocationDetails;
             foreach ($actAllocationDetails as $actAllocationDetail) {
                 $logistic_number = $actAllocationDetail->picktotraceid;
-                $map[$logistic_number] = [$actAllocationDetail,$orderHeader];
+                $map[$logistic_number] = $actAllocationDetail;
             }
         }
         return $map;
@@ -488,7 +488,7 @@ class OrderPackageService
         foreach ($logistic_numbers_chunked_items as $logistic_number) {
             $collectUploadDTOS[] = [
                 'billCode' => $logistic_number,
-                'weight' => 0,
+                'weight' => self::ZT_COLLECT_UPLOAD_DEFAULT_WEIGHT,
                 'appId' => $appId,
                 'importDate' => now()->toDateTimeString(),
             ];

+ 3 - 1
app/Services/OwnerFeeTotalService.php

@@ -355,7 +355,9 @@ class OwnerFeeTotalService
             ->selectRaw("sum(baoshi_indemnity_money) as fee,owner_id,order_id")
             ->leftJoin('orders', 'order_issues.order_id', '=', 'orders.id')
             ->where('owner_id', $owner->id)
-            ->whereBetween('order_issues.created_at', [$start, $end])->first();
+            ->whereBetween('order_issues.created_at', [$start, $end])
+            ->whereBetween('orders.created_at', [$start, $end])
+            ->first();
         $ownerFeeTotal ['indemnityFee'] = [
             'fee' => $indemnityFee->fee ?? 0,
         ];

+ 1 - 1
app/Services/OwnerPriceExpressService.php

@@ -237,7 +237,7 @@ sql
      */
     public function getOwnerPriceExpress($owner,$logistic,$province)
     {
-        return Cache::tags("expressFeeOwner:".$owner)->remember("expressFee:".$owner.$logistic.$province,config("cache.expirations.rarelyChange"),
+        return Cache::tags("expressFeeOwner:".$owner)->remember("expressFee:".$owner."_".$logistic."_".$province,config("cache.expirations.rarelyChange"),
             function ()use($owner,$logistic,$province){
                 return OwnerPriceExpress::query()->with(["details"=>function($query)use($province){
                     /** @var Builder $query */

+ 42 - 10
app/Services/OwnerStoreFeeReportService.php

@@ -2,8 +2,10 @@
 
 namespace App\Services;
 
+use App\Owner;
 use App\OwnerBillReport;
 use App\OwnerBillReportArchive;
+use App\OwnerPriceOperation;
 use App\Traits\ServiceAppAop;
 use App\OwnerStoreFeeReport;
 use Carbon\Carbon;
@@ -31,7 +33,7 @@ class OwnerStoreFeeReportService implements \App\Interfaces\SettlementBillReport
      * 如果参数$counting_month为2021-01-01 则统计2021-01-01 -- 2021-01-31之间的数据
      * @param null $counting_month 统计月份,默认统计上个月的 2021-05-01
      */
-    public function recordReport($counting_month = null,array $ownerIds = [])
+    public function recordReport($counting_month = null, array $ownerIds = [])
     {
         $this->detailService = app('OwnerStoreFeeDetailService');
         if (is_null($counting_month)) {
@@ -56,18 +58,18 @@ class OwnerStoreFeeReportService implements \App\Interfaces\SettlementBillReport
             ->whereBetween('owner_fee_operations.worked_at', [$start, $end])
             ->whereNotNull('owner_fee_operation_details.price')
             ->whereNotNull('owner_fee_operation_details.amount')
-            ->whereIn('model_id', \App\OwnerPriceOperation::query()->select('id')->where('operation_type', '入库'));
+            ->whereIn('model_id', OwnerPriceOperation::query()->select('id')->where('operation_type', '入库'));
         if (!empty($ownerIds)) {
             $builder->whereIn('owner_fee_operations.owner_id', $ownerIds);
         }
         $details = $builder->groupBy(
-                    'counting_month',
-                    'owner_id',
-                    'unit_id',
-                    'price',
-                    'model_id'
-                )
-                ->get();
+            'counting_month',
+            'owner_id',
+            'unit_id',
+            'price',
+            'model_id'
+        )
+            ->get();
         $reports = [];
         foreach ($details as $detail) {
             $counting_month = Carbon::parse($detail->counting_month)->startOfMonth()->toDateString();
@@ -76,7 +78,7 @@ class OwnerStoreFeeReportService implements \App\Interfaces\SettlementBillReport
                 ->where('owner_id', $detail->owner_id)
                 ->where('counting_month', $counting_month)->first();
             $reports[] = [
-                'owner_bill_report_id' => $ownerBillReport->id ?? null,
+                'owner_bill_report_id' => $ownerBillReport->id ?? 1,
                 'owner_id' => $detail->owner_id,
                 'counting_month' => $counting_month,
                 'unit_id' => $detail->unit_id,
@@ -95,6 +97,36 @@ class OwnerStoreFeeReportService implements \App\Interfaces\SettlementBillReport
         foreach ($reports_chunked as $items) {
             OwnerStoreFeeReport::query()->insertOrIgnore($items);
         }
+
+        //没有数量的计费模型填充0数据
+        //查询到全部的货主
+        $owners = Owner::query()->with('ownerPriceOperations.items')->get();
+        foreach ($owners as $owner) {
+            $owner_id = $owner->id;
+            foreach ($owner->ownerPriceOperations as $ownerPriceOperation) {
+                $ownerPriceOperation_id = $ownerPriceOperation->id;
+                $has_report = OwnerStoreFeeReport::query()
+                    ->where('owner_id', $owner_id)
+                    ->where('model_id', $ownerPriceOperation_id)
+                    ->where('counting_month', $counting_month)
+                    ->exists();
+                if ($has_report) continue;
+
+//                foreach ($ownerPriceOperation->items as $ownerPriceOperationItem) {
+                OwnerStoreFeeReport::query()->insert([
+                    'owner_bill_report_id' => 1,
+                    'owner_id' => $owner_id,
+                    'counting_month' => $counting_month, //统计月份
+                    'unit_id' => 4, //件
+                    'unit_price' => $ownerPriceOperation->items[0]->unit_price ?? 0, //单价
+                    'amount' => 0, //数量
+                    'fee' => 0,//费用
+                    'work_name' => $ownerPriceOperation->name,//作业名称
+                    'model_id' => $ownerPriceOperation_id,//计费模型
+                    'tax_fee' => 0,//税费
+                ]);
+            }
+        }
     }
 
     public function get(array $kvPairs): array

+ 7 - 0
app/Services/UserService.php

@@ -37,6 +37,13 @@ class UserService
         })??[];
     }
 
+    function getPermittingLogisticIds($user=null){
+        if(!$user)return [];
+        return $this->cacheService->getOrExecute("user{$user['id']}->getPermittingLogisticIds",function()use($user){
+                return $user->getPermittingLogisticIdsAttribute() ?? [];
+        })??[];
+    }
+
 
     /**
      * 检查用户的管理员身份

+ 13 - 2
app/Services/WaybillService.php

@@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Model;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 use Ramsey\Uuid\Uuid;
 use App\Traits\ServiceAppAop;
 
@@ -363,7 +364,17 @@ class WaybillService
         $w->wms_bill_number = $waybill->wms_bill_number;
         $w->waybill_number  = $waybill->carrier_bill;
         $controller = new WaybillController();
-        return $controller->accomplishToWMS($w);
+        if ($controller->accomplishToWMS($w)){
+            $sql = <<<SQL
+UPDATE ACT_ALLOCATION_DETAILS SET PICKTOTRACEID = ?,DROPID = ? WHERE ORDERNO = ? AND  PICKTOTRACEID = ? AND DROPID = ?
+SQL;
+            $updateRow = DB::connection("oracle")->update($sql,[
+                $waybill->carrier_bill,$waybill->carrier_bill,$waybill->wms_bill_number,$waybill->wms_bill_number,$waybill->wms_bill_number
+            ]);
+            if ($updateRow!=1)Log::warning("德邦单号修改分配失败",["param"=>$w,"row"=>$updateRow]);
+            return true;
+        }
+        return false;
     }
 
     /**
@@ -373,7 +384,7 @@ class WaybillService
     public function getDispatchQuery():Builder
     {
         return Waybill::query()->with(["order:id,address","logistic:id,name","amountUnit:id,name"])
-            ->select("id","order_id","logistic_id","amount_unit_id",
+            ->select("id","order_id","logistic_id","amount_unit_id","deliver_at",
                 "waybill_number","destination","recipient","recipient_mobile",
                 "carrier_bill","warehouse_weight","carrier_weight","inquire_tel",
                 "warehouse_weight_other","carrier_weight_other","amount","origination")->where(function ($query){

+ 31 - 0
app/Services/WorkOrderCommoditiesService.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\WorkOrder;
+use App\WorkOrderCommodities;
+
+class WorkOrderCommoditiesService
+{
+    use ServiceAppAop;
+    protected $modelClass=WorkOrderCommodities::class;
+
+    public function createWorkOrderCommodityByJson(WorkOrder  $workOrder,$json)
+    {
+        $obj =  json_decode($json);
+        $workOrder->commodities()->create(['sku'=>$obj->sku,'amount'=>$obj->amount,'commodity_id'=>$obj->commodity_id]);
+    }
+
+    /**
+     * 工单详情
+     * @param $workOrder
+     * @param $array
+     */
+    public function createWorkOrderCommoditiesByJsonArray($workOrder,$array)
+    {
+        foreach ($array as $json) {
+            $this->createWorkOrderCommodityByJson($workOrder,$json);
+        }
+    }
+}

+ 20 - 0
app/Services/WorkOrderDetailService.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Services;
+
+ use App\Traits\ServiceAppAop;
+use App\WorkOrderDetail;
+
+class WorkOrderDetailService
+{
+    use ServiceAppAop;
+    protected $modelClass=WorkOrderDetail::class;
+
+    public function createWorkOrderDetail($workOrder,$params)
+    {
+        $param  = (new WorkOrderDetail($params))->getAttributes();
+        $workOrder->details()->create($param);
+        $workOrder->loadMissing('details');
+    }
+
+}

+ 113 - 0
app/Services/WorkOrderImageService.php

@@ -0,0 +1,113 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\WorkOrderImage;
+use Illuminate\Http\UploadedFile;
+
+class WorkOrderImageService
+{
+    use ServiceAppAop;
+    protected $modelClass=WorkOrderImage::class;
+
+    /**
+     * 外包装
+     * @param $workOrder
+     * @param $images
+     * @param bool $isLoadMissing
+     */
+    public function createWorkOrderPackageImages($workOrder,$images, bool $isLoadMissing = true)
+    {
+        foreach ($images as $image) {
+           $this->createWorkOrderPackageImage($workOrder,$image);
+        }
+        if ($isLoadMissing)$workOrder->loadMissing('packageImages');
+    }
+
+    /**
+     * @param $workOrder
+     * @param $image
+     */
+    public function createWorkOrderPackageImage($workOrder,$image)
+    {
+        /** @var UploadedFile  $image */
+        $count = $workOrder->packageImages()->count();
+        /** @var WorkOrderImage $workOrderImage */
+        $workOrderImage = $workOrder->packageImages()->create(['type' => 1, 'number' => ++$count]);
+        $workOrderImage->saveFile($image);
+    }
+
+    /**
+     * 工单商品
+     * @param $workOrder
+     * @param $images
+     * @param bool $isLoadMissing
+     */
+    public function createWorkOrderCommodityImages($workOrder,$images, bool $isLoadMissing = true)
+    {
+        foreach ($images as $image) {
+            $this->createWorkOrderCommodityImage($workOrder,$image);
+        }
+        if ($isLoadMissing)$workOrder->loadMissing('commodityImages');
+    }
+
+    /**
+     * @param $workOrder
+     * @param $image
+     */
+    public function createWorkOrderCommodityImage($workOrder,$image)
+    {
+        /** @var UploadedFile  $image */
+        $count = $workOrder->commodityImages()->count();
+        /** @var WorkOrderImage $workOrderImage */
+        $workOrderImage = $workOrder->commodityImages()->create(['type' => 2, 'number' => ++$count]);
+        $workOrderImage->saveFile($image);
+    }
+
+    /**
+     * 交易截图
+     * @param $workOrder
+     * @param $images
+     * @param bool $isLoadMissing
+     */
+    public function createWorkOrderDealImages($workOrder,$images, bool $isLoadMissing = true)
+    {
+        foreach ($images as $image) {
+            $this->createWorkOrderDealImage($workOrder,$image);
+        }
+        if ($isLoadMissing)$workOrder->loadMissing('dealImages');
+    }
+
+    public function createWorkOrderDealImage($workOrder,$image)
+    {
+        /** @var UploadedFile  $image */
+        $count = $workOrder->dealImages()->count();
+        /** @var WorkOrderImage $workOrderImage */
+        $workOrderImage = $workOrder->dealImages()->create(['type' => 3, 'number' => ++$count]);
+        $workOrderImage->saveFile($image);
+    }
+
+    /**
+     * 退款截图
+     * @param $workOrder
+     * @param $images
+     * @param bool $isLoadMissing
+     */
+    public function createWorkOrderRefundImages($workOrder, $images, bool $isLoadMissing = true)
+    {
+        foreach ($images as $image) {
+            $this->createWorkOrderRefundImage($workOrder,$image);
+        }
+        if ($isLoadMissing)$workOrder->loadMissing('refundImages');
+    }
+
+    public function createWorkOrderRefundImage($workOrder,$image)
+    {
+        /** @var UploadedFile  $image */
+        $count = $workOrder->refundImages()->count();
+        /** @var WorkOrderImage $workOrderImage */
+        $workOrderImage = $workOrder->refundImages()->create(['type' => 4, 'number' => ++$count]);
+        $workOrderImage->saveFile($image);
+    }
+}

+ 102 - 0
app/Services/WorkOrderProcessLogService.php

@@ -0,0 +1,102 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\WorkOrderProcessLog;
+use Illuminate\Support\Facades\Auth;
+
+class WorkOrderProcessLogService
+{
+    use ServiceAppAop;
+
+    protected $modelClass = WorkOrderProcessLog::class;
+
+    public function hasLogisticProcessLog($workOrderId): bool
+    {
+        return WorkOrderProcessLog::query()
+            ->where('work_order_id', $workOrderId)
+            ->where('type', '2')->exists();
+    }
+
+    public function hasBaoShiProcessLog($workOrderId): bool
+    {
+        return WorkOrderProcessLog::query()
+            ->where('work_order_id', $workOrderId)
+            ->where('type', '1')->exists();
+    }
+
+    public function createLogisticProcessLog($params)
+    {
+        // 赔偿方  是否赔偿
+        if ($params['is_indemnity'] == 1) {  // 赔偿
+            $params = [
+                'work_order_id' => $params['work_order_id'],
+                'is_indemnity' => $params['is_indemnity'],
+                'indemnity' => $params['indemnity'],
+                'indemnitor' => 1,
+                'remark' => $params['remark'],
+                'type' => 2,
+            ];
+        } else if ($params['is_indemnity'] == 2){ // 不赔偿
+            $params = [
+                'work_order_id' => $params['work_order_id'],
+                'is_indemnity' => $params['is_indemnity'],
+                'remark' => $params['remark'],
+                'indemnitor' => 0,
+            ];
+        }
+
+        $params['creator_id'] = Auth::user()['id'];
+        $params['type'] = '2';
+        $log = WorkOrderProcessLog::query()->create($params);
+        $log->workOrder()->update(['work_order_status' => '3']);
+        $this->syncOrderIssueIndemnity($log);
+        $log->loadMissing('creator');
+        return $log;
+    }
+
+    public function createBaoShiProcessLog($params)
+    {
+        if ($params['is_indemnity'] == 1){  // 赔偿
+            $params = [
+                'work_order_id' => $params['work_order_id'],
+                'is_indemnity' => $params['is_indemnity'],
+                'indemnitor' => $params['indemnitor'],
+                'indemnity' => $params['indemnity'],
+            ];
+        } else if ($params['is_indemnity'] == 2){ // 不赔偿
+            $params = [
+                'work_order_id' => $params['work_order_id'],
+                'is_indemnity' => $params['is_indemnity'],
+                'remark' => $params['remark'],
+                'indemnity' => $params['indemnity'],
+            ];
+        }
+        $params['creator_id'] = Auth::user()['id'];
+        $params['type'] = 1;
+        if ($params['is_indemnity'] == 2) $params['indemnity'] = 0;
+        $log = WorkOrderProcessLog::query()->create($params);
+        $this->syncOrderIssueIndemnity($log);
+        $log->loadMissing('creator');
+        return $log;
+    }
+
+    public function syncOrderIssueIndemnity($log)
+    {
+        if ($log->is_indemnity == '否') return;
+        $orderIssue = $log->workOrder->orderIssue;
+        if ($log->isBaoShiLog()) {
+            if ($log->indemnitor == '宝时'){
+                if ($orderIssue->baoshi_indemnity_money) return ;
+                $orderIssue->update(['baoshi_indemnity_money'=>$log->indemnity]);
+            } else if ($log->indemnitor == '承运商'){
+                if ($orderIssue->logistic_indemnity_money) return ;
+                $orderIssue->update(['logistic_indemnity_money'=>$log->indemnity]);
+            }
+        } else if ($log->isLogisticLog()){
+            if ($orderIssue->logistic_indemnity_money) return ;
+            $orderIssue->update(['logistic_indemnity_money'=>$log->indemnity]);
+        }
+    }
+}

+ 158 - 90
app/Services/WorkOrderService.php

@@ -8,8 +8,8 @@ use App\OrderIssueType;
 use App\OrderPackage;
 use App\Traits\ServiceAppAop;
 use App\WorkOrder;
-use App\WorkOrderType;
 use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Auth;
 
@@ -19,22 +19,18 @@ class WorkOrderService
 
     protected $modelClass = WorkOrder::class;
 
-    protected $work_type_relation = [
-        '拦截' => '订单拦截',
-        '信息更改' => '订单收件信息修改',
-        '其他' => '订单其他异常',
-        '快递异常' => '订单快递异常',
-        '错漏发' => '快递错漏发',
-        '破损' => '快递破损',
-    ];
-
     /**
      * 获取可生成工单的问题件类型
-     * @return Builder[]|\Illuminate\Database\Eloquent\Collection
+     * @return Builder[]|Collection
      */
     public function getIssueType()
     {
-        return OrderIssueType::query()->whereIn('name', ['拦截', '信息更改', '其他', '快递异常', '错漏发', '破损'])->get();
+        $user = Auth::user();
+        $logistic_ids = App('UserService')->getPermittingLogisticIds($user);
+        if ($user->isSuperAdmin() || count($logistic_ids) == 0) {
+            return OrderIssueType::query()->whereIn('name', ['拦截', '信息更改', '其他', '快递异常', '错漏发', '破损', '快递丢件'])->get();
+        }
+        return OrderIssueType::query()->whereIn('name', ['破损', '快递丢件'])->get();
     }
 
     /**
@@ -44,75 +40,152 @@ class WorkOrderService
      */
     public function build($params): array
     {
-        $types = [];
-        $work_order_types = [];
-        $data = Carbon::now();
-        $creator_id = Auth::user()['id'];
-        $parent = WorkOrderType::query()->firstOrCreate(['name' => '订单', 'prent_id' => 0, 'level' => 1]);
         foreach ($params as $param) {
-            $order = Order::query()->where('code', $param['order_no'])->first();
             $type_name = $param['order_issue_type'];
-            if (!$param['order_issue_type']) {
-                $order_issue_type_id = 0;
-                $work_order_type_id = 0;
+            if ('拦截' == $type_name) {
+                $this->createInterceptWorkOrder($param);
+            } else if ('信息更改' == $type_name) {
+                $this->createInformationChangeWorkOrder($param);
+            } else if ('快递异常' == $type_name) {
+                $this->createExpressAbnormalWorkOrder($param);
+            } else if ('错漏发' == $type_name) {
+                $this->createMistakeWorkOrder($param);
+            } else if ('破损' == $type_name) {
+                $this->createDamagedWorkOrder($param);
+            } else if ('快递丢件' == $type_name) {
+                $this->createLossWorkOrder($param);
             } else {
-                if (!array_key_exists($type_name, $types)) {
-                    $types[$type_name] = OrderIssueType::query()->where('name', $type_name)->first();
-                    $work_order_type_name = $this->work_type_relation[$type_name] ?? $type_name;
-                    $work_order_types[$type_name] = WorkOrderType::query()->firstOrCreate(
-                        ['name' => $work_order_type_name],
-                        ['prent_id' => $parent['id'], 'table_name' => 'orders', 'level' => 2]
-                    );
-                }
-                $order_issue_type_id = $types[$type_name]['id'] ?? 0;
-                $work_order_type_id = $work_order_types[$type_name]['id'] ?? 0;
-            }
-            switch ($type_name) {
-                case '拦截':
-                    $remark = "拦截订单";
-                    break;
-                case '信息更改':
-                case '其他':
-                case '快递异常':
-                case '错漏发':
-                case '破损':
-                    $remark = $param['remark'] ?? '';
-                    break;
-                default:
-                    $work_order_type_id = 0;
-                    $remark = $param['remark'] ?? '';
-                    $order_issue_type_id = 0;
-                    break;
-            }
-            $inner_params[] = [
-                'order_id' => $order['id'],
-                'creator_id' => $creator_id,
-                'work_order_type_id' => $work_order_type_id ?? 0,
-                'owner_id' => $order['owner_id'] ?? '',
-                'grad' => $param['grad'] ?? 1,
-                'remark' => $remark,
-                'outer_table_name' => 'orders',
-                'order_issue_type_id' => $order_issue_type_id ?? 0,
-                'uniquely_tag' => $order['code'] ?? null,
-                'status' => 1,
-                'created_at' => $data,
-                'updated_at' => $data,
-            ];
-        }
-        if (isset($inner_params)) {
-            WorkOrder::query()->insert($inner_params);
-            $workOrders = WorkOrder::query()->with('owner','order')->whereIn('order_id',data_get($inner_params,"*.order_id"))->where('created_at',">=",$data)->get();
-            foreach ($workOrders as $workOrder){
-                $user = Auth::user();
-                $remark = $workOrder->remark;
-                $ownerName = $workOrder->owner->name ?? '';
-                $clientCode = $workOrder->order->client_code ?? '';
-                $msg = $user["name"]."建立了新工单<br/>".$ownerName.":".$clientCode."<br/>".$remark;
-                NotificationService::SingleRegister($msg,$clientCode,"订单管理-问题件");
+                $this->createDefaultWorkOrder($param);
             }
-            return ['success' => true];
         }
-        return ['success' => false, 'message' => '参数异常'];
+        return ['success' => true];
+    }
+
+    public function createAndNotification($order, $orderIssueType, $remake): WorkOrder
+    {
+        $user = Auth::user();
+        /** @var WorkOrder $workOrder */
+        $workOrder = WorkOrder::query()->create([
+            'order_id' => $order->id,
+            'creator_id' => $user["id"],
+            'owner_id' => $order->owner_id,
+            'remark' => $remake,
+            'outer_table_name' => 'orders',
+            'order_issue_type_id' => $orderIssueType->id,
+            'uniquely_tag' => $order->code,
+            'status' => 1,
+        ]);
+        $workOrder->notification();
+        return $workOrder;
+    }
+
+    /**
+     * 拦截
+     */
+    public function createInterceptWorkOrder($param): WorkOrder
+    {
+        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '拦截']);
+        $order = Order::query()->where('code', $param['order_no'])->first();
+        $remake = '拦截订单';
+        return $this->createAndNotification($order, $orderIssueType, $remake);
+    }
+
+    /**
+     * 错漏发
+     */
+    public function createMistakeWorkOrder($param): WorkOrder
+    {
+        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '错漏发']);
+        $order = Order::query()->where('code', $param['order_no'])->first();
+        $remake = $param['remark'] ?? '';
+        return $this->createAndNotification($order, $orderIssueType, $remake);
+    }
+
+    /**
+     * 破损
+     */
+    public function createDamagedWorkOrder($param): WorkOrder
+    {
+        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '破损']);
+        $order = Order::query()->where('code', $param['order_no'])->first();
+        $remake = $param['remark'] ?? '';
+
+        $workOrderImageService = app('WorkOrderImageService');
+
+        $workOrder = $this->createAndNotification($order, $orderIssueType, $remake);
+
+        $workOrderImageService->createWorkOrderPackageImages($workOrder, $param['packageImages']);
+
+        $workOrderImageService->createWorkOrderCommodityImages($workOrder, $param['commodityImages']);
+
+        $workOrderImageService->createWorkOrderDealImages($workOrder, $param['dealImages']);
+
+        app('WorkOrderDetailService')->createWorkOrderDetail($workOrder, $param);
+
+        app('WorkOrderCommoditiesService')->createWorkOrderCommoditiesByJsonArray($workOrder, $param['commodities']); // 登记商品信息
+
+        $workOrder->update(['work_order_status' => 2]); // 标记信息已填写
+
+        return $workOrder;
+    }
+
+    /***
+     * 快递异常
+     */
+    public function createExpressAbnormalWorkOrder($param): WorkOrder
+    {
+        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '快递异常']);
+        $order = Order::query()->where('code', $param['order_no'])->first();
+        $remake = $param['remark'] ?? '';
+        return $this->createAndNotification($order, $orderIssueType, $remake);
+    }
+
+    /***
+     * 信息更改
+     */
+    public function createInformationChangeWorkOrder($param): WorkOrder
+    {
+        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '信息更改']);
+        $order = Order::query()->where('code', $param['order_no'])->first();
+        $remake = $param['remark'] ?? '';
+        return $this->createAndNotification($order, $orderIssueType, $remake);
+    }
+
+    /**
+     * 其他
+     */
+    public function createDefaultWorkOrder($param): WorkOrder
+    {
+        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '其他']);
+        $order = Order::query()->where('code', $param['order_no'])->first();
+        $remake = $param['remark'] ?? '';
+        return $this->createAndNotification($order, $orderIssueType, $remake);
+    }
+
+    /**
+     * 快递丢件
+     */
+    public function createLossWorkOrder($param): WorkOrder
+    {
+        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '快递丢件']);
+        $order = Order::query()->where('code', $param['order_no'])->first();
+        $remake = $param['remark'] ?? '';
+        $workOrder = $this->createAndNotification($order, $orderIssueType, $remake);
+        $workOrder->update(['work_order_status' => 1]); // 标记信息未填写
+        return $workOrder;
+    }
+
+    /**
+     *  填充丢件信息
+     */
+    public function fillLossWorkOrder(WorkOrder $workOrder, $param): WorkOrder
+    {
+        $workOrder->saveWorkOrderDetail($param);        // 收方信息 丢件价值 补发单号
+        $workOrder->addDealImage($param['dealImages']); // 交易截图
+        $workOrder->addRefundImage($param['refundImages'] ?? []); // 退款截图
+        $workOrder->update(['work_order_status' => 2]); // 标记信息填写
+        $workOrder->loadDefaultWith();
+        return $workOrder;
     }
 
     /**
@@ -123,10 +196,7 @@ class WorkOrderService
     public function review($wordOrder): array
     {
         $wordOrder->update(['reviewer_id' => Auth::user()['id'], 'review_at' => Carbon::now(), 'status' => '2',]);
-        $workOrders = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
-            /** @var $query Builder */
-            $query->with('packages', 'issue', 'logistic');
-        }, 'reviewer'])->whereIn('id', [$wordOrder['id']])->get();
+        $workOrders = WorkOrder::query()->defaultWith()->whereIn('id', [$wordOrder['id']])->get();
         $this->tags($workOrders);
         return ['success' => true, 'data' => $workOrders->first()];
     }
@@ -142,11 +212,7 @@ class WorkOrderService
             return $item->id;
         })->toArray();
         WorkOrder::query()->whereIn('id', $ids)->update(['review_at' => Carbon::now(), 'reviewer_id' => Auth::user()['id'], 'status' => '2']);
-        $wordOrders = WorkOrder::query()->with(['type', 'creator', 'order' => function ($query) {
-            /** @var $query Builder */
-            $query->with('packages', 'issue', 'logistic');
-        }, 'reviewer'])->whereIn('id', $ids)->get();
-        $this->tags($wordOrders);
+        $wordOrders = WorkOrder::query()->defaultWith()->whereIn('id', $ids)->get();
         return ['success' => true, 'data' => $wordOrders];
     }
 
@@ -160,13 +226,15 @@ class WorkOrderService
     {
         foreach ($work_orders as $work_order) {
             $inner_params[] = [
-                'order_id' => $work_order->order_id,
-                'order_issue_type_id' => $work_order->order_issue_type_id,
-                'result_explain' => $work_order->remark,
+                'order_id' => $work_order->order_id, 'order_issue_type_id' => $work_order->order_issue_type_id, 'result_explain' => $work_order->remark,
             ];
         }
         if (!isset($inner_params)) return ['success' => false, 'message' => '创建问题件失败'];
-        return app('OrderIssueService')->buildOrderIssue($inner_params);
+        try {
+            return app('OrderIssueService')->buildOrderIssue($inner_params);
+        } catch (\Exception $e) {
+            return ['success'=>false,'message' => '刷新页面后重试'];
+        }
     }
 
     /**
@@ -191,7 +259,7 @@ class WorkOrderService
     }
 
     /**
-     * 标记已有 问题件的工单
+     * 标记已有 问题件 的工单
      * @param $workOrders
      */
     public function tags(&$workOrders)

+ 16 - 3
app/User.php

@@ -49,7 +49,8 @@ class User extends Authenticatable
 //    function hasRole($roles){
 //        return !!$roles->intersect($this->roles()->get())->count();
 //    }
-    function isSuperAdmin(){
+    function isSuperAdmin(): bool
+    {
         $superAdmins=config("users.superAdmin");
         foreach ($superAdmins as $superAdmin){
             if($this['name']==$superAdmin){
@@ -111,7 +112,8 @@ class User extends Authenticatable
         });
         return $authorities;
     }
-    function getPermittingOwnerIdsAttribute(){
+    function getPermittingOwnerIdsAttribute(): array
+    {
         $ownerIds=[];
         if($this->isSuperAdmin()||Gate::allows('货主-可见全部')){
             $owners=Owner::query()->whereNull('deleted_at')->get();
@@ -135,7 +137,8 @@ class User extends Authenticatable
         }
         return  array_unique(array_merge($ownerIds, $old_owner));
     }
-    function getPermittingWorkgroupIds($allowAll=false){
+    function getPermittingWorkgroupIds($allowAll=false): array
+    {
         $workgroupIds=[];
         if ($this->isSuperAdmin()||$allowAll){
             $workgroups=UserWorkgroup::all();
@@ -151,6 +154,7 @@ class User extends Authenticatable
         }
         return $workgroupIds;
     }
+
     function getPermittingLaborCompanyIdsAttribute(): array
     {
         $labor_company_ids=array();
@@ -170,6 +174,15 @@ class User extends Authenticatable
         return array_unique($labor_company_ids);
     }
 
+    // 用户可见货主
+    public function getPermittingLogisticIdsAttribute(): array
+    {
+        if ($this->isSuperAdmin()){
+            return Logistic::query()->get()->map(function($logistic){return $logistic->id;})->toArray();
+        }
+        return $this->logistics()->get()->map(function($logistic){return $logistic->id;})->toArray();
+    }
+
     public function workGroups()
     {
         return $this->morphedByMany(UserWorkgroup::class, 'user_authable');

+ 196 - 17
app/WorkOrder.php

@@ -2,13 +2,18 @@
 
 namespace App;
 
+use App\Services\NotificationService;
 use App\Traits\ModelTimeFormat;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
 
 use App\Traits\ModelLogChanging;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Http\UploadedFile;
+use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Gate;
 
 class WorkOrder extends Model
@@ -19,7 +24,7 @@ class WorkOrder extends Model
 
     // 工单 信息
     protected $fillable = [
-        'status',           // 状态
+        'status',           // 审核状态
         'creator_id',       // 创建人
         'reviewer_id',      // 审核人
         'owner_id',      // 货主
@@ -31,6 +36,7 @@ class WorkOrder extends Model
         'review_at',            // 审核时间
         'order_id',             // 订单id
         'uniquely_tag',         // 唯一标识
+        'work_order_status', // 工单状态
     ];
 
     static public $enums = [
@@ -39,6 +45,13 @@ class WorkOrder extends Model
             '待审核' => 1,
             '已处理' => 2,
         ],
+        'work_order_status' => [
+            '' => 0,
+            '信息未填写' => 1,
+            '信息已填写' => 2,
+            '快递已处理' => 3,
+            '工单完成' => 4,
+        ],
         'grad' => [
             '' => 0,
             '一般' => 1,
@@ -64,7 +77,7 @@ class WorkOrder extends Model
 
     public function setStatusAttribute($value)
     {
-        if (!$value) return 0;
+        if (!$value) return ;
         if (is_numeric($value)) {
             $this->attributes['status'] = $value;
         } else {
@@ -72,6 +85,22 @@ 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 '';
@@ -80,7 +109,7 @@ class WorkOrder extends Model
 
     public function setGradAttribute($value)
     {
-        if (!$value) return 0;
+        if (!$value) return ;
         if (is_numeric($value)) {
             $this->attributes['grad'] = $value;
         } else {
@@ -109,25 +138,79 @@ class WorkOrder extends Model
     // 关联货主
     public function owner(): BelongsTo
     {
-        return $this->belongsTo(Owner::class,'owner_id');
+        return $this->belongsTo(Owner::class, 'owner_id');
     }
 
     // 工单类型
     public function type(): BelongsTo
     {
-        return $this->BelongsTo(WorkOrderType::class,'work_order_type_id');
+        return $this->BelongsTo(WorkOrderType::class, 'work_order_type_id');
     }
 
     // 生成问题件类型
-    public function issueType():BelongsTo
+    public function issueType(): BelongsTo
     {
-        return $this->belongsTo(OrderIssueType::class,'order_issue_type_id');
+        return $this->belongsTo(OrderIssueType::class, 'order_issue_type_id');
     }
 
     /** 对应问题件 */
     public function orderIssue(): BelongsTo
     {
-        return $this->belongsTo(OrderIssue::class,'order_id','order_id');
+        return $this->belongsTo(OrderIssue::class, 'order_id', 'order_id');
+    }
+
+    // 图片
+    public function image(): HasMany
+    {
+        return $this->hasMany(WorkOrderImage::class);
+    }
+
+    // 外包装图片
+    public function packageImages(): HasMany
+    {
+        return $this->hasMany(WorkOrderImage::class)->where('type', 1);
+    }
+
+    // 内物破损图片
+    public function commodityImages(): HasMany
+    {
+        return $this->hasMany(WorkOrderImage::class)->where('type', 2);
+    }
+
+    // 交易图片
+    public function dealImages(): HasMany
+    {
+        return $this->hasMany(WorkOrderImage::class)->where('type', 3);
+    }
+
+    // 退款图片
+    public function refundImages(): HasMany
+    {
+        return $this->hasMany(WorkOrderImage::class)->where('type', 4);
+    }
+
+    // 工单详情
+    public function details(): HasMany
+    {
+        return $this->hasMany(WorkOrderDetail::class);
+    }
+
+    // 工单商品信息
+    public function commodities(): HasMany
+    {
+        return $this->hasMany(WorkOrderCommodities::class);
+    }
+
+    // 宝时处理日志
+    public function processLog(): HasOne
+    {
+        return $this->hasOne(WorkOrderProcessLog::class)->where('type','1');
+    }
+
+    // 承运商处理日志
+    public function logisticLog(): HasOne
+    {
+        return $this->hasOne(WorkOrderProcessLog::class)->where('type','2');
     }
 
     public function scopeFilter($query, $filters)
@@ -139,19 +222,115 @@ class WorkOrder extends Model
     /** 默认 with 参数 */
     public function scopeDefaultWith($query)
     {
-        $query->with(['type','owner','issueType','creator','reviewer','order'=>function($query){
-            /** @var $query Builder */
-            $query->with('packages','logistic','owner');
-        },'orderIssue'=>function($query){
-            /** @var $query Builder */
-            $query->with(['issueType','logs'=>function($query){
-                if (Gate::denies('订单管理-问题件-客户不可见')){
+        $query->with(['type', 'owner', 'issueType', 'creator','details','commodities.commodity',
+            'processLog.creator',
+            'logisticLog.creator',
+            'packageImages.uploadFile',
+            'commodityImages.uploadFile',
+            'dealImages.uploadFile',
+            'refundImages.uploadFile',
+            'reviewer',
+            'order' => function ($query) {
+            /** @var Builder $query  */
+            $query->with('packages', 'logistic', 'owner');
+        }, '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');
+                } else {
+                    $query->with('user')->where('tag', '=', 0)->orderByDesc('created_at');
                 }
             }]);
         }]);
     }
 
+    public function loadDefaultWith()
+    {
+        $this->loadMissing(['owner','type', 'issueType', 'creator','details','commodities.commodity',
+            'processLog.creator',
+            'logisticLog.creator',
+            'packageImages.uploadFile',
+            'commodityImages.uploadFile',
+            'dealImages.uploadFile',
+            'refundImages.uploadFile',
+            'reviewer',
+            'order' => function ($query) {
+                /** @var Builder $query  */
+                $query->with('packages', 'logistic', 'owner');
+            }, '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');
+                    }
+                }]);
+            }]);
+    }
+
+    public function notification()
+    {
+        $user = Auth::user();
+        $this->loadMissing('owner', 'order');
+        $remark = $this->remark;
+        $ownerName = $this->owner->name ?? '';
+        $clientCode = $this->order->client_code ?? '';
+        $msg = $user["name"] . "建立了新工单<br/>" . $ownerName . ":" . $clientCode . "<br/>" . $remark;
+        NotificationService::SingleRegister($msg, $clientCode, "订单管理-问题件");
+    }
+
+    public function addPackageImage($images)
+    {       // 外包装图
+        foreach ($images as $image) {
+            /** @var UploadedFile  $image */
+            $count = $this->packageImages()->count();
+            /** @var WorkOrderImage $workOrderImage */
+            $workOrderImage = $this->packageImages()->create(['type' => 0, 'amount' => ++$count]);
+            $workOrderImage->saveFile($image);
+        }
+        $this->loadMissing('packageImages');
+    }
+
+    public function addCommodityImage($images)
+    {       // 内物破损图
+        foreach ($images as $image) {
+            $count = $this->commodityImages()->count();
+            /** @var WorkOrderImage $workOrderImage */
+            $workOrderImage = $this->commodityImages()->create(['type' => 1, 'amount' => ++$count]);
+            $workOrderImage->saveFile($image);
+        }
+        $this->loadMissing('commodityImages');
+    }
+
+    public function addDealImage($images)
+    {       // 交易截图
+        foreach ($images as $image) {
+            $count = $this->dealImages()->count();
+            /** @var WorkOrderImage $workOrderImage */
+            $workOrderImage = $this->dealImages()->create(['type' => 2, 'amount' => ++$count]);
+            $workOrderImage->saveFile($image);
+        }
+        $this->loadMissing('dealImages');
+    }
+
+    public function addRefundImage($images)
+    {        // 退款截图
+        foreach ($images as $image) {
+            $count = $this->refundImages()->count();
+            /** @var WorkOrderImage $workOrderImage */
+            $workOrderImage = $this->refundImages()->create(['type' => 3, 'amount' => ++$count]);
+            $workOrderImage->saveFile($image);
+        }
+        $this->loadMissing('dealImages');
+    }
+
+    public function saveWorkOrderDetail($params)
+    {
+        $param  = (new WorkOrderDetail($params))->getAttributes();
+        $this->details()->create($param);
+        $this->loadMissing('details');
+    }
+
 }

+ 33 - 0
app/WorkOrderCommodities.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class WorkOrderCommodities extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    //
+    protected $fillable = [
+        'work_order_id',
+        'commodity_id',
+        'sku',
+        'amount',
+    ];
+
+    public function workOrder(): BelongsTo
+    {
+        return $this->belongsTo(WorkOrder::class);
+    }
+
+    public function commodity(): BelongsTo
+    {
+        return $this->belongsTo(Commodity::class);
+    }
+}

+ 31 - 0
app/WorkOrderDetail.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class WorkOrderDetail extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    protected $fillable = [
+        'work_order_id',
+        'price',  // 商品价值
+        'sku_amount', // 破损sku数
+        'receive_address', // 收方信息
+        'reissue_logistic_number', // 补发单号
+        'return_logistic_number',   // 退回单号
+        'logistic_number',
+    ];
+
+    public function workOrder(): BelongsTo
+    {
+        return $this->belongsTo(WorkOrder::class);
+    }
+
+}

+ 132 - 0
app/WorkOrderImage.php

@@ -0,0 +1,132 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+use Illuminate\Http\UploadedFile;
+use Intervention\Image\Facades\Image;
+use Ramsey\Uuid\Uuid;
+
+class WorkOrderImage extends Model
+{
+    use ModelLogChanging;
+
+    protected $fillable = [
+        'work_order_id',
+        'type',
+        'number',
+    ];
+
+    static public $enums = [
+        'type' => [
+            '' => 0,
+            '外包装图片' => 1,
+            '内物破碎图片' => 2,
+            '交易截图' => 3,
+            '退款成功截图' => 4,
+        ],
+    ];
+
+    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['type'][$value];
+    }
+
+    public function setTypeAttribute($value)
+    {
+        if (!$value) return ;
+        if (is_numeric($value)) {
+            $this->attributes['type'] = $value;
+        } else {
+            $this->attributes['type'] = self::$enums['type'][$value];
+        }
+    }
+
+    public function workOrder(): BelongsTo
+    {
+        return $this->belongsTo(WorkOrder::class);
+    }
+
+    public function uploadFile(): HasOne
+    {
+        return $this->hasOne(UploadFile::class,'table_id','id')->where('table_name',$this->getTable());
+    }
+
+    public function saveFile(UploadedFile $image): bool
+    {
+        if (!$this->checkFile($image)) return false;
+        $tmpFile = $image->getRealPath();
+        $fileSuffix = $image->getClientOriginalExtension();
+        $dirPath = $this->getStorageDirPath();
+        $fileName = date('ymd') . '-' . Uuid::uuid1();
+        $pathName = $dirPath . $fileName .'.' . $fileSuffix;
+        $result = move_uploaded_file($tmpFile, $pathName);
+        if(!$result) return false;
+        $this->uploadFile()->create(
+            [ 'url' => '/files/workOrder/'.$fileName, 'type' => $fileSuffix,'table_name'=>$this->getTable()]
+        );
+        return true;
+    }
+
+    public function checkFile($image): bool
+    {
+        $tmpFile = $image->getRealPath();
+        $fileSuffix = $image->getClientOriginalExtension();
+
+        if (!is_uploaded_file($tmpFile)) return false;
+        if ($image->getSize() > 5 * 1024 * 1024) return false;
+        if (!in_array($fileSuffix,[ 'gif','image','jpeg','jpg','png','svg'])) return false;
+        return true;
+    }
+
+    public function getStorageDirPath(): string
+    {
+        $path = ['app','public','files','workOrder'];
+        $path = join(DIRECTORY_SEPARATOR,$path);
+        $dirPath = storage_path($path);
+        if (!file_exists($dirPath)) {
+            mkdir($dirPath);
+        }
+        return $dirPath.DIRECTORY_SEPARATOR;
+    }
+
+    public function updateFile($image)
+    {
+        $this->deleteStorageFile();
+        $this->uploadFile()->delete();
+        $this->saveFile($image);
+    }
+
+    public function deleteStorageFile()
+    {
+        $path = $this->getPathName();
+        if (!$path) return;
+        if (file_exists($path)){
+            unlink($path);
+        }
+    }
+
+    public function getPathName(): ?string
+    {
+        if (!$this->uploadFile) return null;
+        $names = [];
+        preg_match("/([\w]+)$/", $this->uploadFile->url,$names);
+        $path = ['app','public','files','workOrder' , $names[0],".{$this->uploadFile->type}"];
+        $path = join(DIRECTORY_SEPARATOR,$path);
+        return storage_path($path);
+    }
+
+}

+ 118 - 0
app/WorkOrderProcessLog.php

@@ -0,0 +1,118 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class WorkOrderProcessLog extends Model
+{
+    use ModelLogChanging;
+
+    //
+    protected $fillable = [
+        'work_order_id',  // 工单
+        'type',           // 处理类型 0 无 1宝时 2 承运商
+        'is_indemnity',   // 是否赔偿 0 无 1是 2否
+        'indemnitor',   // 赔偿人 0 无 1宝时 2承运商
+        'indemnity',      // 赔偿金
+        'creator_id',     // 创建人
+        'remark',         // 描述
+    ];
+
+    static public $enums = [
+        'type' => [
+            '' => 0,
+            '宝时' => 1,
+            '承运商' => 2,
+        ],
+        'is_indemnity' => [
+            '' => 0,
+            '是' => 1,
+            '否' => 2,
+        ],
+        'indemnitor'=> [
+            '' => 0,
+            '宝时' => 1,
+            '承运商' => 2,
+        ],
+    ];
+
+    function __construct(array $attributes = [])
+    {
+        foreach (self::$enums as &$enum) {
+            $enum = $enum + array_flip($enum);
+        }
+        parent::__construct($attributes);
+    }
+
+    public function getTypeAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['type'][$value];
+    }
+
+    public function setTypeAttribute($value)
+    {
+        if (!$value) return ;
+        if (is_numeric($value)) {
+            $this->attributes['type'] = $value;
+        } else {
+            $this->attributes['type'] = self::$enums['type'][$value];
+        }
+    }
+
+    public function getIsIndemnityAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['is_indemnity'][$value];
+    }
+
+    public function setIsIndemnityAttribute($value)
+    {
+        if (!$value) return ;
+        if (is_numeric($value)) {
+            $this->attributes['is_indemnity'] = $value;
+        } else {
+            $this->attributes['is_indemnity'] = self::$enums['is_indemnity'][$value];
+        }
+    }
+
+    public function getIndemnitorAttribute($value)
+    {
+        if (!$value) return '';
+        return self::$enums['indemnitor'][$value];
+    }
+
+    public function setIndemnitorAttribute($value)
+    {
+        if (!$value) return ;
+        if (is_numeric($value)) {
+            $this->attributes['indemnitor'] = $value;
+        } else {
+            $this->attributes['indemnitor'] = self::$enums['indemnitor'][$value];
+        }
+    }
+
+    public function workOrder(): BelongsTo
+    {
+        return $this->belongsTo(WorkOrder::class);
+    }
+
+    public function creator(): BelongsTo
+    {
+        return $this->belongsTo(User::class);
+    }
+
+    public function isLogisticLog(): bool
+    {
+        return $this->type == "承运商";
+    }
+
+    public function isBaoShiLog(): bool
+    {
+        return $this->type == "宝时";
+    }
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 214 - 147
composer.lock


+ 15 - 0
config/api.php

@@ -59,6 +59,21 @@ return [
         ],
     ],
 
+    "syrius" => [
+        "client_id"     => "1dg6clndocrtiugsl4bj83kpk6",
+        "client_secret" => "vthuec06c1jrjr31nt98l8r7kune0uqdgrjeifm0472re923c15",
+        "base_url"      => "",
+        "request"       => [
+            "bin_location"  => "/account/binlocation/",         //POST
+            "find_all_bin_location" => " /account/binlocation/",//GET
+            "delete_bin_location" => " /account/binlocation/",  //DELETE
+            "find_storage_type" =>  "/account/basicdata-type/storage/type/{storageTypeId}", //GET
+            "create_order"  => "/order/warehouse-order/", //POST
+            "find_order"    => "/order/warehouse-order/{id}",//GET
+            "notifications" => "{order-notification-url}"   //POST
+        ],
+    ],
+
     /** goodScan
     https://was.baoshi56.com/api/thirdPart/goodscan/weight/new  //新增包裹
      */

+ 1 - 1
config/sync.php

@@ -43,7 +43,7 @@ return [
         'interval' => 1,   // 时间以分为单位
         'start_at'=> '',    // 开始同步WMS的时间  时间格式: yyyy-MM-dd HH:mm:ss 如 2020-09-05 13:15:16
         'cache_prefix' => [
-            'restart' => 10,  // 重新启动时间 已分钟为单位
+            'restart' => 40,  // 重新启动时间 已分钟为单位
             'last_start_at' => 'last_order_sync_task_start_at' ,
             'last_end_at' => 'last_order_sync_task_end_at' ,
             'last_err_at' => 'last_order_sync_task_error_at' ,

+ 12 - 0
database/factories/WorkOrderCommoditiesFactory.php

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

+ 18 - 0
database/factories/WorkOrderDetailFactory.php

@@ -0,0 +1,18 @@
+<?php
+
+
+use App\WorkOrderDetail;
+use Faker\Generator as Faker;
+use Illuminate\Database\Eloquent\Factory;
+
+/** @var Factory $factory */
+$factory->define(WorkOrderDetail::class, function (Faker $faker) {
+    return [
+        'work_order_id' => $faker->randomNumber(0,200),
+        'price' => $faker->randomFloat(null,0.1,999),
+        'skus' => $faker->text(20),
+        'receive_address' => $faker->address,
+        'reissue_logistic_number' => $faker->numberBetween(10000000,999999999),
+        'return_logistic_number' => $faker->numberBetween(10000000,999999999),
+    ];
+});

+ 12 - 0
database/factories/WorkOrderImageFactory.php

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

+ 12 - 0
database/factories/WorkOrderProcessLogFactory.php

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

+ 38 - 0
database/migrations/2021_09_22_135941_create_work_order_details_table.php

@@ -0,0 +1,38 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateWorkOrderDetailsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('work_order_details', function (Blueprint $table) {
+            $table->id();
+            $table->integer('work_order_id')->index()->comment('工单');
+            $table->tinyInteger('sku_amount')->comment('破损sku数量');
+            $table->decimal('price',11,3)->comment('价格');
+            $table->string('receive_address')->comment('收方信息');
+            $table->string('reissue_logistic_number')->comment('补发单号');
+            $table->string('return_logistic_number')->comment('退回单号');
+            $table->string('logistic_number')->comment('快递单号');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('work_order_details');
+    }
+}

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

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateWorkOrderCommoditiesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('work_order_commodities', function (Blueprint $table) {
+            $table->id();
+            $table->integer('work_order_id')->index()->comment('工单');
+            $table->integer('commodity_id')->comment('商品id');
+            $table->string('sku')->comment('商品sku');
+            $table->integer('amount')->comment('数量');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('work_order_commodities');
+    }
+}

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

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateWorkOrderImagesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('work_order_images', function (Blueprint $table) {
+            $table->id();
+            $table->integer('work_order_id')->index()->comment('工单');
+            $table->tinyInteger('type')->comment('类别');
+            $table->tinyInteger('number')->comment('序号');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('work_order_images');
+    }
+}

+ 38 - 0
database/migrations/2021_09_24_110630_create_work_order_process_logs_table.php

@@ -0,0 +1,38 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateWorkOrderProcessLogsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('work_order_process_logs', function (Blueprint $table) {
+            $table->id();
+            $table->integer('work_order_id')->index()->comment('工单');
+            $table->tinyInteger('type')->index()->comment('类型 0无 1宝时 2承运商');
+            $table->tinyInteger('indemnitor')->index()->comment('赔偿方 0无 1宝时 2承运商');
+            $table->tinyInteger('is_indemnity')->comment('是否赔偿 0无 1是 2否');
+            $table->decimal('indemnity',11,3)->comment('赔偿金额');
+            $table->integer('creator_id')->comment('创建人');
+            $table->string('remark')->nullable()->comment('理由');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('work_order_process_logs');
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddCloumnToWorkkOrders extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->tinyInteger('work_order_status')->comment('工单状态');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('work_orders', function (Blueprint $table) {
+            $table->dropColumn('work_order_status');
+        });
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class DropCurrentTimestampToLaborCompanyDispatchesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('labor_company_dispatches', function (Blueprint $table) {
+            $table->dateTime('dispatch_date')->nullable()->change();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('labor_company_dispatches', function (Blueprint $table) {
+            $table->timestamp('dispatch_date')->change();
+        });
+    }
+}

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

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddColumnStatusToLaborCompanyDispatchesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('labor_company_dispatches', function (Blueprint $table) {
+            $table->integer('status')->default(0)->comment('状态');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('labor_company_dispatches', function (Blueprint $table) {
+            $table->dropColumn('status');
+        });
+    }
+}

+ 16 - 0
database/seeds/WorkOrderCommoditiesSeeder.php

@@ -0,0 +1,16 @@
+<?php
+
+use Illuminate\Database\Seeder;
+
+class WorkOrderCommoditiesSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        //
+    }
+}

+ 17 - 0
database/seeds/WorkOrderDetailSeeder.php

@@ -0,0 +1,17 @@
+<?php
+
+use Illuminate\Database\Seeder;
+
+class WorkOrderDetailSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        $params = factory(\App\WorkOrder::class)->times(30)->make();
+        \App\WorkOrder::query()->insert($params);
+    }
+}

+ 16 - 0
database/seeds/WorkOrderImageSeeder.php

@@ -0,0 +1,16 @@
+<?php
+
+use Illuminate\Database\Seeder;
+
+class WorkOrderImageSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        //
+    }
+}

+ 16 - 0
database/seeds/WorkOrderProcessLogSeeder.php

@@ -0,0 +1,16 @@
+<?php
+
+use Illuminate\Database\Seeder;
+
+class WorkOrderProcessLogSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        //
+    }
+}

+ 6 - 4
resources/views/finance/instantBill.blade.php

@@ -54,8 +54,8 @@
                     </td>
                     <td :rowspan="bill.rowspan"><span>@{{ bill.shopName }}</span></td>
                     <td :rowspan="bill.rowspan"><span>@{{ bill.operationBill }}</span></td>
-                    <td :rowspan="bill.rowspan"><span>@{{ bill.consigneeName }}</span></td>
-                    <td :rowspan="bill.rowspan"><span>@{{ bill.consigneePhone }}</span></td>
+                    <td :rowspan="bill.rowspan"><span v-if="bill.is_encryption" class="text-danger">*加密*</span><span v-else>@{{ bill.consigneeName }}</span></td>
+                    <td :rowspan="bill.rowspan"><span v-if="bill.is_encryption" class="text-danger">*加密*</span><span v-else>@{{ bill.consigneePhone }}</span></td>
                     <td><span>@{{ bill.commodityAmount }}</span></td>
                     <td :rowspan="bill.rowspan"><span>@{{ bill.province }}</span></td>
                     <td>
@@ -102,7 +102,7 @@
                         type : "{{$detail->type}}",
                         shopName : "{{$detail->shop ? $detail->shop->name : ''}}",
                         operationBill : "{{$detail->operation_bill}}",
-                        consigneeName : "{{$detail->consignee_name}}",
+                        consigneeName : ("{{$detail->consignee_name}}" && "{{$detail->consignee_name}}".length>50 && ("{{$detail->consignee_name}}".substring(0,3)==='~Ag' || "{{$detail->consignee_name}}".substring(0,1)==='#')) ? "加密" : "{{$detail->consignee_name}}",
                         consigneePhone : "{{$detail->consignee_phone}}",
                         commodityAmount : "{{$detail->commodity_amount}}",
                         logisticBill : "{{$detail->logistic_bill}}",
@@ -116,7 +116,9 @@
                         createdAt : "{{$detail->created_at}}",
                         total : "{{$detail->work_fee + $detail->logistic_fee}}",
                         items:{!! $detail->items !!},
-                        rowspan:Number("{{count($detail->items)}}")+1
+                        rowspan:Number("{{count($detail->items)}}")+1,
+                        is_encryption : !!("{{$detail->consignee_phone}}".length>50 && ("{{$detail->consignee_phone}}".substring(0,3)==='~Ag' || "{{$detail->consignee_phone}}".substring(0,1)==='#'
+                            || "{{$detail->consignee_phone}}".substring(0,1)==='$')),
                     },
                     @endforeach
                 ],

+ 13 - 3
resources/views/finance/settlementBills/totalFee/index.blade.php

@@ -56,7 +56,10 @@
                 </tr>
              <template v-if="feeTotal['information']??false">
                  <tr>
-                     <td>仓储费</td>
+                     <td>
+                         <a target="_blank"
+                            href="{{ route('settlementBills.storageFee.index',['owner_id' => $request['owner_id'],'year' => $request['year'],'month' => $request['month']]) }}">仓储费</a>
+                     </td>
                      <td class="m-0 p-0">
                          <table class="table  m-0 p-0">
                              <tr v-for="item in feeTotal['information']['storageFee']">
@@ -96,7 +99,10 @@
                      </td>
                  </tr>
                  <tr>
-                     <td>入库费</td>
+                     <td>
+                         <a target="_blank"
+                            href="{{ route('settlementBills.storeFee.report',['owner_id' => $request['owner_id'],'year' => $request['year'],'month' => $request['month']]) }}">入库费</a>
+                     </td>
                      <td class="m-0 p-0">
                          <table class="table  m-0 p-0">
                              <tr v-for="item in feeTotal['information']['storeFee']">
@@ -139,7 +145,11 @@
                      </td>
                  </tr>
                  <tr>
-                     <td>出库费</td>
+                     <td>
+                         <a target="_blank"
+                            href="{{ route('settlementBills.storeOutFee.report',['owner_id' => $request['owner_id'],'year' => $request['year'],'month' => $request['month']]) }}">出库费</a>
+
+                     </td>
                      <td class="m-0 p-0">
                          <table class="table   m-0 p-0">
                              <tr v-for="item in feeTotal['information']['storeOutFee']">

+ 9 - 6
resources/views/layouts/app.blade.php

@@ -125,12 +125,10 @@
         switch (type) {
             case 2:
                 a.innerText = menu.name;
-                li.appendChild(a);
-                return li;
+                break;
             case 3:
                 a.innerText = menu.name;
-                li.appendChild(a);
-                return li;
+                break;
             default:
                 if (menu.font){
                     let span = document.createElement("span");
@@ -139,9 +137,14 @@
                     a.appendChild(span);
                 }
                 a.appendChild(document.createTextNode(menu.name));
-                li.appendChild(a);
-                return li;
+                break;
         }
+        li.appendChild(a);
+        a.onclick = function (){
+
+            return false;
+        };
+        return li;
     }
     function getMenu() {
         let xhr = new XMLHttpRequest();

+ 159 - 18
resources/views/order/index/_work_order_modal.blade.php

@@ -1,44 +1,185 @@
-<div class="modal fade " id="intercept-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel" aria-hidden="true">
-    <div class="modal-dialog modal-dialog-centered">
+<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-content">
             <div class="modal-header">
-                <h5 class="modal-title" id="checkModalLabel" >创建工单</h5>
+                <h5 class="modal-title" id="checkModalLabel">创建工单</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="form-group">
-                    <label for="order_issue_type">工单类型</label>
-                    <div class="pl-1">
-                        <select name="type" id="order_issue_type" class="form-control" v-model="workOrder.orderIssueType">
+                <div class="form-group row">
+                    <label for="order_issue_type" class="col-sm-2 col-form-label text-right">工单类型</label>
+                    <div class="col-sm-10">
+                        <select name="type" id="order_issue_type" class="form-control"
+                                v-model="workOrder.orderIssueType">
                             <option value=""></option>
                             <option v-for="type in workOrder.types" :value="type">@{{ type }}</option>
                         </select>
                     </div>
                 </div>
                 {{--其他--}}
-                <template v-if="['其他',null,'快递异常','错漏发','破损'].includes(workOrder.orderIssueType)">
+                <div class="form-group row" v-if="['其他',null,'快递异常','错漏发','破损','快递丢件'].includes(workOrder.orderIssueType)">
                     <hr>
-                    <label for="remake_info">问题描述</label>
-                    <div class="pl-1">
-                        <textarea class="form-control" name="" id="remake_info" cols="30" rows="5" v-model="workOrder.remark.info"></textarea>
+                    <label for="remake_info" class="col-sm-2 col-form-label text-right">问题描述</label>
+                    <div class="col-sm-10">
+                        <textarea class="form-control" name="" id="remake_info" cols="30" rows="2"
+                                  v-model="workOrder.remark.info"></textarea>
                     </div>
-                </template>
+                </div>
+
+                {{--破损商品价格--}}
+                <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>
+                    <div class="col-sm-10">
+                        <input type="number" id="work-order-price" class="form-control" v-model="workOrder.price"
+                               placeholder="破损商品价格">
+                    </div>
+                </div>
+                {{--快递单号--}}
+                <div class="form-group row" v-if="'破损' === workOrder.orderIssueType">
+                    <label for="work-order-logistic-number"
+                           class="col-sm-2 col-form-label text-right text-primary">快递单号</label>
+                    <div class="col-sm-10">
+                        <input type="text" id="work-order-logistic-number" class="form-control"
+                               v-model="workOrder['logistic_number']" placeholder="快递单号">
+                    </div>
+                </div>
+
+
                 {{--信息更改--}}
-                <template v-else-if="workOrder.orderIssueType === '信息更改'">
+                <div class="form-group row" v-if="'信息更改' === workOrder.orderIssueType ">
                     <hr>
-                    <label for="remake_info">新的收方信息</label>
-                    <div class="pl-1">
-                        <textarea class="form-control" name="" id="remake_info" cols="30" rows="5" v-model="workOrder.remark.info"></textarea>
+                    <label for="order_issue_type" class="col-sm-2 col-form-label">新的收方信息</label>
+                    <div class="col-sm-10">
+                        <textarea class="form-control" name="" id="remake_info" cols="30" rows="5"
+                                  v-model="workOrder.remark.info"></textarea>
+                    </div>
+                </div>
+
+                <hr v-if="'破损' === workOrder.orderIssueType">
+                <div class="form-group " v-if="'破损' === workOrder.orderIssueType">
+                    <div class="pl-1 custom-file col-10 offset-2">
+                        <input type="file" id="package-images" name="package-images" multiple class="custom-file-input"
+                               accept="image/*" @change="pushImagesAndShow($event,workOrder.packageImages)">
+                        <label class="custom-file-label" for="package-images">点击添加外包装破损图片</label>
+                    </div>
+                    <div class="border-dark mt-1 col-10 offset-2">
+                        <div v-for="(image,i) in  workOrder.packageImages"
+                             class="d-inline-block col-4 position-relative card">
+                            <div class="card-body">
+                                <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                <div class="float-right position-relative">
+                                    <button type="button" class="btn btn-sm btn-outline-danger"
+                                            @click="spliceImage(i,workOrder.packageImages)">取消
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <hr v-if="'破损' === workOrder.orderIssueType">
+                <div class="form-group " v-if="'破损' === workOrder.orderIssueType">
+                    <div class="pl-1 custom-file col-10 offset-2">
+                        <input type="file" id="commodity-images" name="package-images" multiple
+                               class="custom-file-input" accept="image/*"
+                               @change="pushImagesAndShow($event,workOrder.commodityImages)">
+                        <label class="custom-file-label" for="commodity-images">点击添加内物破损图片</label>
+                    </div>
+                    <div class="border-dark mt-1 col-10 offset-2">
+                        <div v-for="(image,i) in  workOrder.commodityImages"
+                             class="d-inline-block col-4 position-relative card">
+                            <div class="card-body">
+                                <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                <div class="float-right position-relative">
+                                    <button type="button" class="btn btn-sm btn-outline-danger"
+                                            @click="spliceImage(i,workOrder.commodityImages)">取消
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
                     </div>
-                </template>
+                </div>
+
+                <hr v-if="'破损' === workOrder.orderIssueType">
+                <div class="form-group " v-if="'破损' === workOrder.orderIssueType">
+                    <div class="pl-1 custom-file col-10 offset-2">
+                        <input type="file" id="deal-images" name="package-images" multiple class="custom-file-input"
+                               accept="image/*" @change="pushImagesAndShow($event,workOrder.dealImages)">
+                        <label class="custom-file-label" for="deal-images">点击添加外交易截图</label>
+                    </div>
+                    <div class="border-dark mt-1 col-10 offset-2">
+                        <div v-for="(image,i) in  workOrder.dealImages"
+                             class="d-inline-block col-4 position-relative card">
+                            <div class="card-body">
+                                <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                <div class="float-right position-relative">
+                                    <button type="button" class="btn btn-sm btn-outline-danger"
+                                            @click="spliceImage(i,workOrder.dealImages)">取消
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="form-group row" v-if="'破损' === workOrder.orderIssueType">
+                    <label for="work-order-sku-amount"
+                           class="col-sm-2 col-form-label text-right text-primary">破损sku编号数量</label>
+                    <div class="col-sm-10">
+                        <input type="number" id="work-order-sku-amount" class="form-control"
+                               v-model="workOrder['sku_amount']" placeholder="破损sku编号数量">
+                    </div>
+                </div>
+                <hr v-if="'破损' === workOrder.orderIssueType">
+                <div class="form-group row" v-if="'破损' === workOrder.orderIssueType">
+                    <label for="work-order-sku-amount"
+                           class="col-sm-2 col-form-label text-right text-primary">破损sku信息</label>
+                    <div class="col-sm-10">
+                        <table class="table table-sm table-active table-grid-row">
+                            <tr class="text-center">
+                                <th>sku</th>
+                                <th>商品名称</th>
+                                <th>数量</th>
+                                <th>操作</th>
+                            </tr>
+                            <tr v-for="(item,i) in workOrder.commodities" :key="i" class="text-center">
+                                <td>@{{ item.sku }}</td>
+                                <td>@{{ item.commodity.name }}</td>
+                                <td>@{{ item.amount }}</td>
+                                <td>
+                                    <button type="button" class="btn btn-sm btn-danger"
+                                            @click="workOrder.commodities.splice(i,1)">取消
+                                    </button>
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+                <div class="form-group row" v-if="'破损' === workOrder.orderIssueType">
+                    <label for="work-order-sku-amount" class="col-sm-2 col-form-label text-right "> 添加</label>
+                    <div class="col-sm-10  col-sm-offset-2 form-group form-inline">
+                        <div class="col-4">
+                            <input type="text" class="form-control" placeholder="sku编号" name="sku" id="commodity-sku" ref="commodity-sku">
+                         </div>
+                        <div class="col-4">
+                            <input type="number" class="form-control form-control-static" placeholder="数量" name="amount" ref="commodity-amount"
+                               id="commodity-amount">
+                        </div>
+                        <div class="col-4">
+                            <button type="button" class="btn btn-sm btn-outline-success col-4" @click="addCommodity">添加</button>
+                        </div>
+                    </div>
+                </div>
             </div>
+            <hr v-if="'破损' === workOrder.orderIssueType">
             <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>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 489 - 302
resources/views/order/index/delivering.blade.php


+ 44 - 39
resources/views/order/issue/index.blade.php

@@ -83,10 +83,10 @@
                     <tr class="tr-yellow align-center">
                         <th class=" font-weight-bolder header-1"></th>
                         <th class="td-yellow  font-weight-bolder original-class table-head-warning  header-2 text-center"
-                            colspan="9">
+                            colspan="8">
                             原始运单
                         </th>
-                        <th class="font-weight-bolder header-3 text-center" colspan="14">
+                        <th class="font-weight-bolder header-3 text-center" colspan="15">
                             情况说明
                         </th>
                         @cannot('订单管理-问题件-客户不可见')
@@ -136,9 +136,7 @@
                         <th class="tow-layer align-middle td-yellow" rowspan="2"
                             style="max-width: 150px;min-width: 150px;">原始运单号
                         </th>
-                        <th class="tow-layer align-middle td-yellow" rowspan="2"
-                            style="max-width: 500px;min-width: 400px;">快递路由
-                        </th>
+
                         {{--原始商品明细 开始--}}
                         <th class="tow-layer align-middle td-yellow" v-show="isShowOrderInfo" rowspan="2"
                             style="min-width: 200px">收货人名称
@@ -178,12 +176,17 @@
                             style="min-width: 450px">返回商品明细
                         </th>
                         <th class="three-layer bg-whit  align-middle" rowspan="2" style="min-width: 180px">情况说明</th>
-                        <th class="three-layer   align-middle" rowspan="2" style="min-width: 115px">问题类别</th>
-                        <th class="three-layer  align-middle" colspan="4" style="min-width: 155px">处理结果</th>
+                        <th class="three-layer align-middle" rowspan="2" style="min-width: 115px">问题类别</th>
+                        <th class="three-layer align-middle" colspan="4" style="min-width: 155px">处理结果</th>
+
+                        <th class="three-layer align-middle " rowspan="2"
+                            style="max-width: 500px;min-width: 400px;">快递路由
+                        </th>
                         @cannot('订单管理-问题件-客户不可见')
                             <th class="three-layer  align-middle" rowspan="2"
                                 style="width:50px">@{{ isShowSecondOrderInfo ? '隐藏':'展开' }}
                             </th>
+
                             <th class="three-layer align-middle" rowspan="2"
                                 style="min-width: 120px;"
                                 v-show="isShowSecondOrderInfo">二次客户订单号
@@ -201,6 +204,7 @@
                                 v-show="isShowSecondOrderInfo">二次商品明细
                             </th>
                         @endcannot
+
                         {{--原始商品明细 结束--}}
                         @cannot('订单管理-问题件-客户自定义订单号')
                             <th class="three-layer  align-middle" rowspan="2" style="min-width: 120px">自定义订单号</th>
@@ -418,33 +422,6 @@
                                 </button>
                             </template>
                         </td>
-                        <td>
-                            <div class="alert alert-light " v-for="(item,i) in orderIssue.order.packages">
-                                <div class="text-left">
-                                    <span v-text="item.logistic_number"></span>
-                                    <span class="float-right" v-if="item['transfer_status'].length === 0">暂无路由信息</span>
-                                    <button type="button" class="btn btn-sm btn-outline-primary float-right" v-if="item['transfer_status'].length > 0 && selectOrderPackage!==item.id" @click="selectOrderPackage = item.id">展开</button>
-                                    <button type="button" class="btn btn-sm btn-outline-primary float-right" v-if="selectOrderPackage === item.id" @click="selectOrderPackage = null">收起</button>
-                                </div>
-                                <div class="text-left" v-if="selectOrderPackage === item.id">
-                                    <div v-for="transfer in item['transfer_status']">
-                                        <div >
-                                            <hr>
-                                            <span class="mr-1 text-monospace">时间:</span>
-                                            <span v-text="transfer['accept_time']"></span>
-                                        </div>
-                                        <div>
-                                            <span class="mr-1 text-monospace">到达地:</span>
-                                            <span v-text="transfer['accept_address']"></span>
-                                        </div>
-                                        <div>
-                                            <span class="mr-1 text-monospace">详情:</span>
-                                            <span v-text="transfer['remark']"></span>
-                                        </div>
-                                    </div>
-                                </div>
-                            </div>
-                        </td>
 
                         {{--商品明细 开始--}}
                         <td class="td-yellow child-layer-2-hide text-wrap text-letter"
@@ -730,7 +707,34 @@
                         {{--情况说明 结束--}}
 
                         {{--客户编辑 开启--}}
-                        @cannot('订单管理-问题件-客户不可见')
+                        <td>
+                            <div class="alert alert-light " v-for="(item,i) in orderIssue.order.packages">
+                                <div class="text-left">
+                                    <span v-text="item.logistic_number"></span>
+                                    <span class="float-right" v-if="item['transfer_status'].length === 0">暂无路由信息</span>
+                                    <button type="button" class="btn btn-sm btn-outline-primary float-right" v-if="item['transfer_status'].length > 0 && selectOrderPackage!==item.id" @click="selectOrderPackage = item.id">展开</button>
+                                    <button type="button" class="btn btn-sm btn-outline-primary float-right" v-if="selectOrderPackage === item.id" @click="selectOrderPackage = null">收起</button>
+                                </div>
+                                <div class="text-left" v-if="selectOrderPackage === item.id">
+                                    <div v-for="transfer in item['transfer_status']">
+                                        <div >
+                                            <hr>
+                                            <span class="mr-1 text-monospace">时间:</span>
+                                            <span v-text="transfer['accept_time']"></span>
+                                        </div>
+                                        <div>
+                                            <span class="mr-1 text-monospace">到达地:</span>
+                                            <span v-text="transfer['accept_address']"></span>
+                                        </div>
+                                        <div>
+                                            <span class="mr-1 text-monospace">详情:</span>
+                                            <span v-text="transfer['remark']"></span>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </td>
+                    @cannot('订单管理-问题件-客户不可见')
                             <td class="p-0 m-0 child-layer-3" style="min-width:50px;"
                                 v-if="index===0"
                                 :rowspan="orderIssues.length">
@@ -740,6 +744,7 @@
                                       @click="toggleSeCondeOrder"
                                       v-text="isShowSecondOrderInfo ? '隐藏运单列' : '展开运单列'"></span>
                             </td>
+
                             <td class="child-layer-3-hide" v-show="isShowSecondOrderInfo">
                                 @can('订单管理-问题件-编辑')
                                     <input class="form-control form-control-sm"
@@ -837,8 +842,8 @@
                                             v-if="orderIssue.second_order.amounts > 0"
                                             :id="'secondOrderBtn'+orderIssue.id"
                                             :data-target="'#secondOrder'+orderIssue.id"
-                                            @click="toggleSecond(orderIssue.id,orderIssue.secondeOrderItems)">
-                                           商品@{{ orderIssue.second_order.amounts }}件,点击展开
+                                            @click="toggleSecond(orderIssue.id,orderIssue.secondeOrderItems)"
+                                            v-text="'商品' + orderIssue.second_order.amounts + '件,点击展开' ">
                                     </button>
                                 </template>
                             </td>
@@ -1490,7 +1495,7 @@
                 },
                 isShowOrderInfo(newValue) {
                     setTimeout(function () {
-                        $('.header-2').attr('colspan', 9 + (newValue ? 9 : 0));
+                        $('.header-2').attr('colspan', 8 + (newValue ? 9 : 0));
                     }, 2);
                 },
                 isShowRejectedBill(newValue) {
@@ -1502,7 +1507,7 @@
                 isShowSecondOrderInfo(newValue) {
                     let _this = this;
                     setTimeout(function () {
-                        $('.header-3').attr('colspan', 14 + (newValue ? 6 : 0) + (_this.isShowRejectedBill ? 6 : 0));
+                        $('.header-3').attr('colspan', 15 + (newValue ? 6 : 0) + (_this.isShowRejectedBill ? 6 : 0));
                     }, 2);
                 },
             },

+ 77 - 0
resources/views/order/workOrder/_edit_process_log.blade.php

@@ -0,0 +1,77 @@
+<div class="modal fade " id="work-order-process-log-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
+     aria-hidden="true">
+    <div class="modal-dialog modal-lg modal-dialog-centered">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="checkModalLabel">@{{ processLog.type === '1' ? '宝时处理' : '承运商处理' }}</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="form-group row">
+                    <label for="work-order-logistic-number" class="text-primary col-sm-2 col-form-label text-right">是否赔偿</label>
+                    <div class="col-sm-10">
+                        <div class="custom-control custom-radio">
+                            <input type="radio" id="is-indemnity-yes" name="isIndemnity" class="custom-control-input"
+                                   value="1"
+                                   v-model="processLog['is_indemnity']">
+                            <label class="custom-control-label" for="is-indemnity-yes">赔偿</label>
+                        </div>
+                        <div class="custom-control custom-radio">
+                            <input type="radio" id="is-indemnity-no" name="isIndemnity" class="custom-control-input"
+                                   value="2"
+                                   v-model="processLog['is_indemnity']">
+                            <label class="custom-control-label" for="is-indemnity-no">不赔偿</label>
+                        </div>
+                    </div>
+                </div>
+                {{-- 宝时处理 确认赔偿方 --}}
+                <div class="form-group row" v-show="processLog['is_indemnity'] === '1' &&  processLog.type === 1">
+                    <label for="process-log-indemnity" class="text-primary col-sm-2 col-form-label text-right">赔偿方</label>
+                    <div class="col-sm-10">
+                        <div class="custom-control custom-radio">
+                            <input type="radio" id="indemnitor-baoshi" name="indemnitor" class="custom-control-input"
+                                   value="1"
+                                   v-model="processLog['indemnitor']">
+                            <label class="custom-control-label" for="indemnitor-baoshi">宝时</label>
+                        </div>
+                        <div class="custom-control custom-radio">
+                            <input type="radio" id="indemnitor-logistic" name="indemnitor" class="custom-control-input"
+                                   value="2"
+                                   v-model="processLog['indemnitor']">
+                            <label class="custom-control-label" for="indemnitor-logistic">承运商</label>
+                        </div>
+                    </div>
+                </div>
+                {{--描述--}}
+                <div class="form-group row" v-show="processLog['is_indemnity'] === '2'">
+                    <label for="process-log-remark" class="text-primary col-sm-2 col-form-label text-right ">理由</label>
+                    <div class="col-sm-10">
+                        <textarea name="process-log-remark" id="process-log-remark" cols="30" rows="5" class="form-control"
+                                  v-model="processLog.remark" ref="process-log-remark"></textarea>
+                    </div>
+                </div>
+                {{--赔偿金额--}}
+                <div class="form-group row" v-show="processLog['is_indemnity'] === '1'">
+                    <label for="process-log-indemnity" class="text-primary col-sm-2 col-form-label text-right">赔偿金额</label>
+                    <div class="col-sm-10">
+                        <input type="number" id="process-log-indemnity" class="form-control"
+                               v-model="processLog.indemnity" placeholder="赔偿金额" ref="process-log-indemnity">
+                    </div>
+                </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"   v-show="processLog['type'] === 1" @click="storeProcessLog">提交</button>
+                {{--承运商--}}
+                <button type="button" class="btn btn-outline-primary"   v-show="processLog['type'] === 2" @click="storeLogisticProcessLog">提交</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 90 - 0
resources/views/order/workOrder/_fill_loss_work_order.blade.php

@@ -0,0 +1,90 @@
+<div class="modal fade " id="fill-loss-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="checkModalLabel" >信息填写</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="form-group row">
+                    <div class="col-sm-2"></div>
+                    <div class="col-sm-10  text-primary">
+                        补发单号,退款成功截图 二选一
+                    </div>
+                </div>
+                {{--破损商品价格--}}
+                <div class="form-group row" >
+                    <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="破损商品价格">
+                    </div>
+                </div>
+                {{--快递单号--}}
+                <div class="form-group row" >
+                    <label for="work-order-logistic-number" class="col-sm-2 col-form-label text-right">丢件快递单号</label>
+                    <div class="col-sm-10">
+                        <input type="text" id="work-order-logistic-number" class="form-control" v-model="workOrder['logistic_number']" placeholder="快递单号">
+                    </div>
+                </div>
+                {{--补发快递--}}
+                <div class="form-group row" v-show="workOrder.dealImages.length === 0">
+                    <label for="work-order-reissue-logistic-number" class="col-sm-2 col-form-label text-right">补发快递单号</label>
+                    <div class="col-sm-10">
+                        <input type="text" id="work-order-reissue-logistic-number" class="form-control" v-model="workOrder['reissue_logistic_number']" placeholder="快递单号">
+                    </div>
+                </div>
+                {{--信息更改--}}
+                <div class="form-group row" >
+                    <hr>
+                    <label for="order_issue_type" class="col-sm-2 col-form-label text-right">收方信息</label>
+                    <div class="col-sm-10">
+                        <textarea class="form-control" name="" id="remake_info" cols="30" rows="2" v-model="workOrder.remake"></textarea>
+                    </div>
+                </div>
+
+                <div class="form-group" >
+                    <div class="offset-2 pl-1 custom-file col-10">
+                        <input type="file" id="deal-images" name="deal-images" multiple class="custom-file-input" accept="image/*" @change="pushImagesAndShow($event,workOrder.dealImages)">
+                        <label class="custom-file-label" for="deal-images">点击添加交易截图</label>
+                    </div>
+                    <div class="offset-2 mt-1 col-10">
+                        <div v-for="(image,i) in  workOrder.dealImages" class="d-inline-block col-4 position-relative card">
+                            <div class="card-body">
+                                <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                <div class="float-right position-relative">
+                                    <button type="button" class="btn btn-sm btn-outline-danger" @click="spliceImage(i,workOrder.dealImages)">取消</button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <hr>
+                <div class="form-group" v-show="!workOrder['reissue_logistic_number']">
+                    <div class="pl-1 custom-file col-10 offset-2">
+                        <input type="file" id="refund-images" name="refund-images" multiple class="custom-file-input" accept="image/*" @change="pushImagesAndShow($event,workOrder.refundImages)">
+                        <label class="custom-file-label" for="refund-images">添加退款成功截图</label>
+                    </div>
+                    <div class="offset-2 mt-1 col-10">
+                        <div v-for="(image,i) in  workOrder.refundImages" class="d-inline-block col-4 position-relative card">
+                            <div class="card-body">
+                                <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                <div class="float-right position-relative">
+                                    <button type="button" class="btn btn-sm btn-outline-danger" @click="spliceImage(i,workOrder.refundImages)">取消</button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </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="updateLossWorkOrder">提交
+                </button>
+            </div>
+        </div>
+    </div>
+</div>

+ 165 - 0
resources/views/order/workOrder/_work_order_details.blade.php

@@ -0,0 +1,165 @@
+{{-- 工单详情 --}}
+<div v-if="item.details.length > 0" 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"
+                v-show="selectDetailId !== item.id"
+                @click="selectDetailId = item.id">显示
+        </button>
+        <button type="button" class="btn btn-sm btn-outline-primary float-right"
+                v-show="selectDetailId === item.id"
+                @click="selectDetailId = null">隐藏
+        </button>
+    </div>
+    <transition name="fade">
+        <div class="body-alert" v-if="selectDetailId === item.id">
+            <div class="card-body row col-12 mb-0 pb-0"
+                 v-for="(detail,i) in item.details">
+                {{-- 快递丢件工单详情 --}}
+                <div v-if="item['issue_type']['name'] === '快递丢件'">
+                    <div v-if="detail.logistic_number">
+                        <span class="mr-3">丢件快递单号:</span>
+                        <span class="text-truncate"
+                              v-text="detail.logistic_number"></span>
+                    </div>
+                    <div>
+                        <span class="mr-3">丢件价值:</span>
+                        <span class="text-truncate"
+                              v-text="detail.price"></span>
+                    </div>
+                    {{-- 工单登记商品详情 --}}
+                    <div v-for="(item,i) in item.commodities">
+                        <span class="mr-2">sku</span>
+                        <span v-text="item.sku"></span>
+                        <span class="mr-2">商品名</span>
+                        <span
+                            v-text="item.commodity ? item.commodity.name : ''"></span>
+                        <span class="mr-2">数量</span>
+                        <span v-text="item.amount"></span>
+                    </div>
+                </div>
+
+                {{-- 破损工单详情 --}}
+                <div v-if="item['issue_type']['name'] === '破损'">
+                    <div>
+                        <div>
+                            <span class="mr-3">破损sku数:</span>
+                            <span class="text-truncate"
+                                  v-text="detail.sku_amount"></span>
+                        </div>
+                        <div>
+                            <span class="mr-3">快递单号:</span>
+                            <span class="text-truncate"
+                                  v-text="detail.logistic_number !== 'null' ? detail.logistic_number : ''"></span>
+                        </div>
+                        <div>
+                            <span class="mr-3">破损商品价值:</span>
+                            <span v-text="detail.price"></span>
+                        </div>
+                    </div>
+
+                </div>
+                {{-- 交易截图 --}}
+                <div class="row"
+                     v-if="item['deal_images'] && item['deal_images'].length > 0">
+                    <div class="col-12">
+                        <hr>
+                        <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="">
+                            <a  target="_blank"
+                                v-if="dealImage.upload_file"
+                                :href="filePrefix+dealImage.upload_file.url + '.'+dealImage.upload_file.type">
+                                <img class="image-w"
+                                     :src="filePrefix+dealImage.upload_file.url + '.'+dealImage.upload_file.type"
+                                     alt="交易截图">
+                            </a>
+                        </div>
+                    </div>
+                </div>
+                {{-- 退款截图 --}}
+                <div class="row"
+                     v-if="item['refund_image'] && item['refund_image'].length > 0">
+                    <div class="col-12">
+                        <hr>
+                        <span class="text-monospace" v-text="'退款截图'"></span>
+                    </div>
+                    <div class="card-body col-sm-6"
+                         v-for="(refundImage,i) in item['refund_images']">
+                        <a target="_blank"
+                           v-if="refundImage.upload_file"
+                           :href="filePrefix+refundImage.upload_file.url + '.'+refundImage.upload_file.type">
+                            <img class="image-w"
+                                 :src="filePrefix+refundImage.upload_file.url + '.'+refundImage.upload_file.type"
+                                 alt="退款截图">
+                        </a>
+                    </div>
+                </div>
+                {{-- 外包装截图 --}}
+                <div class="row"
+                     v-if="item['package_images'] && item['package_images'].length > 0">
+                    <div class="col-12">
+                        <hr>
+                        <span class="text-monospace" v-text="'外包装截图'"></span>
+                    </div>
+                    <div class="card-body col-sm-6"
+                         v-for="(packageImage,i) in item['package_images']">
+                        <a target="_blank"
+                           v-if="packageImage.upload_file"
+                           :href="filePrefix+packageImage.upload_file.url + '.'+packageImage.upload_file.type">
+                            <img class="image-w"
+                                 :src="filePrefix+packageImage.upload_file.url + '.'+packageImage.upload_file.type"
+                                 alt="外包装截图">
+                        </a>
+                    </div>
+                </div>
+                {{-- 内物破损图片 --}}
+                <div class="row"
+                     v-if="item['commodity_images'] && item['commodity_images'].length > 0">
+                    <div class="col-12">
+                        <hr>
+                        <span class="text-monospace" v-text="'内物破损图片'"></span>
+                    </div>
+                    <div class="card-body col-sm-6"
+                         v-for="(commodityImage,i) in item['commodity_images']">
+                        <a target="_blank"
+                           v-if="commodityImage.upload_file"
+                           :href="filePrefix+commodityImage.upload_file.url  + '.'+commodityImage.upload_file.type">
+                            <img class="image-w"
+                                 :src="filePrefix+commodityImage.upload_file.url + '.'+commodityImage.upload_file.type"
+                                 alt="内物破损图片">
+                        </a>
+                    </div>
+                </div>
+            </div>
+
+            {{-- 破损商品详情 --}}
+            <div class="row"
+                 v-if="item['issue_type']['name'] === '破损'">
+                <div class="col-12">
+                    <hr>
+                    <div class="text-monospace">破损商品详情</div>
+                </div>
+                <div class="card-body col-12"
+                     v-for="(commodity,i) in item.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>
+            </div>
+        </div>
+    </transition>
+</div>

+ 503 - 181
resources/views/order/workOrder/index.blade.php

@@ -7,41 +7,37 @@
                 <div id="form_div" style="min-width: 1220px;"></div>
                 <div class="form-inline mt-1" id="btn">
                     @can('订单管理-订单问题件生成')
-                        <span class="ml-1">
-                       <button type="button" class="btn btn-outline-dark btn-sm form-control-sm  tooltipTarget"
-                               @click="createOrderIssue(null,false)" style="background: #dad7e8;">生成问题件</button>
-                       </span>
+                        <button type="button"
+                                class="ml-1 btn btn-outline-dark btn-sm form-control-sm  tooltipTarget"
+                                @click="createOrderIssue(null,false)" style="background: #dad7e8;">生成问题件
+                        </button>
                     @endcan
                     @can('订单管理-订单问题件生成')
-                        <span class="ml-1">
-                       <button type="button" class="btn btn-outline-primary btn-sm form-control-sm  tooltipTarget"
-                               @click="exportText()">导出文本</button>
-                       </span>
+                        <button type="button"
+                                class="ml-1 btn btn-outline-primary btn-sm form-control-sm  tooltipTarget"
+                                @click="exportText()">导出文本
+                        </button>
                     @endcan
                     @can('订单管理-工单处理-审核')
-                        <span class="ml-1">
-                        <button type="button" class="btn btn-outline-success btn-sm form-control-sm  tooltipTarget"
-                                @click="batchReview">
-                            批量审核
+                        <button type="button"
+                                class="ml-1 btn btn-outline-success btn-sm form-control-sm tooltipTarget"
+                                @click="batchReview">批量审核
                         </button>
-                        </span>
                     @endcan
-                    <span class="ml-1">
-                    <button type="button" class="btn btn-outline-dark btn-sm form-control-sm  tooltipTarget"
-                            @click="copyLogisticNumber()" style="background: #dad7e8;">批量复制单号</button>
-                    </span>
+                    <button type="button"
+                            class="ml-1 btn btn-outline-dark btn-sm form-control-sm tooltipTarget"
+                            @click="copyLogisticNumber()" style="background: #dad7e8;">批量复制单号
+                    </button>
                     @can('订单管理-工单处理-审核')
-                        <span class="ml-1">
-                        <button type="button" class="btn btn-outline-success btn-sm form-control-sm  tooltipTarget"
-                                @click="showEditIssueType">
-                            批量修改问题件类型
+                        <button type="button"
+                                class="ml-1 btn btn-outline-success btn-sm form-control-sm  tooltipTarget"
+                                @click="showEditIssueType">批量修改问题件类型
                         </button>
-                        </span>
                     @endcan
                 </div>
 
                 <div>
-                    <table class="table table-sm table-striped table-hover table-bordered td-min-width-80" id="table">
+                    <table class="table table-sm table-striped table-hover table-bordered td-min-width-80 " id="table">
                         <tbody class="">
                         <template v-for="(item,i) in workOrders">
                             <tr @click="selectTr===i+1?selectTr=0:selectTr=i+1" :class="selectTr===i+1?'focusing' : ''">
@@ -49,54 +45,163 @@
                                     <label><input type="checkbox" :value="item.id"></label>
                                 </td>
                                 <td class="text-center">
-                                    <span>@{{ i+1 }}</span>
+                                    <span v-text="i+1"></span>
                                     <span v-show="item.is_issue_order" class="badge badge-primary">问题件</span>
                                 </td>
-                                <td class="text-center">
+                                <td class="text-left">
                                     @can('订单管理-订单问题件生成')
                                         <button class="btn btn-sm btn-outline-primary"
-                                                @click="createOrderIssue(item,true)" v-show="!item.is_issue_order ">
-                                            生成问题件
+                                                v-show="!item.is_issue_order "
+                                                @click="createOrderIssue(item,true)">生成问题件
                                         </button>
                                     @endcan
                                     @can('订单管理-工单处理-审核')
-                                        <button class="btn btn-sm btn-outline-success" v-show="item.status !== '已处理'"
-                                                @click="review(item,i)">
-                                            审核
+                                        <button class="btn btn-sm btn-outline-success"
+                                                v-show="item.status !== '已处理'"
+                                                @click="review(item,i)">审核
+                                        </button>
+                                    @endcan
+                                    @can('订单管理-工单处理-货主编辑')
+                                        <button class="btn btn-sm btn-outline-secondary"
+                                                v-if="item['issue_type']['name'] ==='快递丢件'"
+                                                @click="showFillModel(item,i)">信息填充
+                                        </button>
+                                    @endcan
+                                    @can('订单管理-工单处理-承运商编辑')
+                                        <button class="btn btn-sm btn-outline-secondary"
+                                                v-if="['快递丢件','破损'].includes(item['issue_type']['name'])"
+                                                @click="showEditLog(item,i,2)">快递处理
+                                        </button>
+                                    @endcan
+                                    @can('订单管理-工单处理-宝时编辑')
+                                        <button class="btn btn-sm btn-outline-secondary"
+                                                v-if="['快递丢件','破损'].includes(item['issue_type']['name'])"
+                                                @click="showEditLog(item,i,1)">宝时处理
                                         </button>
                                     @endcan
-
+                                </td>
+                                <td class="text-center">
+                                    @can('订单管理-工单处理-宝时编辑')
+                                        <select class="form-control form-control-sm"
+                                                :value="item['work_order_status']"
+                                                :disabled="item['work_order_status'] === '工单完成'"
+                                                @change="updateWorkOrderStatus(item,$event)">
+                                            <option value="">无</option>
+                                            <option :value="status" v-for="status in workOrderStatus"
+                                                    v-text="status"></option>
+                                        </select>
+                                    @else
+                                        @{{ item.work_order_status }}
+                                    @endcan
                                 </td>
                                 <td class="text-center">@{{ item.status }}</td>
                                 <td class="text-center">@{{ item.owner ? item.owner.name : '' }}</td>
                                 <td class="text-center">@{{ item.order ? item.order.client_code : ''}}</td>
                                 <td>@{{item.order ? (item.order.logistic ? item.order.logistic.name : '') : '' }}</td>
                                 <td class="text-center">
-                                    <template v-if="item.order">
-                                        <template v-if="item.order.packages && item.order.packages.length === 1">
-                                            <p>@{{ item.order.packages[0].logistic_number }}</p>
-                                        </template>
-                                        <template v-else-if="item.order.packages && item.order.packages.length > 0">
-                                            <template v-if="selectOrder === item.order.id">
-                                                <template v-for="(package,index) in item.order.packages">
-                                                    @{{ package.logistic_number }}
-                                                </template>
-                                            </template>
-                                            <template v-else>
-                                                <p>@{{ item.order.packages[0].logistic_number }}</p>
-                                            </template>
-                                            <button class="btn btn-sm btn-outline-primary" v-show="selectOrder === null"
-                                                    @click="selectOrder = item.order.id">
-                                                展开
+                                    <div v-if="item.order">
+                                        <p v-if="item.order.packages && item.order.packages.length === 1"
+                                           v-text="item.order.packages[0].logistic_number">
+                                        </p>
+                                        <div v-else-if="item.order.packages && item.order.packages.length > 0">
+                                            <div v-if="selectOrder === item.order.id">
+                                                <p v-for="(package,index) in item.order.packages"
+                                                   v-text="package.logistic_number"></p>
+                                            </div>
+                                            <div v-else>
+                                                <p v-text="item.order.packages[0].logistic_number"></p>
+                                            </div>
+                                            <button class="btn btn-sm btn-outline-primary"
+                                                    v-show="selectOrder === null"
+                                                    @click="selectOrder = item.order.id">展开
                                             </button>
                                             <button class="btn btn-sm btn-outline-primary"
                                                     v-show="selectOrder === item.order.id"
-                                                    @click="selectOrder = null">
-                                                收起
+                                                    @click="selectOrder = null">收起
+                                            </button>
+                                        </div>
+                                    </div>
+                                </td>
+                                <td>
+                                    {{--  承运商处理日志   --}}
+                                    <div v-if="item['logistic_log']" class="alert alert-light">
+                                        <div>
+                                            <span class="text-muted">承运商处理</span>
+                                            <button class="btn btn-sm btn-outline-info float-right"
+                                                    v-show="selectLogisticLogId === item['logistic_log']['id']"
+                                                    @click="selectLogisticLogId = null">隐藏
+                                            </button>
+                                            <button class="btn btn-sm btn-outline-info float-right"
+                                                    v-show="selectLogisticLogId !== item['logistic_log']['id']"
+                                                    @click="selectLogisticLogId = item['logistic_log']['id']">显示
+                                            </button>
+                                        </div>
+                                        <transition name="fade">
+                                            <div v-show="selectLogisticLogId === item['logistic_log']['id']">
+                                                <div>
+                                                    <span class="mr-2">是否赔偿:</span>
+                                                    <span class="text-truncate"
+                                                          v-text="item['logistic_log']['is_indemnity']"></span>
+                                                </div>
+                                                <div v-if="item['logistic_log']['is_indemnity'] === '是'">
+                                                    <span class="mr-2">赔偿金额:</span>
+                                                    <span class="text-truncate"
+                                                          v-text="item['logistic_log']['indemnity']"></span>
+                                                </div>
+                                                <div v-if="item['logistic_log']['is_indemnity'] === '否'">
+                                                    <span class="mr-2">不赔偿理由:</span>
+                                                    <span v-text="item['logistic_log']['remark']"></span>
+                                                </div>
+                                            </div>
+                                        </transition>
+                                    </div>
+                                    <div v-if="item['process_log']" class="alert alert-light">
+                                        <div>
+                                            <span class="text-muted">宝时处理</span>
+                                            <button class="btn btn-sm btn-outline-info float-right"
+                                                    v-if="selectBaoShiLogId === item['process_log']['id']"
+                                                    @click="selectBaoShiLogId = null">隐藏
                                             </button>
+                                            <button class="btn btn-sm btn-outline-info float-right"
+                                                    v-if="selectBaoShiLogId !== item['process_log']['id']"
+                                                    @click="selectBaoShiLogId = item['process_log']['id']">显示
+                                            </button>
+                                        </div>
+                                        <transition name="fade">
+                                            <div v-show="selectBaoShiLogId === item['process_log']['id']">
+                                                <div>
+                                                    <span class="text-muted">是否赔偿: </span>
+                                                    <span v-text="item['process_log']['is_indemnity']"
+                                                          class="ml-2 text-truncate"></span></div>
+                                                <div v-if="item['process_log']['is_indemnity'] === '是'">
+                                                    <span class="text-muted">赔偿方:</span>
+                                                    <span class="text-truncate"
+                                                          v-text="item['process_log']['indemnitor']"></span>
+                                                </div>
+                                                <div v-if="item['process_log']['is_indemnity'] === '是'">
+                                                    <span class="text-muted">赔偿金额:</span>
+                                                    <span class="ml-2 text-truncate"
+                                                          v-text="item['process_log']['indemnity']"></span>
+                                                </div>
+                                                <div v-if="item['process_log']['is_indemnity'] === '否'">
+                                                    <span class="text-muted">不赔偿理由:</span>
+                                                    <span class="ml-2" v-text=" item['process_log']['remark']"></span>
+                                                </div>
+                                            </div>
+                                        </transition>
+                                    </div>
+                                </td>
+                                <td>
+                                    {{-- 工单详情 --}}
+                                    @can('订单管理-工单处理-宝时编辑')
+                                        @include('order.workOrder._work_order_details')
+                                    @elsecan('订单管理-工单处理-承运商编辑')
+                                        <template v-if="item.status === '已处理' && item.is_issue_order">
+                                            @include('order.workOrder._work_order_details')
                                         </template>
-
-                                    </template>
+                                    @elsecan('订单管理-工单处理-货主编辑')
+                                        @include('order.workOrder._work_order_details')
+                                    @endcan
                                 </td>
                                 <td class="text-center">
                                     @can('订单管理-工单处理-审核')
@@ -105,16 +210,16 @@
                                                 :value="item.order_issue_type_id"
                                                 @change="changeIssueType(item,$event)">
                                             <option value="0"></option>
-                                            <option v-for="type in orderIssueTypes" :value="type.name">@{{ type.value
-                                                }}
+                                            <option v-for="type in orderIssueTypes"
+                                                :value="type.name"
+                                                v-text="type.value">
                                             </option>
                                         </select>
                                     @else
-                                        @{{ item.issue_type ?  item.issue_type.name : '' }}
+                                        <span v-text="item['issue_type'] ?  item['issue_type'].name : ''"></span>
                                     @endcan
                                 </td>
                                 <td class="text-center">@{{ item.remark }}</td>
-
                                 <td class="text-center">
                                     @{{ item.result_explain ?item.result_explain : '' }}
                                 </td>
@@ -128,18 +233,17 @@
                                                 <tr class="table table-sm">
                                                     <td>@{{ item.issue_logs[0].content }}</td>
                                                     <td>@{{ item.issue_logs[0].username }}</td>
-                                                    <td>@{{ item.issue_logs[0].created_at }}</td>
+                                                    <td>@{{ item.issue_logs[0].created_at | dataTime}}</td>
                                                 </tr>
                                             </table>
                                         </template>
-                                        <template v-else>
+                                        <template v-else-if="item.issue_logs.length > 1">
                                             <transition name="fade">
                                                 <table class="table table-sm m-0" v-if="selectOrderIssue === item.id">
-
                                                     <tr v-for="log in item.issue_logs">
                                                         <td>@{{ log.content }}</td>
                                                         <td>@{{ log.username }}</td>
-                                                        <td>@{{ log.created_at }}</td>
+                                                        <td>@{{ log.created_at | dataTime}}</td>
                                                     </tr>
                                                 </table>
                                             </transition>
@@ -148,7 +252,7 @@
                                                     <tr>
                                                         <td>@{{ item.issue_logs[0].content }}</td>
                                                         <td>@{{ item.issue_logs[0].username }}</td>
-                                                        <td>@{{ item.issue_logs[0].created_at }}</td>
+                                                        <td>@{{ item.issue_logs[0].created_at | dataTime}}</td>
                                                     </tr>
                                                 </table>
                                             </transition>
@@ -164,39 +268,37 @@
                                     </template>
                                 </td>
                                 <td class="text-center">
-                                    <template v-if="item.review_at">
-                                        <div v-if="item.order && item.order.packages">
-                                            <template v-for="package in item.order.packages">
-                                                <template
-                                                    v-if="package.transfer_status && package.transfer_status.length > 0">
-                                                    <div v-if="selectOrderPackage === package.id">
-                                                        <template v-for="transfer in package.transfer_status">
-                                                            <p>@{{
-                                                                transfer['accept_time']+':'+transfer['accept_address']
-                                                                }}</p>
-                                                        </template>
-                                                    </div>
-                                                    <div v-else>
-                                                        @{{
-                                                        package.transfer_status[0]['accept_time']+':'+package.transfer_status[0]['accept_address']
-                                                        }}
-                                                    </div>
-                                                    <button class="btn btn-sm btn-outline-primary"
-                                                            v-if="selectOrderPackage !== package.id"
-                                                            @click="selectOrderPackage = package.id">展开
-                                                    </button>
-                                                    <button class="btn btn-sm btn-outline-primary" v-else
-                                                            @click="selectOrderPackage = null">收起
-                                                    </button>
-                                                </template>
+                                    <div v-if="item.order && item.order.packages">
+                                        <template v-for="package in item.order.packages">
+                                            <template
+                                                v-if="package.transfer_status && package.transfer_status.length > 0">
+                                                <div v-if="selectOrderPackage === package.id">
+                                                    <template v-for="transfer in package.transfer_status">
+                                                        <p>@{{
+                                                            transfer['accept_time']+':'+transfer['accept_address']
+                                                            }}</p>
+                                                    </template>
+                                                </div>
+                                                <div v-else>
+                                                    @{{
+                                                    package.transfer_status[0]['accept_time']+':'+package.transfer_status[0]['accept_address']
+                                                    }}
+                                                </div>
+                                                <button class="btn btn-sm btn-outline-primary"
+                                                        v-if="selectOrderPackage !== package.id"
+                                                        @click="selectOrderPackage = package.id">展开
+                                                </button>
+                                                <button class="btn btn-sm btn-outline-primary" v-else
+                                                        @click="selectOrderPackage = null">收起
+                                                </button>
                                             </template>
-                                        </div>
-                                    </template>
+                                        </template>
+                                    </div>
                                 </td>
-                                <td class="text-center">@{{ item.creator.name }}</td>
-                                <td class="text-center">@{{ item.created_at }}</td>
+                                <td class="text-center">@{{ item.creator ? item.creator.name : '' }}</td>
+                                <td class="text-center">@{{ item.created_at}}</td>
                                 <td>@{{ item.reviewer ? item.reviewer.name : ''}}</td>
-                                <td>@{{ item.review_at }}</td>
+                                <td>@{{ item.review_at}}</td>
                                 @can('订单管理-工单处理-删除')
                                     <td>
                                         <button class="btn btn-sm btn-outline-danger"
@@ -216,6 +318,8 @@
             @can('订单管理-工单处理-审核')
                 @include('order.workOrder._edit_issue_type')
             @endcan
+            @include('order.workOrder._fill_loss_work_order')
+            @include('order.workOrder._edit_process_log')
         </div>
     </div>
 @endsection()
@@ -225,19 +329,26 @@
     <script type="text/javascript" src="{{mix('js/queryForm/header.js')}}"></script>
     <style>
         .fade-enter-active, .fade-leave-active {
-            transition: opacity .5s;
+            transition: opacity .3s;
         }
 
         .fade-enter, .fade-leave-to {
             opacity: 0;
         }
+
+        .image-div {
+        }
+
+        .image-w {
+            width: 100%;
+        }
     </style>
     <script>
         let list = new Vue({
             el: "#list",
             data: {
                 workOrders: {!! $workOrders->toJson() !!}['data'],
-                selectTr: null,
+
                 form: null,
                 logistics: [
                         @foreach($logistics as $logistic)
@@ -253,15 +364,41 @@
                     },
                     @endforeach
                 ],
-                owners:[
-                    @foreach($owners as $owner)
-                    {name:'{{$owner->id}}',value:'{{$owner->name}}'},
+                owners: [
+                        @foreach($owners as $owner)
+                    {
+                        name: '{{$owner->id}}', value: '{{$owner->name}}'
+                    },
                     @endforeach
                 ],
+                workOrder: {
+                    id: null,
+                    index: null,
+                    reissue_logistic_number: null, // 补发单号
+                    logistic_number: null, // 丢件快递单号
+                    refundImages: [], // 退款图
+                    dealImages: [], // 交易图
+                },
+                processLog: {
+                    id: null,        // log->id
+                    index: '', // 下标
+                    work_order_id: null, // work_order_id
+                    type: null,  // 类型
+                    is_indemnity: null, // 是否赔偿
+                    indemnity: null,  // 金额
+                    remark: null,
+                    indemnitor: null, // 赔偿方
+                },
+                workOrderStatus: ['信息未填写', '信息已填写', '快递已处理', '工单完成'],
+                selectTr: null,
                 selectOrderPackage: null,
                 selectOrder: null,
+                selectLogisticLogId: null,
+                selectBaoShiLogId: null,
+                selectDetailId: null,
                 selectOrderIssue: null,
                 selectIssueType: '',
+                filePrefix: "{{asset("/storage")}}",
             },
             mounted() {
                 let data = [[
@@ -274,7 +411,7 @@
                         tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的承运商'],
                         placeholder: ['承运商', '定位或多选承运商']
                     },
-                    @can('订单管理-订单问题件生成')
+                        @can('订单管理-订单问题件生成')
                     {
                         name: 'owner',
                         type: 'select_multiple_select',
@@ -282,8 +419,10 @@
                         tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的货主'],
                         placeholder: ['货主', '定位或多选货主']
                     },
-                    @endcan
-                    {name: 'logistic_number', type: 'input', placeholder: '快递单号'},
+                        @endcan
+                    {
+                        name: 'logistic_number', type: 'input', placeholder: '快递单号'
+                    },
                     {
                         name: 'is_issue_order',
                         type: 'select',
@@ -305,32 +444,34 @@
                 let column = [
                     {name: 'no', value: '序号', neglect: true},
                     {name: 'operation', value: '操作', neglect: true},
-                    {name: 'status', value: '状态',neglect: true},
-                    {name: 'owner', value: '货主',neglect: true},
-                    {name: 'client_code', value: '订单号',neglect: true},
-                    {name: 'logisticName', value: '承运商',neglect: true},
+                    {name: 'work_order_status', value: '工单状态', neglect: true},
+                    {name: 'status', value: '状态', neglect: true},
+                    {name: 'owner', value: '货主', neglect: true},
+                    {name: 'client_code', value: '订单号', neglect: true},
+                    {name: 'logisticName', value: '承运商', neglect: true},
                     {name: 'logisticNumber', value: '快递单号'},
+                    {name: 'processLog', value: '处理日志'},
+                    {name: 'workOrderDetails', value: '工单详情'},
                     {name: 'issueType', value: '问题件类型'},
-                    {name: 'workOrderInfo', value: '问题描述',neglect: true},
-                    {name: 'result_explain', value: '情况说明',neglect: true},
+                    {name: 'workOrderInfo', value: '问题描述', neglect: true},
+                    {name: 'result_explain', value: '情况说明', neglect: true},
                     {name: 'orderIssueType', value: '问题件类别'},
                     {
                         name: 'orderIssueProcessLogs', type: 'multi', title: "处理结果", rows: [
                             {value: "内容", col: "4"},
                             {value: "操作人", col: "4"},
                             {value: "时间", col: "4"},
-                        ],neglect: true
+                        ], neglect: true
                     },
                     {name: 'Info', value: '物流跟踪信息', neglect: true},
-                    {name: 'creator', value: '创建人',neglect: true},
-                    {name: 'submit_at', value: '提交时间',neglect: true},
-                    {name: 'reviewer', value: '审核人',neglect: true},
-                    {name: 'review_at', value: '审核时间',neglect: true},
+                    {name: 'creator', value: '创建人', neglect: true},
+                    {name: 'submit_at', value: '提交时间', neglect: true},
+                    {name: 'reviewer', value: '审核人', neglect: true},
+                    {name: 'review_at', value: '审核时间', neglect: true},
                     @can('订单管理-工单处理-删除')
-                    {name: 'delete_operation', value: '其他操作',neglect: true},
-                    @endcan()
+                    {name: 'delete_operation', value: '其他操作', neglect: true}
+                    @endcan
                 ];
-
                 new Header({
                     el: "table",
                     name: "workOrders",
@@ -338,41 +479,49 @@
                     data: this.workOrders,
                     fixedTop: ($('#form_div').height()) + 2,
                 }).init();
-
                 $("#list").removeClass("d-none");
             },
             created() {
-                let self = this;
-                $.each(this.workOrders, function (index, workOrder) {
-                    if (!workOrder.order) return;
-                    if (!workOrder.order.packages) return;
-                    self.sortOrder(workOrder);
+                this.workOrders.forEach(item => {
+                    if (!item.order) return;
+                    if (!item.order.packages) return;
+                    this.sortOrder(item);
                 });
             },
+            filters: {
+                dataTime: function (value) {
+                    if (value !== null) {
+                        return moment(value).format('yyyy-MM-DD');
+                    }
+                    return value
+                },
+            },
             methods: {
                 sortOrder(workOrder) {
-                    let self = this;
                     if (!workOrder.order) return;
-                    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']) {
+                        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 = workOrder.order_issue.logs.map(item => {
-                                return {
-                                    username: item.user ? item.user.name : '',
-                                    content: item.content,
-                                    created_at: item.created_at
-                                };
-                            });
+                        if (workOrder['order_issue'].logs) {
+                            workOrder.issue_logs = this.mapLogs(workOrder['order_issue'].logs);
                         }
                     }
                     if (!workOrder.order.packages) return;
-                    $.each(workOrder.order.packages, function (i, item) {
-                        self.sortTransfer(item);
+                    workOrder.order.packages.forEach(item => {
+                        this.sortTransfer(item)
                     })
                 },
+                mapLogs(logs) {
+                    return logs.map(item => {
+                        return {
+                            username: item.user ? item.user.name : '',
+                            content: item.content,
+                            created_at: item.created_at
+                        };
+                    });
+                },
                 sortTransfer(item) {
                     if (!("transfer_status" in item)) return;
                     if (item.transfer_status == null || !(item.transfer_status instanceof Array)) return;
@@ -390,8 +539,8 @@
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
                             res.data.data.is_issue_order = item.is_issue_order;
-                            this.$set(this.workOrders, i, res.data.data);
                             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 : '审核异常');
@@ -406,18 +555,10 @@
                     if (tag) data.ids = [item.id];
                     else data.ids = checkData;
                     if (!confirm('是否生成对应的问题件')) return;
-                    let _this = this;
                     window.tempTip.waitingTip('生成中........');
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
-                            res.data.data.forEach(item => {
-                                this.workOrders.forEach((workOrder, i) => {
-                                    if (item.id === workOrder.id) {
-                                        _this.sortOrder(item);
-                                        _this.$set(_this.workOrders, i, item);
-                                    }
-                                });
-                            });
+                            this.replaceWorkOrder(res.data.data);
                             this.$forceUpdate();
                             window.tempTip.cancelWaitingTip();
                             window.tempTip.showSuccess('已生成对应的问题件');
@@ -430,6 +571,20 @@
                         window.tempTip.show(err)
                     });
                 },
+                replaceWorkOrder(workOrders) {
+                    let data = [];
+                    workOrders.forEach(workOrder => {
+                        data[workOrder.id] = workOrder;
+                    });
+                    this.workOrders.forEach((workOrder, i) => {
+                        if (data[workOrder.id]) {
+                            let item = data[workOrder.id];
+                            this.sortOrder(item);
+                            this.$set(this.workOrders, i, item);
+                        }
+                    });
+                    this.$forceUpdate();
+                },
                 getMessageWorkOrder() {
                     let selected = checkData;
                     if (!selected) {
@@ -455,7 +610,7 @@
                     if (!item.order) return '';
                     if (!item.order.packages) return '';
                     let message = '';
-                    let issue_type = item.issue_type? item.issue_type.name : '';
+                    let issue_type = item['issue_type'] ? item['issue_type'].name : '';
                     switch (issue_type) {
                         case '拦截':
                             message = this.interceptMessage(item);
@@ -471,15 +626,15 @@
                 },
                 interceptMessage(item) {
                     let message = '';
-                    if (item.order.logistic.code.includes('SF') || item.order.logistic.code.includes('ZTO')) {
+                    if (item.order['logistic']['code'].includes('SF') || item.order['logistic'].code.includes('ZTO')) {
                         item.order.packages.forEach(node => {
                             message += node.logistic_number + '\n';
                         });
                         message = message.trim('\n') + ' ——拦截\n';
                     } else {
-                        let item_order_logistic_name = item.order.logistic.name;
-                        let item_order_adder = item.order.consignee_name + ' '
-                            + item.order.consignee_phone + ' '
+                        let item_order_logistic_name = item.order['logistic']['name'];
+                        let item_order_adder = item.order['consignee_name'] + ' '
+                            + item.order['consignee_phone'] + ' '
                             + ' ' + item.order.address;
                         item.order.packages.forEach(p => {
                             if (p) message += item_order_logistic_name + ' ' + p.logistic_number + ' ' + item_order_adder + '\n';
@@ -490,17 +645,16 @@
                 },
                 modificationMessage(item) {
                     let message = '';
-                    let logistic_code = item.order.logistic.code;
-                    let adder = item.order.consignee_name + ' ' + item.order.consignee_phone + ' '
+                    let logistic_code = item.order['logistic']['code'];
+                    let adder = item.order['consignee_name'] + ' ' + item.order['consignee_phone'] + ' '
                         + item.order.province + ' ' + item.order.city + ' ' + item.order.district + ' ' + item.order.address;
-
                     item.order.packages.forEach(node => {
                         if (logistic_code.includes('SF')) { // 顺丰订单
-                            message += node.logistic_number + ' ——改信息: ' + item.remark + ',运费到付或月结' + '\n';
+                            message += node['logistic_number'] + ' ——改信息: ' + item.remark + ',运费到付或月结' + '\n';
                         } else if (logistic_code.includes('ZTO')) {
-                            message += node.logistic_number + ' ——改信息:' + item.remark + '\n';
+                            message += node['logistic_number'] + ' ——改信息:' + item.remark + '\n';
                         } else {
-                            message += node.logistic_number + ' ' + adder + ' ——改地址' + item.remark + '\n';
+                            message += node['logistic_number'] + ' ' + adder + ' ——改地址' + item.remark + '\n';
                         }
                     });
                     return message;
@@ -508,7 +662,7 @@
                 getMessage(item) {
                     let message = '';
                     if (!item.order.packages) return message;
-                    let adder = item.order.consignee_name + ' ' + item.order.consignee_phone + ' '
+                    let adder = item.order['consignee_name'] + ' ' + item.order['consignee_phone'] + ' '
                         + item.order.province + ' ' + item.order.city + ' ' + item.order.district + ' ' + item.order.address;
                     item.order.packages.forEach(p => {
                         message += p.logistic_number + '  ' + adder + ' ——描述 ' + item.remark + '\n';
@@ -534,19 +688,12 @@
                 batchReview() {
                     let url = '{{route('workOrder.batchReviewApi')}}';
                     let data = {ids: checkData};
-                    let _this = this;
                     window.tempTip.setIndex('1999');
                     if (!confirm('是否对当前选中订单进行审核')) return;
                     window.tempTip.waitingTip('审核中........');
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
-                            $.each(res.data.data, (i, data) => {
-                                $.each(_this.workOrders, (index, item) => {
-                                    if (item.id === data.id) {
-                                        _this.$set(this.workOrders, index, data);
-                                    }
-                                });
-                            });
+                            this.replaceWorkOrder(res.data.data);
                             this.$forceUpdate();
                             window.tempTip.cancelWaitingTip();
                             window.tempTip.showSuccess('审核完成');
@@ -597,20 +744,11 @@
                 editOrderIssueType() {
                     let url = '{{route('workOrder.batchUpdateIssueTypeApi')}}'
                     let data = {ids: checkData, type: this.selectIssueType};
-                    let _this = this;
                     window.tempTip.setIndex(1999);
                     window.axios.post(url, data).then(res => {
                         if (res.data.success) {
                             window.tempTip.showSuccess('修改问题件类型成功');
-                            res.data.data.forEach(item => {
-                                _this.sortOrder(item);
-                                _this.workOrders.forEach((workOrder, i, array) => {
-                                    if (workOrder.id === item.id) {
-                                        array[i] = item;
-                                    }
-                                })
-                            });
-                            this.$forceUpdate();
+                            this.replaceWorkOrder(res.data.data);
                             $("#edit-issue-type-type-modal").modal('hide');
                             return;
                         }
@@ -619,23 +757,207 @@
                         window.tempTip.show(err)
                     })
                 },
-                destroy(item,i){
-                    let url = '{{url('apiLocal/workOrder/')}}'+'/'+item.id;
-                    if(!confirm('是否删除当前工单')) return ;
+                destroy(item, i) {
+                    let url = '{{url('apiLocal/workOrder/')}}' + '/' + item.id;
+                    if (!confirm('是否删除当前工单')) return;
                     window.tempTip.waitingTip('删除.........');
-                    window.axios.delete(url).then(res=>{
-                        if (res.data.success){
-                            this.$delete(this.workOrders,i);
+                    window.axios.delete(url).then(res => {
+                        if (res.data.success) {
+                            this.$delete(this.workOrders, i);
                             window.tempTip.cancelWaitingTip();
                             window.tempTip.showSuccess('删除成功');
-                        }else {
+                        } else {
                             window.tempTip.cancelWaitingTip();
                             window.tempTip.show(res.data.message ? res.data.message : '');
                         }
-                    }).catch(err=>{
+                    }).catch(err => {
                         window.tempTip.cancelWaitingTip();
                         window.tempTip.show(err);
                     })
+                },
+                pushImagesAndShow(e, images) {
+                    let map = [];
+                    for (let i = 0; i < e.target.files.length; i++) {
+                        let image = e.target.files[i];
+                        if (this.imageExist(image, images)) {
+                            map.push(image.name);
+                            continue;
+                        }
+                        let src = window.URL.createObjectURL(image);
+                        images.push({src: src, file: image});
+                    }
+                    e.target.value = '';
+                    if (map.length === 0) return;
+                    window.tempTip.setIndex(1999);
+                    window.tempTip.show(map.join('\n,') + '图片重复');
+                },
+                spliceImage(i, images) {
+                    if (!confirm('是否取消选择该图片')) return;
+                    images.splice(i, 1);
+                },
+                imageExist(image, images) {
+                    let arr = images.filter(item => {
+                        return item.file.name === image.name;
+                    });
+                    return arr.length > 0;
+                },
+                showFillModel(item, index) {
+                    this.workOrder.id = item.id;
+                    this.workOrder.index = index;
+                    this.workOrder.reissue_logistic_number = null; // 补发单号
+                    this.workOrder.logistic_number = null; // 补发单号
+                    this.workOrder.dealImages = []; // 交易图
+                    this.workOrder.refundImages = []; // 退款图
+                    $("#fill-loss-work-order-modal").modal('show');
+                },
+                updateLossWorkOrder() {
+                    let formData = new FormData();
+                    formData.append('id', this.workOrder.id);
+                    formData.append('reissue_logistic_number', this.workOrder.reissue_logistic_number);
+                    formData.append('logistic_number', this.workOrder.logistic_number);
+                    formData.append('price', this.workOrder.price);
+                    let dealImages = this.getImages(this.workOrder.dealImages);
+                    let refundImages = this.getImages(this.workOrder.refundImages);
+                    this.setFormDataImagePrefix(formData, 'dealImages', dealImages);
+                    this.setFormDataImagePrefix(formData, 'refundImages', refundImages);
+                    this.fillLossWorkOrder(formData);
+                },
+                setFormDataImagePrefix(formData, prefix, images) {
+                    images.forEach((item, i) => {
+                        formData.append(`${prefix}[]`, item);
+                    });
+                },
+                getImages(images) {
+                    return images.map((item) => {
+                        return item.file;
+                    })
+                },
+                fillLossWorkOrder(data) {
+                    let url = "{{route('workOrder.lossApi')}}";
+                    window.tempTip.setIndex(1999);
+                    window.axios.post(url, data, {'Content-Type': 'multipart/form-data'}).then(res => {
+                        if (res.data.success) {
+                            this.sortOrder(res.data.data);
+                            this.$set(this.workOrders, this.workOrder.index, res.data.data);
+                            window.tempTip.showSuccess('工单信息填充成功');
+                        } else {
+                            window.tempTip.show(res.data.message);
+                        }
+                    }).catch(err => {
+                        window.tempTip.show(err);
+                    });
+                },
+                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.updateWorkOrderStatusApi')}}";
+                    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;
                 }
             },
         });

+ 19 - 14
resources/views/personnel/laborApply/create.blade.php

@@ -2,7 +2,9 @@
 @section('title')录入-临时工申请协调@endsection
 
 @section('content')
-    <div class="container-fluid" id="list">
+    <div class="container-fluid d-none" id="list">
+        @include('shared._messages')
+
         <div class="card col-md-8 offset-md-2">
             <div class="card-body">
                 <!--
@@ -12,21 +14,24 @@
                    3 临时开放
                 -->
                 @can('人事管理')
-                <form v-if="can_create_status === 2" action="{{ route('laborApply.temporaryOpen') }}" method="post" accept-charset="UTF-8">
-                    {{ csrf_field() }}
-                    {{ method_field('PUT') }}
-                    <div class="form-group">
-                        <button type="submit" class="btn btn-outline-secondary btn-sm">
-                            <i class="far fa-trash-alt"></i> 临时开放
-                        </button>
-                    </div>
-                </form>
+                    <form v-if="can_create_status === 2" action="{{ route('laborApply.temporaryOpen') }}" method="post"
+                          accept-charset="UTF-8">
+                        {{ csrf_field() }}
+                        {{ method_field('PUT') }}
+                        <div class="form-group">
+                            <button type="submit" class="btn btn-outline-secondary btn-sm">
+                                <i class="far fa-trash-alt"></i> 临时开放
+                            </button>
+                        </div>
+                    </form>
                 @endcan
                 <h2 v-if="can_create_status === 2"
-                    style="text-align: center;color: red;font-size: 28px">超过申请时间无法提交申请,联系管理员:152 2169 4191 , 173 1630 6907 </h2>
+                    style="text-align: center;color: red;font-size: 28px">超过申请时间无法提交申请,联系管理员:152 2169 4191 , 173 1630
+                    6907 </h2>
                 <h2 v-if="can_create_status === 3"
                     style="text-align: center;color: red;font-size: 28px">系统临时开放,请尽快提交</h2>
-                <form v-if="(can_create_status === 1) || (can_create_status === 3)" action="{{ route('laborApply.store') }}" method="POST" accept-charset="UTF-8">
+                <form v-if="(can_create_status === 1) || (can_create_status === 3)"
+                      action="{{ route('laborApply.store') }}" method="POST" accept-charset="UTF-8">
                     @csrf
                     @include('shared._error')
                     {{--仓库--}}
@@ -72,7 +77,7 @@
                         <label for="remark" class="col-2 col-form-label text-right">用工要求</label>
                         <div class="col-8">
                             <textarea class="form-control" rows="3"
-                                      placeholder required
+                                      placeholder
                                       name="remark" id="remark"></textarea>
                         </div>
                     </div>
@@ -96,7 +101,7 @@
                 can_create_status: {!! $can_create_status !!}
             },
             mounted() {
-
+                $('#list').removeClass('d-none');
             },
 
             methods: {}

+ 3 - 2
resources/views/personnel/laborApply/dispatch/detail/create.blade.php

@@ -5,7 +5,7 @@
     <div class="container-fluid" id="list">
         <div class="card col-md-8 offset-md-2">
             <div class="card-body">
-                <form action="{{ route('laborApplyDispatch.storeDetail', $laborCompanyDispatch->id) }}" method="post"
+                <form action="{{ route('laborCompanyDispatch.storeDetail', $laborCompanyDispatch->id) }}" method="post"
                       style="display: inline-block;"
                       onsubmit="return confirm('您确定要提交吗?');">
                     {{ csrf_field() }}
@@ -67,7 +67,8 @@
 
             methods: {
                 addItem() {
-                    if (this.items.length <= this.labor_company_dispatch.labor_worker_num -1 ) {
+                    let sum_man_num = this.labor_company_dispatch.man_num + this.labor_company_dispatch.woman_num;
+                    if (this.items.length <= sum_man_num - 1) {
                         this.items.push({});
                     } else {
                         window.tempTip.show("不能超过最大人数限制!");

+ 3 - 2
resources/views/personnel/laborApply/dispatch/detail/edit.blade.php

@@ -5,7 +5,7 @@
     <div class="container-fluid" id="list">
         <div class="card col-md-8 offset-md-2">
             <div class="card-body">
-                <form action="{{ route('laborApplyDispatch.storeDetail', $laborCompanyDispatch->id) }}" method="post"
+                <form action="{{ route('laborCompanyDispatch.storeDetail', $laborCompanyDispatch->id) }}" method="post"
                       style="display: inline-block;"
                       onsubmit="return confirm('您确定要提交吗?');">
                     {{ csrf_field() }}
@@ -68,7 +68,8 @@
 
             methods: {
                 addItem() {
-                    if (this.items.length <= this.labor_company_dispatch.labor_worker_num - 1) {
+                    let sum_man_num = this.labor_company_dispatch.man_num + this.labor_company_dispatch.woman_num;
+                    if (this.items.length <= sum_man_num - 1) {
                         this.items.push({});
                     } else {
                         window.tempTip.show("不能超过最大人数限制!");

+ 52 - 0
resources/views/personnel/laborApply/dispatch/edit.blade.php

@@ -0,0 +1,52 @@
+@extends('layouts.app')
+@section('title')修改-劳务派遣明细@endsection
+
+@section('content')
+    <div class="container-fluid" id="list">
+        <div class="card col-md-8 offset-md-2">
+            <div class="card-body">
+                <form action="{{ route('laborCompanyDispatch.update',$laborCompanyDispatch->id) }}" method="POST" accept-charset="UTF-8">
+                    @csrf
+                    @method('PUT')
+                    @include('shared._error')
+                    {{--男工人数--}}
+                    <div class="from-group row mt-3">
+                        <label for="man_num" class="col-2 col-form-label text-right">男工人数</label>
+                        <div class="col-8">
+                            <input type="number" class="form-control" id="man_num" name="man_num" value="{{ $laborCompanyDispatch->man_num }}" required>
+                        </div>
+                    </div>
+
+                    {{--女工人数--}}
+                    <div class="from-group row mt-3">
+                        <label for="woman_num" class="col-2 col-form-label text-right">女工人数</label>
+                        <div class="col-8">
+                            <input type="number" class="form-control" id="woman_num" name="woman_num" value="{{ $laborCompanyDispatch->woman_num }}" required>
+                        </div>
+                    </div>
+                    {{--提交--}}
+                    <div class="form-group row mt-5">
+                        <div class="col-8 offset-2">
+                            <input type="submit" class="btn btn-success form-control">
+                        </div>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+@endsection
+
+@section('lastScript')
+    <script>
+        new Vue({
+            el: "#list",
+            data: {
+            },
+            mounted() {
+
+            },
+
+            methods: {}
+        });
+    </script>
+@endsection

+ 62 - 20
resources/views/personnel/laborApply/dispatch/index.blade.php

@@ -16,11 +16,55 @@
                     <td>
                         <div>
                             @{{ i+1 }}
-                            <span v-if="labor_company_dispatch.exceed_max_labor_num_status==2"><i class="fa fa-thermometer-full" style="color: red" aria-hidden="true"></i></span>
+                            <span v-if="labor_company_dispatch.exceed_max_labor_num_status==2"><i
+                                    class="fa fa-thermometer-full" style="color: red" aria-hidden="true"></i></span>
                         </div>
+                    </td>
+                    <td class="">
+                        @can('劳务所')
+                            <div class="float-left ml-3" v-if="labor_company_dispatch.status==='人事确认'">
+                                <form :action="getBaseUrl(labor_company_dispatch) + '/laborCompanyReceivingOrder'"
+                                      method="post"
+                                      accept-charset="UTF-8" onsubmit="return confirm('是否确认接单!')">
+                                    @csrf
+                                    @method('PATCH')
+                                    <input type="number" name="status" hidden value="3">
+                                    <button type="submit" class="btn btn-outline-primary btn-sm" role="button">劳务接单
+                                    </button>
+                                </form>
+                            </div>
+                            <div class="float-left ml-3" v-if="labor_company_dispatch.status==='劳务接单'">
+                                <a :href="getCreateOrEditDetailUrl(labor_company_dispatch)"
+                                   class="btn btn-outline-secondary btn-sm" role="button">
+                                    @{{
+                                    labor_company_dispatch.labor_company_dispatch_details.length>0?'修改明细':'录入明细'
+                                    }}
+                                </a>
+                            </div>
+                        @endcan()
+                        @can('人事管理')
+                            <div class="float-left ml-3" v-if="labor_company_dispatch.status==='创建'">
+                                <form :action="getBaseUrl(labor_company_dispatch) + '/personnelCheck'" method="post"
+                                      accept-charset="UTF-8" onsubmit="return confirm('是否确认!')">
+                                    @csrf
+                                    @method('PATCH')
+                                    <input type="text" name="status" hidden value="人事确认">
+                                    <button type="submit" class="btn btn-outline-primary btn-sm" role="button">人事确认
+                                    </button>
+                                </form>
+                            </div>
 
+                            <div class="float-left ml-3" v-if="labor_company_dispatch.status==='创建'">
+                                <a :href="getEditlLaborCompanyDispatchUrl(labor_company_dispatch)"
+                                   class="btn btn-outline-secondary btn-sm" role="button">
+                                    修改派遣人数
+                                </a>
+                            </div>
+                        @endcan()
                     </td>
+
                     <td>@{{ labor_company_dispatch.labor_company.name }}</td>
+                    <td>@{{ labor_company_dispatch.status }}</td>
                     <td>@{{ labor_company_dispatch.man_num }}</td>
                     <td>@{{ labor_company_dispatch.woman_num }}</td>
                     <td>
@@ -47,12 +91,6 @@
                         </div>
                     </td>
                     <td>@{{ labor_company_dispatch.dispatch_date }}</td>
-                    <td>
-                        <a :href="getCreateOrEditDetailUrl(labor_company_dispatch)"
-                           class="btn btn-outline-secondary btn-sm" role="button">
-                            @{{ labor_company_dispatch.labor_company_dispatch_details.length>0?'修改临时工明细':'录入临时工明细' }}
-                        </a>
-                    </td>
 
                 </tr>
             </table>
@@ -94,12 +132,13 @@
                 _this.form.init();
                 let column = [
                     {name: 'index', value: '序号', neglect: true},
+                    {name: 'do', value: '操作'},
                     {name: 'name', value: '劳务公司'},
+                    {name: 'status', value: '状态 '},
                     {name: 'man_num', value: '男工人数'},
                     {name: 'woman_num', value: '女工人数'},
                     {name: 'details', value: '派遣详情'},
                     {name: 'dispatch_date', value: '分配日期'},
-                    {name: 'do', value: '操作'},
                 ];
                 new Header({
                     el: "table",
@@ -112,25 +151,28 @@
             },
 
             methods: {
+                /*临时工信息详情*/
                 getCreateOrEditDetailUrl(labor_company_dispatch) {
                     let url = "";
                     if (labor_company_dispatch.labor_company_dispatch_details.length > 0) {
-                        url = "{{ url('personnel/laborApply/dispatch') }}/" + labor_company_dispatch.id + '/detail/edit';
+                        url = "{{ url('personnel/laborApply/laborCompanyDispatch') }}/" + labor_company_dispatch.id + '/detail/edit';
                     } else {
-                        url = "{{ url('personnel/laborApply/dispatch') }}/" + labor_company_dispatch.id + '/detail/create';
+                        url = "{{ url('personnel/laborApply/laborCompanyDispatch') }}/" + labor_company_dispatch.id + '/detail/create';
                     }
                     return url;
                 },
-                exceed_max_labor_num_color(obj) {
-                    let result = {};
-                    if (obj.exceed_max_labor_num_status == 2) {
-                        result = {
-                            color: 'red',
-                        };
-
-                    }
-                    return result;
-                }
+                /*分配详情编辑*/
+                getEditlLaborCompanyDispatchUrl(labor_company_dispatch) {
+                    let url = "";
+                    url = "{{ url('personnel/laborApply/laborCompanyDispatch') }}/" + labor_company_dispatch.id + '/edit';
+                    return url;
+                },
+                /*劳务接单*/
+                getBaseUrl(labor_company_dispatch) {
+                    let url = "";
+                    url = "{{ url('personnel/laborApply/laborCompanyDispatch') }}/" + labor_company_dispatch.id;
+                    return url;
+                },
             },
         });
     </script>

+ 4 - 3
resources/views/personnel/laborApply/edit.blade.php

@@ -5,8 +5,9 @@
     <div class="container-fluid" id="list">
         <div class="card col-md-8 offset-md-2">
             <div class="card-body">
-                <form action="{{ route('laborApply.store') }}" method="POST" accept-charset="UTF-8">
+                <form action="{{ route('laborApply.update',$laborApply->id) }}" method="POST" accept-charset="UTF-8">
                     @csrf
+                    @method( 'PATCH' )
                     @include('shared._error')
                     {{--仓库--}}
                     <div class="from-group row mt-3">
@@ -15,7 +16,7 @@
                             <select class="form-control" id="warehouse_id" name="warehouse_id" required>
                                 <option value="" hidden disabled selected>请选择仓库</option>
                                 @foreach($warehouses as $warehouse)
-                                    <option {{ $warehouse->id == $laborApply->warehouse_id ? 'selected':''}}>{{ $warehouse->name }}</option>
+                                    <option value="{{ $warehouse->id }}" {{ $warehouse->id == $laborApply->warehouse_id ? 'selected':''}}>{{ $warehouse->name }}</option>
                                 @endforeach
                             </select>
                         </div>
@@ -27,7 +28,7 @@
                             <select class="form-control" id="user_workgroup_id" name="user_workgroup_id" required>
                                 <option value="" hidden disabled selected>请选择所属组别</option>
                                 @foreach($userWorkGroups as $userWorkGroup)
-                                    <option {{ $userWorkGroup->id == $laborApply->user_workgroup_id ? 'selected':''}}>{{ $userWorkGroup->name }}</option>
+                                    <option value="{{ $userWorkGroup->id }}" {{ $userWorkGroup->id == $laborApply->user_workgroup_id ? 'selected':''}}>{{ $userWorkGroup->name }}</option>
                                 @endforeach
                             </select>
                         </div>

+ 1 - 37
resources/views/personnel/laborApply/index.blade.php

@@ -8,7 +8,7 @@
             <div class="ml-3 form-inline" id="btn">
                 @can('人事管理')
                     <span class="ml-1">
-                        <a href="{{ route('laborApply.createDispatch') }}" type="button"
+                        <a title="00:00 - 01:00 禁止生成数据" href="{{ route('laborApply.createDispatch') }}" type="button"
                            class="btn btn-sm ml-2 btn-outline-danger">重新生成劳务派遣数据</a>
                     </span>
                 @endcan
@@ -43,41 +43,6 @@
                                 <i class="far fa-trash-alt"></i> 删除
                             </button>
                         </form>
-                        <form v-if="labor_apply.status === '劳务接单'" :action="getBaseUrl(labor_apply)" method="post"
-                              style="display: inline-block;">
-                        {{ csrf_field() }}
-                        {{ method_field('PATCH') }}
-                        <!-- Button trigger modal -->
-                            <button type="button" class="btn btn-primary" data-toggle="modal"
-                                    data-target="#actualNumModal">
-                                实到人数
-                            </button>
-
-                            <!-- Modal -->
-                            <div class="modal fade" id="actualNumModal" tabindex="-1"
-                                 aria-labelledby="actualNumModalLabel" aria-hidden="true">
-                                <div class="modal-dialog">
-                                    <div class="modal-content">
-                                        <div class="modal-header">
-                                            <h5 class="modal-title" id="actualNumModalLabel">实到人数</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="form-group">
-                                                <input type="number" class="form-control" name="actual_num">
-                                            </div>
-                                        </div>
-                                        <div class="modal-footer">
-                                            <button type="button" class="btn btn-secondary" data-dismiss="modal">取消
-                                            </button>
-                                            <button type="submit" class="btn btn-primary">确认</button>
-                                        </div>
-                                    </div>
-                                </div>
-                            </div>
-                        </form>
                     </td>
                 </tr>
             </table>
@@ -102,7 +67,6 @@
                 selectTr: 0
             },
             mounted() {
-                console.log(this.labor_applies);
                 $('#list').removeClass('d-none');
                 let _this = this;
                 $(".up").slideUp();

+ 6 - 6
resources/views/rejected/edit.blade.php

@@ -4,12 +4,12 @@
 @section('content')
 
     <div id="nav2">
-{{--        @component('rejected.menu')--}}
-{{--            @can('退货管理-录入')--}}
-{{--                <li class="nav-item">--}}
-{{--                    <a class="nav-link" href="javascript:;" :class="{active:isActive('edit',3)}">修改</a>--}}
-{{--                </li> @endcan--}}
-{{--        @endcomponent--}}
+        {{--@component('rejected.menu')
+            @can('退货管理-录入')
+                <li class="nav-item">
+                    <a class="nav-link" href="javascript:;" :class="{active:isActive('edit',3)}">修改</a>
+                </li> @endcan
+        @endcomponent--}}
     </div>
     <div class="container-fluid d-none" id="editPanel">
         <div class="card mb-2">

+ 14 - 1
routes/apiLocal.php

@@ -31,7 +31,11 @@ Route::group(['prefix' => 'rejected' ],function(){
 Route::post('logistic/numberFeatures/computeLogisticByNumber', 'LogisticNumberFeatureController@apiComputeLogisticByNumber');
 Route::post('logistic/logisticNumberReturnIsUnique', 'RejectedBillController@apiLogisticNumberReturnIsUnique');
 
-Route::post('commodity/getCommodityByBarcode', 'CommodityController@apiGetCommodityByBarcode');
+/** 商品 */
+Route::prefix('commodity')->group(function (){
+    Route::post('getCommodityByBarcode', 'CommodityController@apiGetCommodityByBarcode');
+    Route::post('getCommodity','CommodityController@getCommodityApi')->name('commodity.getCommodityApi');
+});
 
 Route::post('rejectedBill/getRejectedByLogisticNumberReturn', 'RejectedController@apiGetRejectedByLogisticNumberReturn');
 
@@ -263,6 +267,10 @@ Route::group(['prefix' => 'print'],function (){
 });
 
 Route::prefix('workOrder')->group(function(){
+    Route::post('store','WorkOrderController@storeApi')->name('workOrder.storeApi'); // 创建
+    Route::post('damaged','WorkOrderController@damagedApi')->name('workOrder.damagedApi'); // 创建 破损
+    Route::post('loss','WorkOrderController@updateLossApi')->name('workOrder.lossApi'); // 客户提供丢件信息
+    Route::post('workOrderStatus','WorkOrderController@updateWorkOrderStatusApi')->name('workOrder.updateWorkOrderStatusApi');
     Route::post('store','WorkOrderController@storeApi')->name('workOrder.storeApi'); // 创建
     Route::post('review','WorkOrderController@reviewApi')->name('workOrder.reviewApi'); // 审核
     Route::post('batchReview','WorkOrderController@batchReviewApi')->name('workOrder.batchReviewApi');  // 批量审核
@@ -270,6 +278,11 @@ Route::prefix('workOrder')->group(function(){
     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::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(){

+ 13 - 9
routes/web.php

@@ -50,16 +50,20 @@ Route::get('personnel/checking-in/importAndExportQRCode','QRCodeController@impor
 Route::post('personnel/checking-in/refreshQRCode','QRCodeController@refreshQRCode');
 
 //人事管理
-Route::group(['prefix'=>'personnel'],function() {
+Route::group(['prefix'=>'personnel','middleware'=>'auth'],function() {
+
     //临时开放录入
     Route::put('laborApply/temporaryOpen','LaborApplyController@temporaryOpen')->name('laborApply.temporaryOpen');
     Route::get('laborApply/createDispatch','LaborApplyController@createDispatch')->name('laborApply.createDispatch');
     //劳务派遣查看
-    Route::get('laborApply/dispatch','LaborCompanyDispatchController@index')->name('laborApplyDispatch.index');
-    Route::get('laborApply/dispatch/{laborCompanyDispatch}/detail/create','LaborCompanyDispatchController@createDetail')->name('laborApplyDispatch.createDetail');
-    Route::get('laborApply/dispatch/{laborCompanyDispatch}/detail/edit','LaborCompanyDispatchController@editDetail')->name('laborApplyDispatch.editDetail');
-    Route::post('laborApply/dispatch/{laborCompanyDispatch}/detail','LaborCompanyDispatchController@storeDetail')->name('laborApplyDispatch.storeDetail');
-
+    Route::group(['prefix' => 'laborApply'], function () {
+        Route::patch('laborCompanyDispatch/{laborCompanyDispatch}/laborCompanyReceivingOrder', 'LaborCompanyDispatchController@laborCompanyReceivingOrder')->name('laborCompanyDispatch.laborCompanyReceivingOrder');
+        Route::patch('laborCompanyDispatch/{laborCompanyDispatch}/personnelCheck', 'LaborCompanyDispatchController@personnelCheck')->name('laborCompanyDispatch.personnelCheck');
+        Route::resource('laborCompanyDispatch','LaborCompanyDispatchController')->only(['index','edit','update']);
+        Route::get('laborCompanyDispatch/{laborCompanyDispatch}/detail/create','LaborCompanyDispatchController@createDetail')->name('laborCompanyDispatch.createDetail');
+        Route::get('laborCompanyDispatch/{laborCompanyDispatch}/detail/edit','LaborCompanyDispatchController@editDetail')->name('laborCompanyDispatch.editDetail');
+        Route::post('laborCompanyDispatch/{laborCompanyDispatch}/detail','LaborCompanyDispatchController@storeDetail')->name('laborCompanyDispatch.storeDetail');
+    });
     Route::resource('laborApply', 'LaborApplyController');
 
 });
@@ -850,7 +854,7 @@ Route::group(['prefix'=>'package'],function(){
             });
             //仓储费
             Route::group(['prefix' => 'storageFee'], function () {
-                Route::get('','SettlementBillStorageFeeController@index');
+                Route::get('','SettlementBillStorageFeeController@index')->name('settlementBills.storageFee.index');
                 Route::post('confirmBill','SettlementBillStorageFeeController@confirmBill');
                 Route::any('export','SettlementBillStorageFeeController@export');
             });
@@ -861,7 +865,7 @@ Route::group(['prefix'=>'package'],function(){
                 Route::any('detail/export', 'SettlementBillStoreFeeDetailController@export');
                 Route::any('report/export', 'SettlementBillStoreFeeReportController@export');
                 Route::get('detail', 'SettlementBillStoreFeeDetailController@index');
-                Route::get('report', 'SettlementBillStoreFeeReportController@index');
+                Route::get('report', 'SettlementBillStoreFeeReportController@index')->name('settlementBills.storeFee.report');
             });
             //出库费
             Route::group(['prefix' => 'storeOutFee'], function () {
@@ -870,7 +874,7 @@ Route::group(['prefix'=>'package'],function(){
                 Route::any('detail/export', 'SettlementBillStoreOutFeeDetailController@export');
                 Route::any('report/export', 'SettlementBillStoreOutFeeReportController@export');
                 Route::get('detail', 'SettlementBillStoreOutFeeDetailController@index');
-                Route::get('report', 'SettlementBillStoreOutFeeReportController@index');
+                Route::get('report', 'SettlementBillStoreOutFeeReportController@index')->name('settlementBills.storeOutFee.report');
             });
             //杂项费
             Route::group(['prefix' => 'sundryFee'], function () {

+ 0 - 2
tests/Services/LogisticAliJiSuApiService/FormatTest.php

@@ -5,9 +5,7 @@ namespace Tests\Services\LogisticAliJiSuApiService;
 use App\Services\LogisticAliJiSuApiService;
 use App\Services\LogisticYDService;
 use App\Services\LogisticYTOService;
-use BeyondCode\DumpServer\DumpServerServiceProvider;
 use Tests\TestCase;
-use App\LogisticYD;
 use App\Traits\TestMockSubServices;
 
 class FormatTest extends TestCase

+ 31 - 3
tests/Services/OrderPackageReceivedSyncService/TestUpdate.php

@@ -69,23 +69,51 @@ class TestUpdate extends TestCase
         ];
 
         $this->service->update($data);
-        $this->assertDatabaseHas('order_packages',[
+        $this->assertDatabaseHas('order_packages', [
             'logistic_number' => 'SF1038651915891',
             'status' => '派送中',
             'received_at' => Carbon::now()->toDateTimeString(),
             'exception' => '否',
         ]);
-        $this->assertDatabaseHas('order_packages',[
+        $this->assertDatabaseHas('order_packages', [
             'logistic_number' => 'SF1038651413847',
             'status' => '派送中',
             'received_at' => Carbon::now()->toDateTimeString(),
             'exception' => '否',
         ]);
-        $this->assertDatabaseHas('order_packages',[
+        $this->assertDatabaseHas('order_packages', [
             'logistic_number' => 'SF1038611050071',
             'status' => '派送中',
             'received_at' => Carbon::now()->toDateTimeString(),
             'exception' => '否',
         ]);
     }
+
+    public function test_111()
+    {
+
+        $logistic_number = 'SF1038651915811';
+        OrderPackage::query()->where('logistic_number', $logistic_number)->delete();
+        $orderPackage = factory(OrderPackage::class)->create([
+            'logistic_number' => $logistic_number,
+            'is_manual_update' => true,
+            'exception_status' => '单号异常',
+            'status' => 2,
+        ]);
+
+        $data = [
+            [
+                'logistic_number' => $logistic_number,
+                'exception_status' => '延迟发货',
+            ],
+        ];
+        $this->service->update($data);
+//        OrderPackage::query()->where('logistic_number', $logistic_number)->update([
+//            'status' => 5,
+////            'exception_status' => 3,
+//        ]);
+
+        dump(OrderPackage::query()->where('logistic_number', $logistic_number)->get()->toArray());
+
+    }
 }

+ 55 - 0
文档/SystemHandBook.md

@@ -62,3 +62,58 @@
 * **权限**
 
   根据用户所有权限不同,上述功能可能有部分缺少
+## 订单管理
+
+* **订单**
+    1. 查询
+       * 导出Excel 导出经过查询筛选后对应的数据,已Excel的结构保存在本地
+            分为俩个中
+       * 批量添加备注
+       * 冻结
+       * 解冻
+       * 取消分配
+       * 重置快递获取标记
+       * 重置接口回传标记
+       * 标记问题件
+       * 生成退回单
+       * 复制快递单号
+       * 生成工单
+       * 一键回传
+       * 一键揽收
+    
+* **波次**
+    1. 查询
+       * 修复波次
+* **问题件**
+    1. 查询
+        * 导出Excel 导出经过查询筛选后对应的数据,已Excel的结构保存在本地
+        * 批量完结
+        * 批量处理说明
+        * 批量处理赔偿金额与事故责任方
+        * 复制快递单号 
+        * 批量导入处理
+        * 复制退回单号
+        * 批量财务确认
+        * 批量财务确认取消
+        * 置顶
+        * 
+* **工单处理**
+    * 查询
+        1. 审核
+           > 添加审核标记
+        2. 生成问题件  
+           > 勾选生成工单对应的问题件。当勾选的工单已有对应问题件,生成问题件失败。返回错误提示信息
+        3. 快递处理
+           > 需要对应的 权限 快递处理,以及指定了对应的承运商。
+            承运商只需要处理 破损和丢件 的工单。
+            填写 赔偿金额 或 退回单号等信息。
+        4. 宝时处理
+           > 需要对应权限 宝时处理 。
+            添加 破损和丢件的处理记录。
+            填写 赔偿金额 或 其他信息。
+        5. 信息填充
+           > 对应权限 货主编辑。
+            填写破损工单对应信息。 
+        
+
+

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio