ajun 4 anni fa
parent
commit
ecfbc1c6b6

+ 25 - 0
app/Filters/WorkOrderFilters.php

@@ -5,6 +5,7 @@ namespace App\Filters;
 
 use App\Order;
 use App\OrderIssue;
+use App\OrderIssueType;
 use App\OrderPackage;
 use App\Services\OwnerService;
 use App\Traits\ModelSearchWay;
@@ -45,6 +46,7 @@ class WorkOrderFilters
     protected $workOrderTypeQuery;
     protected $orderQuery;
     protected $orderPackageQuery;
+    protected $issueTypeQuery;
 
     public function __construct(Request $request)
     {
@@ -94,6 +96,8 @@ class WorkOrderFilters
         $this->afterFilterLogistic($owner_ids,$logistic_ids);
 
         $this->afterFilterOwner($owner_ids);
+
+        $this->afterFileIssueType();
     }
 
     // 可见货主过滤
@@ -118,6 +122,15 @@ class WorkOrderFilters
         }
     }
 
+    public function afterFileIssueType()
+    {
+        if(Gate::allows('订单管理-工单处理-客服编辑') || Gate::allows('订单管理-工单处理-货主编辑')){
+            $this->getOrderIssueQuery()->whereIn('name',['拦截', '信息更改', '其他', '快递异常', '错漏发', '破损', '快递丢件']);
+        } else if (Gate::allows('订单管理-工单处理-承运商编辑')){
+            $this->getOrderIssueQuery()->whereIn('name',['拦截', '信息更改', '破损', '快递丢件','快递异常']);
+        }
+    }
+
     public function beforeApply()
     {
         if ($this->orderPackageQuery){
@@ -127,6 +140,10 @@ class WorkOrderFilters
         if ($this->orderQuery) {
             $this->queryBuilder->whereIn('order_id',$this->orderQuery);
         }
+
+        if ($this->issueTypeQuery){
+            $this->queryBuilder->whereIn('order_issue_type_id',$this->issueTypeQuery);
+        }
     }
 
     public function getOrderQuery(): Builder
@@ -145,6 +162,14 @@ class WorkOrderFilters
         return $this->orderPackageQuery;
     }
 
+    public function getOrderIssueQuery(): Builder
+    {
+        if (!$this->issueTypeQuery){
+            $this->issueTypeQuery = OrderIssueType::query()->select('id');
+        }
+        return $this->issueTypeQuery;
+    }
+
     public function id($id)
     {
         if(is_array($id))$this->queryBuilder->whereIn('work_orders.id',$id);

+ 9 - 0
app/Http/Controllers/TestController.php

@@ -712,4 +712,13 @@ sql;
         $orderIssue = OrderIssue::query()->find('48798');
         $orderIssue->syncRejectingStatus();
     }
+
+    public function test123()
+    {
+
+        $reflection = new \ReflectionClass(new OrderIssue());
+        dump($reflection->getMethods());
+        dump($reflection->getConstants());
+        dump($reflection->getInterfaces());
+    }
 }

+ 167 - 79
app/Http/Controllers/WorkOrderController.php

@@ -6,7 +6,10 @@ use App\Filters\WorkOrderFilters;
 use App\Http\Requests\WorkOrder\WorkOrderRequest;
 use App\Logistic;
 use App\OrderIssue;
+use App\Services\OrderService;
+use App\Services\OwnerService;
 use App\Services\WorkOrderCommoditiesService;
+use App\Services\WorkOrderLogService;
 use App\Services\WorkOrderService;
 use App\WorkOrder;
 use Illuminate\Http\Request;
@@ -15,93 +18,144 @@ use Illuminate\Support\Facades\Gate;
 class WorkOrderController extends Controller
 {
 
-    public function index(Request $request, WorkOrderFilters $filters, WorkOrderService $service)
+    /**
+     * @var WorkOrderService $service
+     * @var WorkOrderCommoditiesService $commoditiesService
+     * @var WorkOrderLogService $logService
+     * @var OrderService $orderService
+     * @var OwnerService $ownerService
+     */
+    public $service;
+    public $commoditiesService;
+    public $logService;
+    public $orderService;
+    public $ownerService;
+
+    public function __construct(
+        WorkOrderService $service,
+        WorkOrderCommoditiesService $commoditiesService,
+        WorkOrderLogService $logService,
+        OrderService $orderService,
+        OwnerService $ownerService)
+    {
+        $this->service = $service;
+        $this->commoditiesService = $commoditiesService;
+        $this->logService = $logService;
+        $this->orderService = $orderService;
+        $this->ownerService = $ownerService;
+    }
+
+    public function index(Request $request, WorkOrderFilters $filters)
     {
         if (Gate::denies('订单管理-工单处理-查询')) return redirect('/');
+
         $workOrders = WorkOrder::query()->filter($filters)->defaultWith()->orderBy('created_at')->orderByDesc('status')->paginate($request['paginate'] ?? 50);
+
         $logistics = Logistic::all();
-        $orderIssueTypes = $service->getIssueType();
-        $owners = app('OwnerService')->getAuthorizedOwners();
-        $service->tags($workOrders);
-        return view('order.workOrder.index', compact('workOrders', 'logistics', 'orderIssueTypes','owners'));
+
+        $orderIssueTypes = $this->service->getIssueType();
+
+        $owners = $this->ownerService->getAuthorizedOwners();
+
+        $this->service->tags($workOrders);
+
+        return view('order.workOrder.index', compact('workOrders', 'logistics', 'orderIssueTypes', 'owners'));
     }
 
     // 审核 api
-    public function reviewApi(Request $request, WorkOrderService $service): array
+    public function reviewApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-审核')) return ['success' => false, 'message' => '没有对应的编辑权限'];
+
         $workOrder = WorkOrder::query()->find($request['id']);
-        return $service->review($workOrder);
+
+        return $this->service->review($workOrder);
     }
 
     // 批量审核 api
-    public function batchReviewApi(Request $request,WorkOrderService  $service): array
+    public function batchReviewApi(Request $request): array
     {
-        if(Gate::denies('订单管理-工单处理-审核'))return ['success' => false, 'message' => '没有对应的编辑权限'];
-        if (WorkOrder::query()->whereIn('id',$request['ids'])->whereNotNull('review_at')->exists())
+        if (Gate::denies('订单管理-工单处理-审核')) {
+            return ['success' => false, 'message' => '没有对应的编辑权限'];
+        }
+
+        if (WorkOrder::query()->whereIn('id', $request['ids'])->whereNotNull('review_at')->exists())
             return ['success' => false, 'message' => '选中的工单已有审核完成,刷新页面重试'];
-        $work_orders = WorkOrder::query()->whereIn('id',$request['ids'])->get();
-        $service->tags($work_orders);
-        return $service->batchReview($work_orders);
+
+        $work_orders = WorkOrder::query()->whereIn('id', $request['ids'])->get();
+
+        $this->service->tags($work_orders);
+
+        return $this->service->batchReview($work_orders);
     }
 
     // 生成问题件 api
-    public function buildOrderIssueApi(Request $request, WorkOrderService $service): array
+    public function buildOrderIssueApi(Request $request): array
     {
         if (Gate::denies('订单管理-订单问题件生成'))
             return ['success' => false, 'message' => '没有对应权限'];
+
         $work_orders = WorkOrder::query()->whereIn('id', $request['ids'])->get();
+
         if (count($work_orders) == 0) return ['success' => false, 'message' => '刷新当前页面重试'];
-        if (OrderIssue::query()->whereIn('order_id',$work_orders->map(function($item){return $item['order_id'];}))->exists()){
+
+        if (OrderIssue::query()->whereIn('order_id', $work_orders->map(function ($item) {
+            return $item['order_id'];
+        }))->exists()) {
             return ['success' => false, 'message' => '已有对应的问题件'];
         }
-        $result = $service->buildOrderIssue($work_orders);
+
+        $result = $this->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];
+
+        $workOrders = WorkOrder::query()->defaultWith()->whereIn('id', $request['ids'])->get();
+
+        $this->service->tags($workOrders);
+
+        return ['success' => true, 'data' => $workOrders];
     }
 
     // 创建工单 api
-    public function storeApi(Request $request, WorkOrderService $service):array
+    public function storeApi(Request $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
             return ['success' => false, 'message' => '没有对应权限'];
         $params = $request->all();
-        if (count($params) == 0) return ['success' => false,'message' => '参数异常'];
-        app('OrderService')->syncOrderByCodes(array_map(function($param){
+        if (count($params) == 0) return ['success' => false, 'message' => '参数异常'];
+        app('OrderService')->syncOrderByCodes(array_map(function ($param) {
             return $param['order_no'];
-        },$params));
-        return  $service->build($params);
+        }, $params));
+        return $this->service->build($params);
     }
 
     // 破损工单
-    public function damagedApi(WorkOrderRequest $request, WorkOrderService $service): array
+    public function damagedApi(WorkOrderRequest $request): array
     {
         if (Gate::denies('订单管理-订单-生成工单'))
             return ['success' => false, 'message' => '没有对应权限'];
-        app('OrderService')->syncOrderByCodes([$request->input('order_no')]);
 
-        $workOrder =  $service->createDamagedWorkOrder($request->all());
+        $this->orderService->syncOrderByCodes([$request->input('order_no')]);
+
+        $workOrder = $this->service->createDamagedWorkOrder($request->all());
 
         if ($workOrder) return ['success' => true];
-        else return  ['success' => false];
+        else return ['success' => false];
     }
 
     // 货主 遗失工单信息 填充
-    public function updateLossApi(Request $request, WorkOrderService $service): array
+    public function updateLossApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-货主编辑'))
             return ['success' => false, 'message' => '没有对应权限'];
 
-        /** @var WorkOrder $workOrder */
-        $workOrder = WorkOrder::query()->where('id',$request->input('id'))->first();
+        $workOrder = $this->service->find($request->input('id'));
 
-        if (!$workOrder) return ['success' => false,'message' => '参数异常'];
+        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
 
-        $workOrder = $service->fillLossWorkOrder($workOrder,$request->all());
+        $workOrder = $this->service->fillLossWorkOrder($workOrder, $request->all());
 
-        if(!$workOrder) return ['success' => false,'message' => '创建异常'];
+        if (!$workOrder) return ['success' => false, 'message' => '创建异常'];
 
         return ['success' => true, 'data' => $workOrder];
     }
@@ -110,35 +164,42 @@ class WorkOrderController extends Controller
     public function updateIssueTypeApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-审核'))
-            return ['success' => false,'message' => '没有对应权限'];
+            return ['success' => false, 'message' => '没有对应权限'];
+
+        WorkOrder::query()->where('id', $request['id'])->update(['order_issue_type_id' => $request['type_id']]);
 
-        WorkOrder::query()->where('id',$request['id'])->update(['order_issue_type_id' => $request['type_id']]);
         return ['success' => true];
     }
 
     // 批量修改问题件类型
-    public function batchUpdateIssueTypeApi(Request $request,WorkOrderService $service): array
+    public function batchUpdateIssueTypeApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-审核'))
-            return ['success' => false,'message' => '没有对应权限'];
-        WorkOrder::query()->whereIn('id',$request['ids'])->update(['order_issue_type_id' => $request['type']]);
-        $items = WorkOrder::query()->defaultWith()->whereIn('id',$request['ids'])->get();
-        $service->tags($items);
-        return ['success' => true,'data' => $items];
+            return ['success' => false, 'message' => '没有对应权限'];
+
+        WorkOrder::query()->whereIn('id', $request['ids'])->update(['order_issue_type_id' => $request['type']]);
+
+        $items = WorkOrder::query()->defaultWith()->whereIn('id', $request['ids'])->get();
+
+        $this->service->tags($items);
+
+        return ['success' => true, 'data' => $items];
     }
 
     // 删除
     public function destroyApi($id): array
     {
         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' => '对应工单已处理,拒绝删除'];
+            return ['success' => false, 'message' => '没有对应权限'];
+
+        $workOrder = $this->service->find($id);
+
+        if (!$workOrder)
+            return ['success' => false, 'message' => '对应工单信息未找到'];
+        if ($workOrder->status == '已处理') {
+            return ['success' => false, 'message' => '对应工单已处理,拒绝删除'];
         }
-        WorkOrder::query()->where('id',$id)->Delete();
+        WorkOrder::query()->where('id', $id)->Delete();
         return ['success' => true];
     }
 
@@ -146,41 +207,47 @@ class WorkOrderController extends Controller
     public function updateWorkOrderStatusApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-宝时编辑'))
-            return  ['success' => false,'message' => '没有对应权限'];
+            return ['success' => false, 'message' => '没有对应权限'];
         try {
-            $workOrder = WorkOrder::query()->find($request['id']);
+            $workOrder = $this->service->find($request->input('id'));
+
             $workOrder->work_order_status = $request['work_order_status'];
+
             $workOrder->update();
         } catch (\Exception $e) {
-            return ['success' => false,'message' => '编辑工单状态失败'];
+            return ['success' => false, 'message' => '编辑工单状态失败'];
         }
         return ['success' => true];
     }
 
     // 承运商处理工单状态
-    public function logisticUpdateWorkOrderStatusApi(Request $request):array
+    public function logisticUpdateWorkOrderStatusApi(Request $request): array
     {
         if (Gate::denies('订单管理-工单处理-承运商编辑'))
-            return  ['success' => false,'message' => '没有对应权限'];
+            return ['success' => false, 'message' => '没有对应权限'];
         try {
-            $workOrder = WorkOrder::query()->find($request['id']);
+            $workOrder = $this->service->find($request->input('id'));
+
             $workOrder->work_order_status = $request['work_order_status'];
+
             $workOrder->update();
         } catch (\Exception $e) {
-            return ['success' => false,'message' => '编辑工单状态失败'];
+            return ['success' => false, 'message' => '编辑工单状态失败'];
         }
-        return ['success'=> true];
+        return ['success' => true];
     }
 
-    public function ownerUpdateCommoditiesApi(Request $request,WorkOrderCommoditiesService  $commoditiesService): array
+    public function ownerUpdateCommoditiesApi(Request $request): array
     {
-        if (Gate::denies('订单管理-工单处理-货主编辑')){
-            return  ['success' => false,'message' => '没有对应权限'];
+        if (Gate::denies('订单管理-工单处理-货主编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
         }
-        /** @var WorkOrder $workOrder */
-        $workOrder = WorkOrder::query()->find($request->input('id'));
-        if (!$workOrder)return  ['success' => false,'message' => '参数异常'];
-        $commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder,$request->input('commodities'));
+
+        $workOrder = $this->service->find($request->input('id'));
+
+        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
+
+        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder, $request->input('commodities'));
 
         $workOrder->loadDefaultWith();
 
@@ -189,17 +256,16 @@ class WorkOrderController extends Controller
         return ['success' => true, 'data' => $workOrder];
     }
 
-    public function logisticUpdateCommoditiesApi(Request $request,WorkOrderCommoditiesService  $commoditiesService): array
+    public function logisticUpdateCommoditiesApi(Request $request): array
     {
-        if (Gate::denies('订单管理-工单处理-承运商编辑')){
-            return  ['success' => false,'message' => '没有对应权限'];
+        if (Gate::denies('订单管理-工单处理-承运商编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
         }
-        /** @var WorkOrder $workOrder */
-        $workOrder = WorkOrder::query()->find($request->input('id'));
+        $workOrder = $this->service->find($request->input('id'));
 
-        if (!$workOrder)return  ['success' => false,'message' => '参数异常'];
+        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
 
-        $commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder,$request->input('commodities'));
+        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder, $request->input('commodities'));
 
         $workOrder->loadDefaultWith();
 
@@ -208,20 +274,42 @@ class WorkOrderController extends Controller
         return ['success' => true, 'data' => $workOrder];
     }
 
-    public function logisticEndApi(Request $request,WorkOrderService  $service): array
+    public function baoShiUpdateCommoditiesApi(Request $request): array
+    {
+        if (Gate::denies('订单管理-工单处理-宝时编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
+        }
+        $workOrder = $this->service->find($request->input('id'));
+
+        if (!$workOrder) return ['success' => false, 'message' => '参数异常'];
+
+        $this->commoditiesService->updateWorkOrderCommoditiesByJsonArray($workOrder, $request->input('commodities'));
+
+        $workOrder->loadDefaultWith();
+
+        if (($workOrder->issueType->name ?? '') === '错漏发') {
+            $workOrder->changeStatus('完成');
+
+            $this->logService->createLog($workOrder, '完成', '错漏发完结');
+        }
+
+        return ['success' => true, 'data' => $workOrder];
+    }
+
+    public function logisticEndApi(Request $request): array
     {
-        if (Gate::denies('订单管理-工单处理-承运商编辑')){
-            return  ['success' => false,'message' => '没有对应权限'];
+        if (Gate::denies('订单管理-工单处理-承运商编辑')) {
+            return ['success' => false, 'message' => '没有对应权限'];
         }
+        $workOrder = $this->service->find($request->input('id'));
 
-        /** @var WorkOrder $workOrder */
-        $workOrder = WorkOrder::query()->find($request->input('id'));
-        if (!$workOrder) return  ['success' => false,'message' => '参数错误,刷新重试'];
-        $service->logisticEnd($workOrder);
+        if (!$workOrder) return ['success' => false, 'message' => '参数错误,刷新重试'];
+
+        $this->service->logisticEnd($workOrder);
 
         $workOrder->loadDefaultWith();
 
-        return ['success' => true,'data' => $workOrder];
+        return ['success' => true, 'data' => $workOrder];
     }
 
 }

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

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\WorkOrderLog;
+use Illuminate\Http\Request;
+
+class WorkOrderLogController 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\WorkOrderLog  $workOrderLog
+     * @return \Illuminate\Http\Response
+     */
+    public function show(WorkOrderLog $workOrderLog)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\WorkOrderLog  $workOrderLog
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(WorkOrderLog $workOrderLog)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\WorkOrderLog  $workOrderLog
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, WorkOrderLog $workOrderLog)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\WorkOrderLog  $workOrderLog
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(WorkOrderLog $workOrderLog)
+    {
+        //
+    }
+}

+ 4 - 0
app/Providers/AppServiceProvider.php

@@ -189,6 +189,8 @@ use App\Services\WorkOrderCommoditiesService;
 use App\Services\WorkOrderImageService;
 use App\Services\WorkOrderProcessLogService;
 use App\Services\LaborApplyService;
+use App\Services\WorkOrderLogService;
+use App\Services\OrderIssueTypeService;
 
 class AppServiceProvider extends ServiceProvider
 {
@@ -286,6 +288,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OrderIssueProcessLogService', OrderIssueProcessLogService::class);
         app()->singleton('OrderIssueRejectedBillService', OrderIssueRejectedBillService::class);
         app()->singleton('OrderIssueService', OrderIssueService::class);
+        app()->singleton('OrderIssueTypeService',OrderIssueTypeService::class);
         app()->singleton('OrderIssueWorkLoadService', OrderIssueWorkLoadService::class);
         app()->singleton('OrderPackageCommoditiesService', OrderPackageCommoditiesService::class);
         app()->singleton('OrderPackageCommoditySerialNumberService', OrderPackageCommoditySerialNumberService::class);
@@ -386,6 +389,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('WorkOrderCommoditiesService',WorkOrderCommoditiesService::class);
         app()->singleton('WorkOrderDetailService',WorkOrderDetailService::class);
         app()->singleton('WorkOrderImageService',WorkOrderImageService::class);
+        app()->singleton('WorkOrderLogService',WorkOrderLogService::class);
         app()->singleton('WorkOrderProcessLogService',WorkOrderProcessLogService::class);
         app()->singleton('WorkOrderService',WorkOrderService::class);
         app()->singleton('WorkOrderTypeService',WorkOrderTypeService::class);

+ 12 - 0
app/Services/OrderIssueTypeService.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\OrderIssueType;
+
+class OrderIssueTypeService
+{
+    use ServiceAppAop;
+    protected $modelClass=OrderIssueType::class;
+}

+ 18 - 0
app/Services/WorkOrderImageService.php

@@ -102,4 +102,22 @@ class WorkOrderImageService
         $workOrderImage = $workOrder->images()->create(['type' => 4, 'number' => ++$count]);
         $workOrderImage->saveFile($image);
     }
+
+
+    public function createImages($workOrder,$package_images = null,$commodity_images = null,$deal_images = null,$refund_images = null)
+    {
+        if ($package_images) $this->createWorkOrderPackageImages($workOrder,$package_images);
+        if ($commodity_images) $this->createWorkOrderCommodityImages($workOrder,$commodity_images);
+        if ($deal_images) $this->createWorkOrderDealImages($workOrder,$deal_images);
+        if ($refund_images) $this->createWorkOrderRefundImages($workOrder,$refund_images);
+    }
+
+    public function createWorkOrderImages($workOrder,$params)
+    {
+        $package_images=  $params['packageImages'] ?? [];
+        $commodity_images = $params['commodityImages'] ?? [];
+        $deal_images  = $params['dealImages'] ?? [];
+        $refund_images = $params['refundImages'] ?? [];
+        $this->createImages($workOrder,$package_images,$commodity_images,$deal_images,$refund_images);
+    }
 }

+ 29 - 0
app/Services/WorkOrderLogService.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Services;
+
+use App\Traits\ServiceAppAop;
+use App\WorkOrder;
+use App\WorkOrderLog;
+use Illuminate\Support\Facades\Auth;
+
+class WorkOrderLogService
+{
+    use ServiceAppAop;
+
+    protected $modelClass = WorkOrderLog::class;
+
+    public function createLog(WorkOrder $workOrder, $type, $content)
+    {
+        $user = Auth::user();
+
+        $log = new WorkOrderLog([
+            'work_order_id' => $workOrder->id,
+            'type' => $type,
+            'creator_id' => $user['id'] ?? '',
+            'content' => $content
+        ]);
+        $log->save();
+    }
+
+}

+ 125 - 46
app/Services/WorkOrderService.php

@@ -8,6 +8,7 @@ use App\OrderIssueType;
 use App\OrderPackage;
 use App\Traits\ServiceAppAop;
 use App\WorkOrder;
+use App\WorkOrderProcessLog;
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Support\Carbon;
@@ -20,6 +21,36 @@ class WorkOrderService
 
     protected $modelClass = WorkOrder::class;
 
+    /**
+     * @var WorkOrderLogService  $logService
+     * @var WorkOrderImageService  $imageService
+     * @var WorkOrderCommoditiesService  $commoditiesService
+     * @var WorkOrderDetailService $detailService
+     * @var OrderIssueTypeService $issueTypeService
+     * @var OrderService $orderService
+     */
+    private $logService;
+    private $imageService;
+    private $commoditiesService;
+    private $detailService;
+    private $issueTypeService;
+    private $orderService;
+
+    public function __construct(WorkOrderLogService $logService,
+                                WorkOrderImageService $imageService,
+                                WorkOrderCommoditiesService $commoditiesService,
+                                WorkOrderDetailService $detailService,
+                                OrderIssueTypeService $issueTypeService,
+                                OrderService $orderService)
+    {
+        $this->logService = $logService;
+        $this->imageService = $imageService;
+        $this->commoditiesService = $commoditiesService;
+        $this->detailService = $detailService;
+        $this->issueTypeService = $issueTypeService;
+        $this->orderService = $orderService;
+    }
+
     /**
      * 获取可生成工单的问题件类型
      * @return Builder[]|Collection
@@ -29,7 +60,7 @@ class WorkOrderService
         if (Gate::allows('订单管理-工单处理-客服编辑') || Gate::allows('订单管理-工单处理-货主编辑')) {
             return OrderIssueType::query()->whereIn('name', ['拦截', '信息更改', '其他', '快递异常', '错漏发', '破损', '快递丢件'])->get();
         } else if (Gate::allows('订单管理-工单处理-承运商编辑')) {
-            return OrderIssueType::query()->whereIn('name', ['拦截', '信息更改', '破损', '快递丢件'])->get();
+            return OrderIssueType::query()->whereIn('name', ['拦截', '信息更改', '破损', '快递丢件','快递异常'])->get();
         }
         return OrderIssueType::query()->whereIn('name', ['拦截', '信息更改', '其他', '快递异常', '错漏发', '破损', '快递丢件'])->get();
     }
@@ -62,22 +93,30 @@ class WorkOrderService
         return ['success' => true];
     }
 
-    public function createAndNotification($order, $orderIssueType, $remark): WorkOrder
+    public function createWorkOrder($order, $issueType, $remark)
     {
         $user = Auth::user();
-        /** @var WorkOrder $workOrder */
-        $workOrder = WorkOrder::query()->create([
+
+        return WorkOrder::query()->create([
             'order_id' => $order->id,
             'logistic_id' => $order->logistic_id ?? '',
             'owner_id' => $order->owner_id ?? '',
-            'creator_id' => $user["id"],
+            'creator_id' => $user['id'] ?? '',
             'remark' => $remark,
             'outer_table_name' => 'orders',
-            'order_issue_type_id' => $orderIssueType->id,
+            'order_issue_type_id' => $issueType->id,
             'uniquely_tag' => $order->code,
             'status' => 0,
         ]);
+    }
+
+    public function createAndNotification($order, $orderIssueType, $remark): WorkOrder
+    {
+        /** @var WorkOrder $workOrder */
+        $workOrder = $this->createWorkOrder($order, $orderIssueType, $remark);
+
         $workOrder->notification();
+
         return $workOrder;
     }
 
@@ -86,10 +125,19 @@ class WorkOrderService
      */
     public function createInterceptWorkOrder($param): WorkOrder
     {
-        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '拦截']);
-        $order = Order::query()->where('code', $param['order_no'])->first();
+        $issueType = $this->issueTypeService->firstOrCreate(['name' => '拦截']);
+
+        $order = $this->orderService->first(['code'=> $param['order_no']]);
+
         $remark = $param['remark'] ?? '拦截工单';
-        return $this->createAndNotification($order, $orderIssueType, $remark);
+
+        $workOrder = $this->createAndNotification($order, $issueType, $remark);
+
+        $workOrder->changeStatus('承运商处理');
+
+        $this->logService->createLog($workOrder,'创建','创建');
+
+        return $workOrder;
     }
 
     /**
@@ -97,10 +145,17 @@ class WorkOrderService
      */
     public function createMistakeWorkOrder($param): WorkOrder
     {
-        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '错漏发']);
-        $order = Order::query()->where('code', $param['order_no'])->first();
+        $issueType = $this->issueTypeService->firstOrCreate(['name' => '错漏发']);
+
+        $order = $this->orderService->first(['code'=> $param['order_no']]);
+
         $remark = $param['remark'] ?? '';
-        return $this->createAndNotification($order, $orderIssueType, $remark);
+
+        $workOrder = $this->createAndNotification($order, $issueType, $remark);
+
+        $workOrder->changeStatus('宝时处理');
+
+        return $workOrder;
     }
 
     /**
@@ -108,28 +163,22 @@ class WorkOrderService
      */
     public function createDamagedWorkOrder($param): WorkOrder
     {
-        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '破损']);
-
-        $order = Order::query()->where('code', $param['order_no'])->first();
-
-        $remark = $param['remark'] ?? '';
+        $issueType = $this->issueTypeService->firstOrCreate(['name' => '破损']);
 
-        $workOrder = $this->createAndNotification($order, $orderIssueType, $remark);
+        $order = $this->orderService->first(['code'=> $param['order_no']]);
 
-        $imageService = app('WorkOrderImageService');
+        $workOrder = $this->createAndNotification($order, $issueType, $param['remark'] ?? '');
 
-        $imageService->createWorkOrderPackageImages($workOrder, $param['packageImages']);
+        $this->imageService->createWorkOrderImages($workOrder,$param);
 
-        $imageService->createWorkOrderCommodityImages($workOrder, $param['commodityImages']);
+        $this->detailService->createWorkOrderDetail($workOrder, $param);
 
-        $imageService->createWorkOrderDealImages($workOrder, $param['dealImages']);
-
-        app('WorkOrderDetailService')->createWorkOrderDetail($workOrder, $param);
-
-        app('WorkOrderCommoditiesService')->createWorkOrderCommoditiesByJsonArray($workOrder, $param['commodities']); // 登记商品信息
+        $this->commoditiesService->createWorkOrderCommoditiesByJsonArray($workOrder, $param['commodities']); // 登记商品信息
 
         $workOrder->changeStatus('承运商处理');
 
+        $this->logService->createLog($workOrder,'创建','创建工单');
+
         return $workOrder;
     }
 
@@ -138,11 +187,16 @@ class WorkOrderService
      */
     public function createExpressAbnormalWorkOrder($param): WorkOrder
     {
-        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '快递异常']);
-        $order = Order::query()->where('code', $param['order_no'])->first();
-        $remark = $param['remark'] ?? '';
-        $workOrder =  $this->createAndNotification($order, $orderIssueType, $remark);
+        $order = $this->orderService->first(['code'=> $param['order_no']]);
+
+        $issueType = $this->issueTypeService->firstOrCreate(['name' => '快递异常']);
+
+        $workOrder =  $this->createAndNotification($order, $issueType, $param['remark'] ?? '');
+
         $workOrder->changeStatus('承运商处理');
+
+        $this->logService->createLog($workOrder,'创建','创建工单');
+
         return $workOrder;
     }
 
@@ -151,14 +205,16 @@ class WorkOrderService
      */
     public function createInformationChangeWorkOrder($param): WorkOrder
     {
-        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '信息更改']);
-        $order = Order::query()->where('code', $param['order_no'])->first();
-        $remark = $param['remark'] ?? '';
+        $issueType = $this->issueTypeService->firstOrCreate(['name' => '信息更改']);
 
-        $workOrder = $this->createAndNotification($order, $orderIssueType, $remark);
+        $order = $this->orderService->first(['code'=> $param['order_no']]);
+
+        $workOrder = $this->createAndNotification($order, $issueType, $param['remark'] ?? '');
 
         $workOrder->changeStatus('承运商处理');
 
+        $this->logService->createLog($workOrder,'创建','创建工单');
+
         return $workOrder;
     }
 
@@ -167,10 +223,11 @@ class WorkOrderService
      */
     public function createDefaultWorkOrder($param): WorkOrder
     {
-        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '其他']);
-        $order = Order::query()->where('code', $param['order_no'])->first();
-        $remark = $param['remark'] ?? '';
-        return $this->createAndNotification($order, $orderIssueType, $remark);
+        $orderIssueType = $this->issueTypeService->firstOrCreate(['name' => '其他']);
+
+        $order = $this->orderService->first(['code'=> $param['order_no']]);
+
+        return $this->createAndNotification($order, $orderIssueType, $param['remark'] ?? '');
     }
 
     /**
@@ -178,13 +235,16 @@ class WorkOrderService
      */
     public function createLossWorkOrder($param): WorkOrder
     {
-        $orderIssueType = OrderIssueType::query()->firstOrCreate(['name' => '快递丢件']);
-        $order = Order::query()->where('code', $param['order_no'])->first();
-        $remark = $param['remark'] ?? '';
-        $workOrder = $this->createAndNotification($order, $orderIssueType, $remark);
+        $orderIssueType = $this->issueTypeService->firstOrCreate(['name' => '快递丢件']);
+
+        $order = $this->orderService->first(['code'=> $param['order_no']]);
+
+        $workOrder = $this->createAndNotification($order, $orderIssueType, $param['remark'] ?? '');
 
         $workOrder->changeStatus('货主处理');
 
+        $this->logService->createLog($workOrder,'创建','创建工单');
+
         return $workOrder;
     }
 
@@ -194,18 +254,34 @@ class WorkOrderService
     public function fillLossWorkOrder(WorkOrder $workOrder, $param): WorkOrder
     {
         $workOrder->saveWorkOrderDetail($param);        // 收方信息 丢件价值 补发单号
-        /** @var WorkOrderImageService $imageService */
-        $imageService = app(WorkOrderImageService::class);
-        $imageService->createWorkOrderDealImages($workOrder,$param['dealImages']);
-        $imageService->createWorkOrderPackageImages($workOrder,$param['dealImages'] ?? []);
+
+        $this->imageService->createWorkOrderImages($workOrder,$param);
+
         $workOrder->changeStatus(['承运商处理']);
+
+        $this->logService->createLog($workOrder,'处理','填充丢件信息');
+
         return $workOrder;
     }
 
+    public function end(WorkOrder $workOrder)
+    {
+        $workOrder->end();
+
+        $this->logService->createLog($workOrder,'完结','完结工单');
+    }
 
     public function logisticEnd(WorkOrder $workOrder)
     {
         $workOrder->changeStatus('完成');
+        $this->logService->createLog($workOrder,'完结','承运商完结工单');
+    }
+
+    public function find($id):WorkOrder
+    {
+        /** @var WorkOrder $item */
+        $item = WorkOrder::query()->where('id',$id)->first();
+        return $item;
     }
 
 
@@ -217,8 +293,11 @@ class WorkOrderService
     public function review($wordOrder): array
     {
         $wordOrder->update(['reviewer_id' => Auth::user()['id'], 'review_at' => Carbon::now(), 'status' => '2',]);
+
         $workOrders = WorkOrder::query()->defaultWith()->whereIn('id', [$wordOrder['id']])->get();
+
         $this->tags($workOrders);
+
         return ['success' => true, 'data' => $workOrders->first()];
     }
 

+ 9 - 5
app/WorkOrder.php

@@ -35,7 +35,7 @@ class WorkOrder extends Model
         'order_id',             // 订单id
         'uniquely_tag',         // 唯一标识
 //        'grad',         // 紧急等级
-//        'remark',       // 工单信息描述
+        'remark',       // 工单信息描述
 //        'outer_table_name',     // 链接表名
 //        'work_order_status', // 工单状态
     ];
@@ -223,16 +223,20 @@ class WorkOrder extends Model
         return $this->processLogs->where('type', 2);
     }
 
+    public function logs(): HasMany
+    {
+        return $this->hasMany(WorkOrderLog::class);
+    }
+
     public function scopeFilter($query, $filters)
     {
         return $filters->apply($query);
     }
 
-
     /** 默认 with 参数 */
     public function scopeDefaultWith($query)
     {
-        $query->with(['type', 'owner', 'logistic', 'issueType', 'creator', 'details', 'commodities.commodity',
+        $query->with(['type', 'owner', 'logistic', 'issueType', 'creator', 'details', 'commodities.commodity','logs.creator',
             'processLogs.creator',
             'images.uploadFile',
             'reviewer',
@@ -251,7 +255,7 @@ class WorkOrder extends Model
 
     public function loadDefaultWith()
     {
-        $this->loadMissing(['type', 'owner', 'logistic', 'issueType', 'creator', 'details', 'commodities.commodity',
+        $this->loadMissing(['type', 'owner', 'logistic', 'issueType', 'creator', 'details', 'commodities.commodity','logs.creator',
             'processLogs.creator',
             'images.uploadFile',
             'reviewer',
@@ -289,7 +293,7 @@ class WorkOrder extends Model
     // 工单完结
     public function end()
     {
-        $this->update(['ststus'  => 4]);
+        $this->update(['status'  => 4]);
     }
 
     public function changeStatus($status)

+ 60 - 0
app/WorkOrderLog.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class WorkOrderLog extends Model
+{
+//    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    protected $fillable = ['work_order_id','content','type','creator_id'];
+
+    static public $enums = [
+        'type' => [
+            '' => 0,
+            '创建' => 1,
+            '处理' => 2,
+            '完结' => 3,
+        ],
+    ];
+
+    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 workOrder(): BelongsTo
+    {
+        return $this->belongsTo(WorkOrder::class);
+    }
+
+    public function creator(): BelongsTo
+    {
+        return $this->belongsTo(User::class);
+    }
+}

+ 12 - 0
database/factories/WorkOrderLogFactory.php

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

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

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateWorkOrderLogsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('work_order_logs', function (Blueprint $table) {
+            $table->id();
+            $table->integer('work_order_id')->index()->comment('工单');
+            $table->string('content')->comment('详情');
+            $table->integer('type')->comment('类型');
+            $table->integer('creator_id')->comment('创建人');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('work_order_logs');
+    }
+}

+ 16 - 0
database/seeds/WorkOrderLogSeeder.php

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

+ 9 - 7
resources/views/order/index/_work_order_modal.blade.php

@@ -53,7 +53,7 @@
                 {{--信息更改--}}
                 <div class="form-group row" v-if="'信息更改' === workOrder.orderIssueType ">
                     <hr>
-                    <label for="order_issue_type" class="col-sm-2 col-form-label">新的收方信息</label>
+                    <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="5"
                                   v-model="workOrder.remark.info"></textarea>
@@ -126,8 +126,8 @@
                     </div>
                 </div>
 
-                <hr v-if="'破损' === workOrder.orderIssueType">
-                <div class="form-group row" v-if="'破损' === workOrder.orderIssueType">
+                <hr v-if="['破损','快递丢件','错漏发','快递异常'].includes(workOrder.orderIssueType)">
+                <div class="form-group row" v-if="['破损','快递丢件','错漏发','快递异常'].includes(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">
@@ -144,12 +144,14 @@
                             </tr>
                             </thead>
                             <tbody>
-                            <tr v-for="(commodity,i) in workOrder.commodities">
+                            <tr v-for="(commodity,i) in workOrder.commodities" class="text-center">
                                 <td><span v-text="commodity.logistic_number"></span></td>
                                 <td><span v-text="commodity.sku"></span></td>
                                 <td>
-                                    <span v-text="commodity.sku" :data="commodity.abnormal_type = '破损'">破损</span>
-                                    <span v-text="commodity.sku" :data="commodity.abnormal_type = '错漏发'">错漏发</span>
+                                    <span v-if="workOrder.orderIssueType === '破损'"
+                                          :data="commodity.abnormal_type = '破损'" >破损</span>
+                                    <span v-if="workOrder.orderIssueType === '错漏发'"
+                                          :data="commodity.abnormal_type = '错漏发'"  >错漏发</span>
                                 </td>
                                 <td><span v-text="commodity.name"></span></td>
                                 <td><span v-text="commodity.amount"></span></td>
@@ -158,7 +160,7 @@
                                 </td>
                                 <td>
                                     <button type="button" class="close" @click="workOrder.commodities.splice(i,1)">
-                                        <span aria-hidden="true">&times;</span>
+                                        <span aria-hidden="true" class="text-danger">&times;</span>
                                     </button>
                                 </td>
                             </tr>

+ 16 - 9
resources/views/order/workOrder/_baoshi_fill_work_order.blade.php

@@ -1,10 +1,10 @@
 {{--快递处理丢件工单--}}
-<div class="modal fade " id="logistic-fill-work-order-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
+<div class="modal fade " id="baoshi-fill-work-order-modal" tabindex="-1" role="dialog" aria-labelledby="checkModalLabel"
      aria-hidden="true">
     <div class="modal-dialog modal-xl modal-dialog-centered">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title" id="logistic-work-order-modal">丢件工单</h5>
+                <h5 class="modal-title" id="baoshi-work-order-modal">丢件工单</h5>
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                     <span aria-hidden="true">&times;</span>
                 </button>
@@ -20,11 +20,11 @@
                             <td>订单数量</td>
                             <td>异常数量</td>
                             <td>核实数量</td>
-                            <td v-if="fillWorkOrder && (fillWorkOrder.issue_type_name === '错漏发')">核实结果</td>
+                            <td>核实结果</td>
                             <td>处理结果</td>
                         </tr>
                         </thead>
-                        <tbody>
+                        <tbody v-if="fillWorkOrder">
                         <tr v-for="(item) in fillWorkOrder?.commodities || [] ">
                             <td>
                                 <span v-text="item.logistic_number"></span>
@@ -45,16 +45,23 @@
                                 <input type="number" class="form-control form-control-sm" v-model="item.check_amount">
                             </td>
                             <td>
-                                <select class="form-control form-control-sm" v-model="item.check_result" v-if=" fillWorkOrder && (fillWorkOrder.issue_type_name === '错漏发')">
-                                    <option v-for="type in ['核实少发','核实多发','核实未错漏发']" :value="type" v-text="type"></option>
+                                <select class="form-control form-control-sm"
+                                        v-if="fillWorkOrder.issue_type_name === '破损'"
+                                        v-model="item.check_result" >
+                                    <option v-for="type in ['核实破损','核实未破损']"
+                                            :value="type" v-text="type"></option>
                                 </select>
 
-                                <select name="" id=""></select>
+                                <select class="form-control form-control-sm"
+                                        v-if="['快递异常','快递丢件'].includes(fillWorkOrder.issue_type_name)"
+                                        v-model="item.check_result" >
+                                    <option v-for="type in ['已拦截']" :value="type" v-text="type"></option>
+                                </select>
                             </td>
                             <td>
                                 <select class="form-control form-control-sm" v-model="item.process_result">
                                     <option
-                                        v-for="type in (['少发','多发','多发,客户退回','少发,不补发','核实未错漏发'])"
+                                        v-for="type in (['赔偿','不赔偿'])"
                                         :value="type" v-text="type"></option>
                                 </select>
                             </td>
@@ -65,7 +72,7 @@
             </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="logisticUpdateCommodities">提交</button>
+                <button type="button" class="btn btn-outline-primary" @click="baoShiUpdateCommodities">提交</button>
             </div>
         </div>
     </div>

+ 8 - 4
resources/views/order/workOrder/_logistic_fill_work_order.blade.php

@@ -4,7 +4,10 @@
     <div class="modal-dialog modal-xl modal-dialog-centered">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title" id="logistic-work-order-modal">丢件工单</h5>
+                <h5 class="modal-title" id="logistic-work-order-modal" v-if="fillWorkOrder">
+                    <span v-text="fillWorkOrder.issue_type_name + '工单'">
+                    </span>
+                </h5>
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                     <span aria-hidden="true">&times;</span>
                 </button>
@@ -20,7 +23,7 @@
                             <td>订单数量</td>
                             <td>异常数量</td>
                             <td>核实数量</td>
-                            <td >核实结果</td>
+                            <td>核实结果</td>
                             <td>处理结果</td>
                         </tr>
                         </thead>
@@ -44,11 +47,12 @@
                             <td>
                                 <input type="number" class="form-control form-control-sm" v-model="item.check_amount">
                             </td>
-                            <td >
+                            <td>
                                 <select class="form-control form-control-sm"
                                         v-if="fillWorkOrder.issue_type_name === '破损'"
                                         v-model="item.check_result" >
-                                    <option v-for="type in ['核实破损','核实未破损']" :value="type" v-text="type"></option>
+                                    <option v-for="type in ['核实破损','核实未破损']"
+                                            :value="type" v-text="type"></option>
                                 </select>
 
                                 <select class="form-control form-control-sm"

+ 168 - 160
resources/views/order/workOrder/_work_order_details.blade.php

@@ -1,4 +1,4 @@
-<div v-if="item.details.length > 0" class="alert alert-light mb-0">
+<div class="alert alert-light mb-0">
     <div class="header-alert">
         <span class="text-monospace">工单详情</span>
         <button type="button" class="btn btn-sm btn-outline-primary float-right"
@@ -10,172 +10,180 @@
                 @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 ?.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>
+<transition name="fade">
+    <div class="alert alert-light mb-0 border border-top"
+         v-if="item.details && item.details.lenght > 0 && selectDetailId === item.id"
+         v-show="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 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>
+                    <span class="mr-3">丢件价值:</span>
+                    <span class="text-truncate"
+                          v-text="detail.price"></span>
                 </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 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 ?.name || ''"></span>
+                    <span class="mr-2">数量</span>
+                    <span v-text="item.amount"></span>
                 </div>
             </div>
+        </div>
+    </div>
+</transition>
+<transition name="fade">
+    <div class="alert alert-light mb-0 border border-top"
+         v-show="selectDetailId === item.id"
+         v-if="item.deal_images && item.deal_images.length > 0">
+        <div class="col-12">
+            <span class="text-monospace" v-text="'交易截图'"></span>
+        </div>
+        <div class="card-body col-sm-6"
+             v-for="(dealImage,i) in item.deal_images">
+            <div class="">
+                <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>
+</transition>
 
-            {{-- 破损商品详情 --}}
-            <div class="row">
-                <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 ?.name || '' "></span>
-                    </div>
-                    <div>
-                        <span class="mr-3">数量:</span>
-                        <span class="text-truncate"
-                              v-text="commodity.amount"></span>
-                    </div>
-                    <div>
-                        <span class="mr-3">异常:</span>
-                        <span class="text-truncate"
-                              v-text="commodity.abnormal_type"></span>
-                    </div>
+<transition name="fade">
+    <div class="alert alert-light mb-0 border border-top"
+         v-show="selectDetailId === item.id"
+         v-if="item.refund_image && item.refund_image.length > 0">
+        <div class="col-12">
+           <span class="text-monospace" v-text="'交易截图'"></span>
+        </div>
+        <div class="card-body col-sm-6"
+             v-for="(refund_image,i) in item.refund_image">
+            <div class="">
+                <a  target="_blank"
+                    v-if="dealImage.upload_file"
+                    :href="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type">
+                    <img class="image-w"
+                         :src="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type"
+                         alt="交易截图">
+                </a>
+            </div>
+        </div>
+    </div>
+</transition>
 
-                    <div>
-                        <span class="mr-3">核实:</span>
-                        <span class="text-truncate"
-                              v-text="commodity.abnormal_type"></span>
-                    </div>
+<transition name="fade">
+    <div class="alert alert-light mb-0 border border-top"
+         v-show="selectDetailId === item.id"
+         v-if="item.refund_image && item.refund_image.length > 0">
+        <div class="col-12">
+           <span class="text-monospace" v-text="'交易截图'"></span>
+        </div>
+        <div class="card-body col-sm-6"
+             v-for="(refund_image,i) in item.refund_image">
+            <div class="">
+                <a  target="_blank"
+                    v-if="dealImage.upload_file"
+                    :href="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type">
+                    <img class="image-w"
+                         :src="filePrefix+refund_image.upload_file.url + '.'+refund_image.upload_file.type"
+                         alt="交易截图">
+                </a>
+            </div>
+        </div>
+    </div>
+</transition>
+
+<transition name="fade">
+    <div class="alert alert-light mb-0  border border-top"
+         v-show="selectDetailId === item.id"
+         v-if="item['package_images'] && item['package_images'].length > 0">
+        <div class="col-12">
+           <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>
+</transition>
 
-                    <div>
-                        <span class="mr-3">处理结果</span>
-                        <span class="text-truncate"
-                              v-text="commodity.abnormal_type"></span>
-                    </div>
+<transition name="fade">
+    <div class="alert alert-light mb-0 border border-top"
+         v-show="selectDetailId === item.id"
+         v-if="item['commodity_images'] && item['commodity_images'].length > 0">
+        <div class="col-12">
+           <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>
+</transition>
+<transition name="fade">
+    {{-- 破损商品详情 --}}
+    <div class="alert alert-light mb-0  border border-top"
+        v-show="selectDetailId === item.id"
+        v-if="item.commodities && item.commodities.length > 0">
 
-                </div>
+        <div class="col-12">
+           <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 ?.name || '' "></span>
+            </div>
+            <div>
+                <span class="mr-3">数量:</span>
+                <span class="text-truncate"
+                      v-text="commodity.amount"></span>
+            </div>
+
+            <div>
+                <span class="mr-3">核实:</span>
+                <span class="text-truncate"
+                      v-text="commodity.check_result"></span>
+            </div>
+
+            <div>
+                <span class="mr-3">处理结果</span>
+                <span class="text-truncate"
+                      v-text="commodity.process_result"></span>
             </div>
         </div>
-    </transition>
-</div>
+    </div>
+</transition>

+ 93 - 36
resources/views/order/workOrder/index.blade.php

@@ -68,28 +68,28 @@
                                                 @click="logisticFillWorkOrder(item,i)">
                                             快递处理
                                         </button>
-                                            <button class="btn btn-sm btn-outline-primary"
+                                        <button class="btn btn-sm btn-outline-primary"
                                                 v-if="['拦截','信息更改'].includes(item.issue_type_name) && item.status ==='承运商处理'"
                                                 @click="logisticEndWorkOrder(item,i)">
-                                                快递处理
-                                            </button>
+                                            快递处理
+                                        </button>
                                     @endcan
                                     @can('订单管理-工单处理-宝时编辑')
                                         <button class="btn btn-sm btn-outline-primary"
-                                                v-if="['错漏发'].includes(item.issue_type_name) && item.status ==='宝时处理'">
+                                                v-if="['错漏发'].includes(item.issue_type_name) && item.status ==='宝时处理'"
+                                            @click="baoShiFillWorkOrder(item,i)">
                                             宝时处理
                                         </button>
                                         <button class="btn btn-sm btn-outline-secondary"
                                                 v-if="['快递丢件','破损'].includes(item.issue_type_name) && item.status ==='宝时处理'"
-                                                @click="showEditLog(item,i,1)">
+                                                @click="baoShiFillWorkOrder(item,i)">
                                             宝时处理
                                         </button>
 
-                                        <button class="btn btn-sm btn-outline-secondary"
-                                                v-if="['快递丢件','破损'].includes(item.issue_type_name)"
-                                        >
-                                            宝时处理
-                                        </button>
+{{--                                        <button class="btn btn-sm btn-outline-secondary"--}}
+{{--                                                v-if="['快递丢件','破损'].includes(item.issue_type_name)">--}}
+{{--                                            宝时处理--}}
+{{--                                        </button>--}}
 
                                     @endcan
                                 </td>
@@ -141,26 +141,51 @@
                                 <td class="container">
                                     <div class="row">
                                         @can('订单管理-工单处理-删除')
-                                            <div class="col-2 m-0 p-0">
-                                                <div class="alert alert-light mb-0">
-                                                    <div class="header-alert">
-                                                        <span class="text-monospace">&nbsp;</span>
-                                                        <button type="button"
-                                                                class="btn btn-sm btn-outline-danger float-left">
-                                                            删除
-                                                        </button>
-                                                    </div>
+                                            <div class="col-1 ">
+                                                <div class="header-alert">
+                                                    <button type="button"
+                                                            class="btn btn-sm btn-outline-danger" @click="destroy(item)">
+                                                        删除
+                                                    </button>
                                                 </div>
                                             </div>
                                         @endcan
                                         <div class="col-6 m-0 ">
                                             @include('order.workOrder._work_order_details')
                                         </div>
-                                        <div @can('订单管理-工单处理-删除') class="col-4 p-0"
+                                        <div @can('订单管理-工单处理-删除') class="col-5 m-0"
                                              @else class="col-6 p-0" @endcan>
                                             <div class="alert alert-light mb-0">
-                                                <span class="text-monospace">处理日志</span>
+                                                <button type="button" class="btn btn-sm btn-outline-primary float-left"
+                                                        v-show="selectLog !== item.id && item.logs && item.logs.length > 0"
+                                                        @click="selectLog=item.id">
+                                                    显示
+                                                </button>
+                                                <button type="button" class="btn btn-sm btn-outline-primary float-left"
+                                                        v-show="selectLog === item.id && item.logs && item.logs.length > 0"
+                                                        @click="selectLog=null">
+                                                    收起
+                                                </button>
+                                                <span>&nbsp;</span>
                                             </div>
+                                            <transition-group name="fade">
+                                                <div class="alert alert-light mb-0  border-top"
+                                                     v-show="selectLog === item.id"
+                                                     v-for="(log,index) in item.logs" v-bind:key="item.id+':'+index">
+                                                    <div>
+                                                        <span class="text-monospace">创建人:</span>
+                                                        <span v-text="log?.creator?.name"></span>
+                                                    </div>
+                                                    <div>
+                                                        <span class="text-monospace">创建时间:</span>
+                                                        <span v-text="log.created_at"></span>
+                                                    </div>
+                                                    <div>
+                                                        <span class="text-monospace">内容:</span>
+                                                        <span v-text="log.content"></span>
+                                                    </div>
+                                                </div>
+                                            </transition-group>
                                         </div>
                                     </div>
 
@@ -257,6 +282,7 @@
                 selectDetailId: null,
                 selectOrderIssue: null,
                 selectIssueType: '',
+                selectLog: null,
                 selectIndex: null,  // 选中工单
                 filePrefix: "{{asset("/storage")}}",
             },
@@ -330,16 +356,16 @@
                             @endcan
                         ], 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},
-                        @can('订单管理-工单处理-删除')
-                    {
-                        name: 'delete_operation', value: '其他操作', neglect: true
-                    }
-                    @endcan
+                    {{--{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},--}}
+                    {{--    @can('订单管理-工单处理-删除')--}}
+                    {{--{--}}
+                    {{--    name: 'delete_operation', value: '其他操作', neglect: true--}}
+                    {{--}--}}
+                    {{--@endcan--}}
                 ];
                 new Header({
                     el: "table",
@@ -367,6 +393,7 @@
             },
             methods: {
                 filterItem(items, name, value) {
+                    console.log(items);
                     return items.filter(item => {
                         return item[name].toString() === value.toString();
                     })
@@ -911,12 +938,15 @@
                     this.fillWorkOrder.commodities.forEach(e => {
                         formData.append("commodities[]", JSON.stringify(e));
                     });
+                    window.tempTip.setIndex(1999);
                     window.axios.post(url, formData, {'Content-Type': 'multipart/form-data'})
                         .then(res => {
                             if (res.data.success) {
                                 this.sortOrder(res.data.data);
                                 this.$set(this.workOrders, this.selectIndex, res.data.data);
                                 window.tempTip.showSuccess('修改成功');
+                                $("#logistic-fill-work-order-modal").modal('hide');
+
                             } else {
                                 window.tempTip.show(res.data?.message || '');
                             }
@@ -925,20 +955,47 @@
                     })
 
                 },
-                logisticEndWorkOrder(item,index){
+                logisticEndWorkOrder(item, index) {
                     // 拦截,信息更改的工单处理
                     let url = "{{route("workOrder.logistic.endApi")}}";
-                    window.axios.post(url,{id:item.id}).then(res=>{
-                        if (res.data.success){
+                    window.axios.post(url, {id: item.id}).then(res => {
+                        if (res.data.success) {
                             window.tempTip.showSuccess('工单已处理');
                             this.sortOrder(res.data.data);
-                            this.$set(this.workOrders,index,res.data.data);
+                            this.$set(this.workOrders, index, res.data.data);
                         } else {
                             window.tempTip.show(res.data?.message || '工单处理异常刷新后重试');
                         }
-                    }).catch(err=>{
+                    }).catch(err => {
                         window.tempTip.show(err || '工单处理异常刷新后重试');
                     });
+                },
+                baoShiFillWorkOrder(item,index){
+                    this.fillWorkOrder = JSON.parse(JSON.stringify(item));
+                    this.selectIndex = index;
+                    $('#baoshi-fill-work-order-modal').modal('show');
+                },
+                baoShiUpdateCommodities(){
+                    let url = "{{route("workOrder.commodity.baoShiUpdateCommodities")}}";
+                    let formData = new FormData();
+                    formData.append('id', this.fillWorkOrder.id);
+                    this.fillWorkOrder.commodities.forEach(e => {
+                        formData.append("commodities[]", JSON.stringify(e));
+                    });
+                    window.tempTip.setIndex(1999);
+                    window.axios.post(url, formData, {'Content-Type': 'multipart/form-data'})
+                        .then(res => {
+                            if (res.data.success) {
+                                this.sortOrder(res.data.data);
+                                this.$set(this.workOrders, this.selectIndex, res.data.data);
+                                window.tempTip.showSuccess('修改成功');
+                                $("#baoshi-fill-work-order-modal").modal('hide');
+                            } else {
+                                window.tempTip.show(res.data?.message || '');
+                            }
+                        }).catch(err => {
+                        window.tempTip.show(err);
+                    })
                 }
             },
         });

+ 3 - 2
routes/apiLocal.php

@@ -287,8 +287,9 @@ Route::prefix('workOrder')->group(function(){
 
     Route::post('logistic/end',"WorkOrderController@logisticEndApi")->name('workOrder.logistic.endApi');
     Route::prefix('commodity')->group(function(){
-        Route::post("updateCommodities","WorkOrderController@ownerUpdateCommoditiesApi")->name("workOrder.commodity.ownerUpdateApi");
-        Route::post("updateCommodities","WorkOrderController@ownerUpdateCommoditiesApi")->name("workOrder.commodity.logisticUpdateApi");
+        Route::post("updateCommodities/owner","WorkOrderController@ownerUpdateCommoditiesApi")->name("workOrder.commodity.ownerUpdateApi");
+        Route::post("updateCommodities/logistic","WorkOrderController@logisticUpdateCommoditiesApi")->name("workOrder.commodity.logisticUpdateApi");
+        Route::post("updateCommodities/baoshi","WorkOrderController@baoShiUpdateCommoditiesApi")->name("workOrder.commodity.baoShiUpdateCommodities");
     });
 
     Route::prefix('process')->group(function (){