Explorar el Código

问题件导出事故责任方和项目责任方合并为一个字段

haozi hace 5 años
padre
commit
4a7d6a59b4
Se han modificado 72 ficheros con 2988 adiciones y 299 borrados
  1. 57 0
      app/DischargeTask.php
  2. 16 0
      app/Facilitator.php
  3. 107 0
      app/Filters/DischargeTaskFilters.php
  4. 7 3
      app/Filters/OrderIssueFilters.php
  5. 148 0
      app/Http/Controllers/DischargeTaskController.php
  6. 110 0
      app/Http/Controllers/FacilitatorController.php
  7. 1 1
      app/Http/Controllers/HomeController.php
  8. 23 20
      app/Http/Controllers/OrderIssueController.php
  9. 24 3
      app/Http/Controllers/OrderIssueProcessLogController.php
  10. 27 27
      app/Http/Controllers/WaybillController.php
  11. 1 1
      app/Http/Controllers/WaybillFinancialExceptedController.php
  12. 1 1
      app/Http/Controllers/WaybillFinancialSnapshotsController.php
  13. 110 0
      app/Http/Requests/DischargeTask/DischargeTaskRequest.php
  14. 74 0
      app/Http/Requests/DischargeTask/FacilitatorRequest.php
  15. 75 101
      app/OrderIssue.php
  16. 8 0
      app/Providers/AppServiceProvider.php
  17. 148 0
      app/Services/DischargeTaskService.php
  18. 13 0
      app/Services/FacilitatorService.php
  19. 23 4
      app/Services/WaybillService.php
  20. 26 0
      app/Traits/ModelSearchWay.php
  21. 15 0
      database/factories/CommodityBarcodeFactory.php
  22. 27 0
      database/factories/DischargeTaskFactory.php
  23. 13 0
      database/factories/FacilitatorFactory.php
  24. 2 1
      database/factories/OrderFactory.php
  25. 1 1
      database/factories/OrderIssueFactory.php
  26. 27 0
      database/factories/RejectedBillFactory.php
  27. 23 0
      database/factories/RejectedBillItemFactory.php
  28. 53 0
      database/migrations/2021_03_18_162505_create_discharge_tasks_table.php
  29. 32 0
      database/migrations/2021_03_18_163135_create_facilitators_table.php
  30. 67 0
      database/migrations/2021_03_19_102545_change_waybill_auth_and_add_discharge_task_auth.php
  31. 33 0
      database/migrations/2021_03_23_091700_add_order_issue_user_owner_group.php
  32. 18 0
      database/seeds/DischargeTaskSeeder.php
  33. 18 0
      database/seeds/FacilitatorSeeder.php
  34. 2 2
      resources/views/layouts/menu.blade.php
  35. 29 0
      resources/views/maintenance/facilitator/_create.blade.php
  36. 29 0
      resources/views/maintenance/facilitator/_edit.blade.php
  37. 34 0
      resources/views/maintenance/facilitator/_table.blade.php
  38. 151 0
      resources/views/maintenance/facilitator/index.blade.php
  39. 5 0
      resources/views/maintenance/menu.blade.php
  40. 10 0
      resources/views/order/issue/edit.blade.php
  41. 21 11
      resources/views/order/issue/index.blade.php
  42. 2 11
      resources/views/process/index.blade.php
  43. 35 0
      resources/views/transport/discharge/facilitator/_table.blade.php
  44. 106 0
      resources/views/transport/discharge/facilitator/index.blade.php
  45. 17 0
      resources/views/transport/discharge/facilitator/menu.blade.php
  46. 21 0
      resources/views/transport/discharge/menu.blade.php
  47. 59 0
      resources/views/transport/discharge/statement/_table.blade.php
  48. 110 0
      resources/views/transport/discharge/statement/index.blade.php
  49. 12 0
      resources/views/transport/discharge/statement/menu.blade.php
  50. 120 0
      resources/views/transport/discharge/task/_createTask.blade.php
  51. 86 0
      resources/views/transport/discharge/task/_executeTask.blade.php
  52. 103 0
      resources/views/transport/discharge/task/_table.blade.php
  53. 333 0
      resources/views/transport/discharge/task/index.blade.php
  54. 11 0
      resources/views/transport/discharge/task/menu.blade.php
  55. 18 0
      resources/views/transport/menu.blade.php
  56. 48 0
      resources/views/transport/waybill/_batchUploadImg.blade.php
  57. 2 1
      resources/views/transport/waybill/authorityMenu.blade.php
  58. 10 9
      resources/views/transport/waybill/create.blade.php
  59. 9 6
      resources/views/transport/waybill/delivering.blade.php
  60. 3 2
      resources/views/transport/waybill/edit.blade.php
  61. 28 28
      resources/views/transport/waybill/index.blade.php
  62. 34 0
      resources/views/transport/waybill/menu.blade.php
  63. 3 3
      resources/views/transport/waybill/menuWaybill.blade.php
  64. 5 4
      resources/views/transport/waybill/recycle.blade.php
  65. 1 1
      resources/views/transport/waybill/waybillEdit.blade.php
  66. 7 7
      resources/views/transport/waybill/waybillFinancialSnapshot/index.blade.php
  67. 0 35
      resources/views/waybill/menu.blade.php
  68. 22 8
      routes/apiLocal.php
  69. 56 1
      routes/web.php
  70. 7 7
      tests/codeCoverage/Http/Controllers/WaybillsController.php.html
  71. 92 0
      tests/old/OrderIssueTest.php
  72. 19 0
      yarn.lock

+ 57 - 0
app/DischargeTask.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use Illuminate\Database\Eloquent\Model;
+
+use App\Traits\ModelLogChanging;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class DischargeTask extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+
+    const status = [
+        '创建',
+        '接单',
+        '作业中',
+        '完成'
+    ];
+
+    const types = [
+        '装车',
+        '卸车'
+    ];
+
+    const units = [
+        'm3',
+        '吨',
+        '托',
+        '件'
+    ];
+
+    protected $fillable = [
+        'owner_id','type','numbers','status',
+        'income_amount','income_unit','income_unit_price','income_total_cost','income_remark',
+        'facilitator_id','expenditure_amount','expenditure_unit','expenditure_unit_price','expenditure_total_cost','expenditure_remark',
+        'income_at','expenditure_at'
+    ];
+
+    function owner(): BelongsTo
+    {
+        return $this->belongsTo(Owner::class);
+    }
+
+    function facilitator(): BelongsTo
+    {
+        return $this->belongsTo(Facilitator::class);
+    }
+
+    public function scopeFilter($query, $filters)
+    {
+        return $filters->apply($query);
+    }
+
+}

+ 16 - 0
app/Facilitator.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App;
+
+use App\Traits\ModelTimeFormat;
+use App\Traits\ModelLogChanging;
+
+use Illuminate\Database\Eloquent\Model;
+
+
+class Facilitator extends Model
+{
+    use ModelLogChanging;
+    use ModelTimeFormat;
+    protected $fillable = ['name'];
+}

+ 107 - 0
app/Filters/DischargeTaskFilters.php

@@ -0,0 +1,107 @@
+<?php
+
+
+namespace App\Filters;
+
+
+  use Illuminate\Http\Request;
+
+class DischargeTaskFilters
+{
+    protected $request;
+    protected $queryBuilder;
+    protected $filters = [
+        'owner_id', 'created_at_start', 'created_at_end', 'numbers', 'status', 'type', 'income_remark','facilitator_id'
+    ];
+    protected $array_filter;
+    protected $params = [];
+
+    public function __construct(Request $request)
+    {
+        $this->request = $request;
+        $this->params = $request->all();
+        $this->array_filter = array_filter($this->request->only($this->filters));
+    }
+
+    public function apply($builder)
+    {
+        $this->queryBuilder = $builder;
+        $this->beforeApply();
+        foreach ($this->array_filter as $filter => $value) {
+            if (method_exists($this, $filter)) {
+                $this->$filter($value, $this->queryBuilder);
+            }
+        }
+        return $this->queryBuilder;
+    }
+
+    private function beforeApply(){
+        if(isset($this->params['data'])){
+            $ids = explode(',',$this->params['data']);
+            $this->id($ids);
+        }
+    }
+
+    private function isSearchLike($str)
+    {
+        if (substr($str, 0, 1) == "%" || substr($str, strlen($str) - 1, 1) == "%") {
+            return true;
+        }
+        return false;
+    }
+
+    private function searchWay($query, $param, $column)
+    {
+        if ($this->isSearchLike($param)) {
+            $query->where($column, 'like', $param);
+        } else {
+            $query->whereIn($column, array_filter(preg_split('/[,, ]+/is', $param)));
+        }
+        return $query;
+    }
+
+    public function owner_id($owner_id)
+    {
+        $this->queryBuilder->where('owner_id',$owner_id);
+    }
+
+    public function created_at_start($created_at_start)
+    {
+        $this->queryBuilder->where('created_at','>=',$created_at_start);
+    }
+    public function created_at_end($created_at_end)
+    {
+        $this->queryBuilder->where('created_at','<=',$created_at_end);
+    }
+
+    public function numbers($numbers)
+    {
+        $this->searchWay($this->queryBuilder,$numbers,'numbers');
+    }
+
+    public function status($status)
+    {
+        $this->queryBuilder->where('status',$status);
+    }
+
+    public function type($type)
+    {
+        $this->queryBuilder->where('type',$type);
+    }
+
+    public function income_remark($income_remark)
+    {
+        $this->queryBuilder->where('income_remark','like',$income_remark."%");
+    }
+
+    public function id($ids)
+    {
+        $this->queryBuilder->whereIn('id',$ids);
+    }
+
+    public function facilitator_id($facilitator_id)
+    {
+        $this->searchWay($this->queryBuilder,$facilitator_id,'facilitator_id');
+    }
+
+}

+ 7 - 3
app/Filters/OrderIssueFilters.php

@@ -14,11 +14,9 @@ use App\OrderPackageCommodities;
 use App\RejectedBill;
 use App\RejectedBillItem;
 use App\Shop;
-use App\UserWorkgroup;
 use Carbon\Carbon;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
-use PhpMyAdmin\Server\UserGroups;
 
 
 class OrderIssueFilters
@@ -65,7 +63,8 @@ class OrderIssueFilters
         'shop_name',
         'finance_confirm',
         'logistic_number_return',
-        'final_status'
+        'final_status',
+        'user_owner_group_id'
     ];
     protected $array_filter;
     protected $params = [];
@@ -424,4 +423,9 @@ class OrderIssueFilters
         $this->queryBuilder->where('order_issues.finance_confirm',$finance_confirm);
     }
 
+    public function user_owner_group_id($user_owner_group_id)
+    {
+        $this->queryBuilder->where('order_issues.user_owner_group_id',$user_owner_group_id);
+    }
+
 }

+ 148 - 0
app/Http/Controllers/DischargeTaskController.php

@@ -0,0 +1,148 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\AsyncResponse;
+use App\Facilitator;
+use App\DischargeTask;
+use App\Filters\DischargeTaskFilters;
+use App\Http\Requests\DischargeTask\DischargeTaskRequest;
+use App\Services\common\ExportService;
+use App\Services\OwnerService;
+use Illuminate\Http\Request;
+use Illuminate\Http\Response;
+use Illuminate\Support\Facades\Gate;
+
+class DischargeTaskController extends Controller
+{
+    use AsyncResponse;
+
+    public function index(Request $request, DischargeTaskFilters $filters)
+    {
+        if (!Gate::allows('运输管理-卸货-查询')) {
+            return redirect(url('/'));
+        }
+        $dischargeTasks = DischargeTask::query()->with(['facilitator', 'owner'])->filter($filters)->orderByDesc('id')->paginate($request['paginate'] ?? 50);
+        $owners = app(OwnerService::class)->getAuthorizedOwners();
+        $facilitators = Facilitator::query()->select('name', 'id')->get();
+        return view('transport.discharge.task.index', compact('dischargeTasks', 'owners', 'facilitators'));
+    }
+
+    // 结算报表
+    public function statementIndex(Request $request, DischargeTaskFilters $filters)
+    {
+        if (!Gate::allows('运输管理-卸货-结算报表-查询')) {
+            return redirect(url('/'));
+        }
+        $dischargeStatements = DischargeTask::query()->with('facilitator')->filter($filters)->orderBy('id')->paginate($request['paginate'] ?? 50);
+        $owners = app(OwnerService::class)->getAuthorizedOwners();
+        $facilitators = Facilitator::query()->select('name', 'id')->get();
+        return view('transport.discharge.statement.index', compact('dischargeStatements', 'owners', 'facilitators'));
+    }
+
+
+    public function create()
+    {
+
+    }
+
+
+    public function store(Request $request)
+    {
+    }
+
+    // async 创建
+    public function storeApi(DischargeTaskRequest $request)
+    {
+        $this->gate('运输管理-卸货-创建');
+        $result = app('DischargeTaskService')->createTask($request->all());
+        if ($result['success']) $this->success($result['data']);
+        $this->error('任务创建异常,刷新当前页面重试');
+    }
+
+    public function show(DischargeTask $dischargeTask)
+    {
+        //
+    }
+
+
+    public function edit(DischargeTask $dischargeTask)
+    {
+        //
+    }
+
+    public function update(Request $request, DischargeTask $dischargeTask)
+    {
+        //
+    }
+
+    // async 编辑
+    public function updateApi(DischargeTaskRequest $request)
+    {
+        $this->gate('运输管理-卸货-编辑');
+        $dischargeTask = DischargeTask::query()->where('id', $request['id'])->first();
+        $result = app('DischargeTaskService')->updateDischargeTask($dischargeTask, $request->all());
+        if ($result['success']) $this->success($result['data']);
+        else $this->error($result['message'] ?? '操作异常,请刷新页面重试');
+    }
+
+    // 修改任务服务商
+    public function updateTaskFacilitatorApi(DischargeTaskRequest $request)
+    {
+        $this->gate('运输管理-卸货-编辑');
+        /** @var  DischargeTask $dischargeTask */
+        $dischargeTask = DischargeTask::query()->where('id', $request['id'])->first();
+        if (!$dischargeTask) $this->error('没有找对应的卸货任务');
+        $result = app('DischargeTaskService')->updateTaskFacilitator($dischargeTask, $request->all());
+        if ($result['success']) $this->success($result['data']);
+        else $this->error($result['message'] ?? '操作异常,请刷新页面重试');
+    }
+
+    public function destroy(DischargeTask $dischargeTask)
+    {
+
+    }
+
+    //  async 删除
+    public function destroyApi(DischargeTaskRequest $request)
+    {
+        $this->gate('运输管理-卸货-删除');
+        /** @var DischargeTask $dischargeTask */
+        $dischargeTask = DischargeTask::query()->where('id', $request['id'])->first();
+        $result = app('DischargeTaskService')->deleteDischargeTask($dischargeTask);
+        if ($result['success']) $this->success();
+        else $this->error($result['message']);
+    }
+
+    // 执行任务
+    public function executingTaskApi(DischargeTaskRequest $request)
+    {
+        $this->gate('运输管理-卸货-编辑');
+        $dischargeTask = DischargeTask::query()->where('id', $request['id'])->first();
+        $result = app('DischargeTaskService')->updateTaskProvider($dischargeTask, $request->all());
+        if ($result['success']) $this->success($result['data']);
+        $this->error($result['message'] ?? '操作异常,请刷新页面重试');
+    }
+
+    // 卸货任务下载
+    public function export(Request $request, DischargeTaskFilters $filters)
+    {
+        $this->gate('运输管理-卸货-查询');
+        $dischargeTasks = DischargeTask::query()->with(['Facilitator', 'owner'])->filter($filters)->orderByDesc('id')->get();
+        $row = ['日期', '客户名称', '作业名称', '入库单号', '数量', '单位', '单价', '收费', '状态', '备注'];
+        $json = app('DischargeTaskService')->getJson($dischargeTasks);
+        return app(ExportService::class)->json($row, $json, "卸货任务");
+    }
+
+    // 结算报表下载
+    public function exportStatements(Request $request, DischargeTaskFilters $filters)
+    {
+        $this->gate('运输管理-卸货-结算报表-查询');
+
+        $dischargeTasks = DischargeTask::query()->with(['facilitator', 'owner'])->filter($filters)->orderByDesc('id')->get();
+        $row = ['日期', '客户名称', '作业名称', '入库单号', '数量', '单位', '收入单价', '收入合计', '服务商', '数量', '单位', '支出单价', '支出合计', '状态', '收入备注', '支出备注'];
+        $json = app('DischargeTaskService')->getStatementsJson($dischargeTasks);
+        return app(ExportService::class)->json($row, $json, "卸货结算报表");
+    }
+
+}

+ 110 - 0
app/Http/Controllers/FacilitatorController.php

@@ -0,0 +1,110 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\AsyncResponse;
+use App\Facilitator;
+use App\DischargeTask;
+use App\Filters\DischargeTaskFilters;
+use App\Http\Requests\DischargeTask\FacilitatorRequest;
+use App\Services\common\ExportService;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Gate;
+
+class FacilitatorController extends Controller
+{
+    use AsyncResponse;
+
+    // 服务商基础设置
+    public function index(Request $request)
+    {
+        if (!Gate::allows('服务商-查询')) {
+            return redirect(url('/'));
+        }
+        $facilitators = Facilitator::query()->select(['id', 'name', 'created_at'])->orderByDesc('id')->paginate($request['paginate'] ?? 50);
+        return view('maintenance.facilitator.index', compact('facilitators'));
+    }
+
+    // 服务商对账单
+    public function statementIndex(Request $request, DischargeTaskFilters $filters)
+    {
+        if (!Gate::allows('服务商-对账单-查询')) {
+            return redirect(url('/'));
+        }
+        $facilitatorStatements = DischargeTask::query()
+            ->filter($filters)
+            ->with('facilitator')
+            ->select(['id', 'facilitator_id', 'expenditure_amount', 'expenditure_unit', 'expenditure_unit_price', 'expenditure_total_cost', 'expenditure_remark', 'created_at'])
+            ->whereNotNull('facilitator_id')
+            ->where('facilitator_id','!=','0')
+            ->orderByDesc('id')->paginate($request['paginate'] ?? 50);
+        $facilitators = Facilitator::query()->get();
+        return view('transport.discharge.facilitator.index', compact('facilitatorStatements', 'facilitators'));
+    }
+
+    public function create()
+    {
+    }
+
+    public function store(Request $request)
+    {
+    }
+
+    public function storeApi(FacilitatorRequest $request)
+    {
+        $this->gate('服务商-创建');
+        $facilitator = Facilitator::query()->create($request->all());
+        $this->success($facilitator);
+    }
+
+    public function show(Facilitator $facilitator)
+    {
+    }
+
+    public function edit(Facilitator $facilitator)
+    {
+    }
+
+    public function update(Request $request, Facilitator $facilitator)
+    {
+    }
+
+    public function updateApi(FacilitatorRequest $request)
+    {
+        $this->gate('服务商-编辑');
+        $facilitator = Facilitator::query()->where('id', $request['id'])->update($request->only(['name']));
+        if ($facilitator) $this->success(Facilitator::query()->find($request['id']));
+        $this->error('更新失败');
+    }
+
+    public function destroy(Facilitator $facilitator)
+    {
+    }
+
+    public function destroyApi(FacilitatorRequest $request)
+    {
+        $this->gate('服务商-删除');
+        $count = Facilitator::query()->where('id', $request['id'])->delete();
+        if ($count > 0) $this->success('删除成功');
+        $this->error('删除失败');
+    }
+
+    // 对账单导出
+    public function exportStatement(Request $request, DischargeTaskFilters $filters)
+    {
+        $this->gate('服务商-对账单-查询');
+        /** @var Collection $facilitatorStatements */
+        $facilitatorStatements = DischargeTask::query()
+            ->filter($filters)
+            ->with('facilitator')
+            ->select(['id', 'facilitator_id', 'expenditure_amount', 'expenditure_unit', 'expenditure_unit_price', 'expenditure_total_cost', 'expenditure_remark', 'created_at'])
+            ->whereNotNull('facilitator_id')
+            ->where('facilitator_id','!=','0')
+            ->orderByDesc('id')->get();
+        $row = ['日期', '服务商', '数量', '单位', '单价', '总金额合计'];
+        $json = app('DischargeTaskService')->getFacilitatorStatementsJson($facilitatorStatements);
+        return app(ExportService::class)->json($row, $json, "服务商对账单报表");
+    }
+
+}

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

@@ -25,7 +25,7 @@ class HomeController extends Controller
     public function index()
     {
         if(!Gate::allows('退货管理-查询')){
-            if(!Gate::allows('运输管理-查询')){ return view('home');}
+            if(!Gate::allows('运输管理-运单-查询')){ return view('home');}
             return redirect(url('waybill'));
         }
         return redirect(url('rejected/index/general'));

+ 23 - 20
app/Http/Controllers/OrderIssueController.php

@@ -20,6 +20,7 @@ use App\Services\OrderIssueService;
 use App\Services\OrderService;
 use App\Services\OwnerService;
 use App\Shop;
+use App\UserOwnerGroup;
 use App\UserWorkgroup;
 use Exception;
 use Illuminate\Database\QueryException;
@@ -39,15 +40,14 @@ class OrderIssueController extends Controller
         if (!Gate::allows('订单管理-问题件-查询')) {
             return redirect(url('/'));
         }
-        /** @var OrderIssueService $orderIssueService */
-        $orderIssueService = app('OrderIssueService');
         $owners = app(OwnerService::class)->getAuthorizedOwners();
         $orderIssues = OrderIssue::query()->filter($filter)->defaultWith()->paginate($request['paginate'] ?? 50);
         $orderIssueType = OrderIssueType::all();
         $qualityLabel = QualityLabel::all();
         $logistics = Logistic::all();
         $userWorkgroup = UserWorkgroup::all();
-        return view('order/issue/index', compact('owners', 'orderIssues', 'orderIssueType', 'qualityLabel','userWorkgroup','logistics'));
+        $userOwnerGroups = UserOwnerGroup::all();
+        return view('order/issue/index', compact('owners', 'orderIssues', 'orderIssueType', 'qualityLabel','userWorkgroup','logistics','userOwnerGroups'));
     }
 
     public function create()
@@ -94,11 +94,12 @@ class OrderIssueController extends Controller
         $secondOrder = $orderIssue->secondOrder;
         $rejectedBill = RejectedBill::query()->where('id', $orderIssue->rejected_bill_id)->first();
         $userWorkgroup = UserWorkgroup::all();
+        $userOwnerGroups = UserOwnerGroup::all();
         $orderIssueType = OrderIssueType::all();
         $owners = Owner::all();
         $shops = Shop::all();
         $logistics = Logistic::all();
-        return view('order/issue/edit', compact('orderIssue', 'owners', 'userWorkgroup', 'shops', 'logistics', 'orderIssueType', 'order', 'secondOrder', 'rejectedBill'));
+        return view('order/issue/edit', compact('orderIssue', 'owners', 'userWorkgroup', 'shops', 'logistics', 'orderIssueType', 'order', 'secondOrder', 'rejectedBill','userOwnerGroups'));
     }
 
     public function batchImport(Request $request)
@@ -206,7 +207,7 @@ class OrderIssueController extends Controller
         try {
             $data =  $request->only([
                 'order_issue_type_id','owner_id','logistic_id', 'logistic_number_return','result_explain','final_status','second_order_id','second_client_no',
-                'logistic_indemnity_money','logistic_express_remission','baoshi_indemnity_money','baoshi_express_remission','user_workgroup_id'
+                'logistic_indemnity_money','logistic_express_remission','baoshi_indemnity_money','baoshi_express_remission','user_workgroup_id','user_owner_group_id'
             ]);
             $orderIssue = OrderIssue::query()->find($request->id);
             $orderIssue->update($data);
@@ -403,7 +404,7 @@ class OrderIssueController extends Controller
         ]);
     }
 
-    public function endOrderIssuesApi(Request $request)
+    public function endOrderIssuesApi(Request $request): array
     {
         if (!Gate::allows('订单管理-问题件-编辑')) {
             return ['success'=>false,'fail_info' => '没有对应权限'];
@@ -418,7 +419,7 @@ class OrderIssueController extends Controller
         return ['success'=>true,'logs'=>$logs];
     }
 
-    public function editSecondClientNoApi(Request $request)
+    public function editSecondClientNoApi(Request $request): array
     {
         if(!Gate::allows('订单管理-问题件-编辑')){
             return ['success'=>false,'fail_info'=>'没有对应权限'];
@@ -437,7 +438,7 @@ class OrderIssueController extends Controller
         }
     }
 
-    public function editSecondLogisticNumberApi(Request $request)
+    public function editSecondLogisticNumberApi(Request $request): array
     {
         if(!Gate::allows('订单管理-问题件-编辑'))
             return ['success'=>false,'fail_info'=>'没有对应权限'];
@@ -451,14 +452,14 @@ class OrderIssueController extends Controller
         }
     }
 
-    public function disposeImportApi(Request $request)
+    public function disposeImportApi(Request $request): array
     {
         if(!Gate::allows('订单管理-问题件-编辑'))
             return ['success'=>false,'fail_info'=>'没有对应权限'];
         return app(OrderIssueService::class)->disposeImport($request->input('ids'));
     }
 
-    public function importPasteDataApi(Request $request)
+    public function importPasteDataApi(Request $request): array
     {
         if (!Gate::allows('订单管理-问题件-导入-文本导入'))
             return ['success'=>false,'fail_info'=>'没有对应权限'];
@@ -542,7 +543,7 @@ class OrderIssueController extends Controller
             }
             if(count($map)!==0)$maps[] = $map;
         }
-//        if(count($errors)>0)
+
         if(count($errors)>0) return ['success'=>false,'fail_info'=>$errors];
         try {
             foreach ($maps as $map) {
@@ -576,7 +577,7 @@ class OrderIssueController extends Controller
             '退回单号', '退单商品名','退单商品条码','退单商品数量','是否正品','退单状态','退单备注',
             '操作类型','说明','操作者','情况说明','问题类别',
             '二次订单号','二次承运商','二次运单号','二次商品条码','二次商品名','二次商品数量',
-            '最终状态', '承运商赔偿金额', '承运商快递减免', '宝时赔偿金额', '宝时快递减免','事故责任方'
+            '最终状态', '承运商赔偿金额', '承运商快递减免', '宝时赔偿金额', '宝时快递减免','事故责任方',/*'项目责任方'*/
         ];
         foreach ($order_Issues as $order_issue){
             $order =  $order_issue->order;
@@ -633,6 +634,8 @@ class OrderIssueController extends Controller
             $order_issue->userWorkgroups->each(function ($userWorkgroup)use (&$userWorkgroupsName) {
                 $userWorkgroupsName.=($userWorkgroup->name).",\r\n";
             });
+            if (isset($order_issue->userOwnerGroup->name))$userWorkgroupsName.=$order_issue->userOwnerGroup->name.",\r\n";
+
             $json[] = [
                 isset($order_issue->created_at) ? str_split($order_issue->created_at,10)[0] :'',       // 登记日期
                 isset($order->created_at) ? str_split($order->created_at,10)[0] :'',             // 创建日期
@@ -684,10 +687,10 @@ class OrderIssueController extends Controller
                 $order_issue->logistic_express_remission,
                 $order_issue->baoshi_indemnity_money,
                 $order_issue->baoshi_express_remission,
-                rtrim($userWorkgroupsName,",\r\n")
+                rtrim($userWorkgroupsName,",\r\n"),
+//                $order_issue->userOwnerGroup->name ?? '',
             ];
         }
-        $mergeColumn = ['A','B','C','D','E','F','G','H','I','J','K','L','P','T','X','Y','Z','AA','AF','AG','AH','AI','AJ','AK'];   // 合并行
         return app(ExportService::class)->json($row,$json,"订单问题件");
     }
 
@@ -705,7 +708,7 @@ class OrderIssueController extends Controller
         return view('order.issue.recycle',compact('orderIssues','paginate'));
     }
 
-    public function recoverOrderIssueApi(Request $request)
+    public function recoverOrderIssueApi(Request $request): array
     {
         if (!Gate::allows('订单管理-问题件-删除')) {
             return ['success'=>false,'error'=>'没有对应权限'];
@@ -717,7 +720,7 @@ class OrderIssueController extends Controller
         return  $service->recoverOrderIssue($request['ids']);
     }
 
-    public function financeConfirmApi(Request $request)
+    public function financeConfirmApi(Request $request): array
     {
         if (!Gate::allows('订单管理-问题件-财务确认')) {
             return ['success'=>false,'error'=>'没有对应权限'];
@@ -733,7 +736,7 @@ class OrderIssueController extends Controller
         }
     }
 
-    public function archiveOrderIssueApi(Request $request)
+    public function archiveOrderIssueApi(Request $request): array
     {
         if (!Gate::allows('订单管理-问题件-编辑')) return ['success'=>false,'error'=>'没有对应权限'];
         if(!$request->has('ids'))return ['success'=>false,'error'=>'没有勾选问题件'];
@@ -751,7 +754,7 @@ class OrderIssueController extends Controller
         return ['success' =>true];
     }
 
-    public function addUserWorkgroup(Request $request)
+    public function addUserWorkgroup(Request $request): array
     {
         $orderIssueId = $request->orderIssueId;
         $userWorkgroupId = $request->userWorkgroupId;
@@ -762,7 +765,7 @@ class OrderIssueController extends Controller
         }
         return ['success' => true,'data' =>UserWorkgroup::find($userWorkgroupId)];
     }
-    public function destroyUserWorkgroup(Request $request)
+    public function destroyUserWorkgroup(Request $request): array
     {
         $orderIssueId = $request->orderIssueId;
         $userWorkgroupId = $request->userWorkgroupId;
@@ -797,7 +800,7 @@ class OrderIssueController extends Controller
         return ['success' => true];
     }
 
-    public function destroySecondLogisticNumberApi(Request $request)
+    public function destroySecondLogisticNumberApi(Request $request): array
     {
         if (!Gate::allows('订单管理-问题件-编辑')) return ['success'=>false,'error'=>'没有对应权限'];
         $count = OrderIssue::query()->where("id",$request->id)->update(["second_logistic_number"=>'']);

+ 24 - 3
app/Http/Controllers/OrderIssueProcessLogController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\OrderIssue;
 use App\OrderIssueProcessLog;
 use App\Services\LogService;
 use App\Services\OrderIssueProcessLogService;
@@ -13,7 +14,11 @@ use Illuminate\Support\Facades\Gate;
 class OrderIssueProcessLogController extends Controller
 {
 
-
+    /**
+     * 处理日志创建
+     * @param Request $request
+     * @return array
+     */
     public function apiStore(Request $request)
     {
         if (!Gate::allows('订单管理-问题件-编辑')) {
@@ -41,15 +46,31 @@ class OrderIssueProcessLogController extends Controller
         }
     }
 
-    public function apiDestroy(Request $request){
+    /**
+     * 删除处理日志
+     * @param Request $request
+     * @return array|bool[]
+     * @throws \Exception
+     */
+    public function destroyApi(Request $request): array
+    {
         if(!$request->filled('id')){
             return ['success'=>false,'fail_info'=>'没有传入对应参数'];
         }
-        OrderIssueProcessLog::query()->where('id',$request->input('id'))->delete();
+        /** @var OrderIssueProcessLog $orderIssueProcessLog */
+        $orderIssueProcessLog = OrderIssueProcessLog::query()->where('id',$request->input('id'))->first();
+        // 删除的如果是完结条目,将处理状态改为空
+        if($orderIssueProcessLog['type'] === '结束') OrderIssue::query()->where('id',$orderIssueProcessLog['order_issue_id'])->update(['final_status'=>null]);
+        $orderIssueProcessLog->delete();
         app('LogService')->log(__METHOD__, __FUNCTION__, json_encode($request->getContent()));
         return ['success'=>true];
     }
 
+    /**
+     * 批量完结订单
+     * @param Request $request
+     * @return array
+     */
     public function batchStoreApi(Request $request){
         if (!Gate::allows('订单管理-问题件-编辑')) {
             return ['success' => false, 'fail_info' => '没有对应的权限'];

+ 27 - 27
app/Http/Controllers/WaybillController.php

@@ -53,10 +53,10 @@ class WaybillController extends Controller
      */
     public function index(Request $request,OwnerService $ownerService,LogisticService $logisticService)
     {
-        if(!Gate::allows('运输管理-查询')){ return view("waybill.authorityMenu");  }
+        if(!Gate::allows('运输管理-运单-查询')){ return view("transport.waybill.authorityMenu");  }
         $paginateParams = $request->input();
         $waybills=app('waybillService')->paginate($request->input());
-        return view('waybill.index', [
+        return view('transport.waybill.index', [
             'waybills' => $waybills,
             'logistics' => $logisticService->getSelection(["id","name"],"物流"),
             'owners' => $ownerService->getIntersectPermitting(),
@@ -67,20 +67,20 @@ class WaybillController extends Controller
 
     public function create(Request $request,OwnerService $ownerService)
     {
-        if(!Gate::allows('运输管理-录入')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('/'));  }
         $type=$request->type ?? "";
         if ($type==='ZF')$type='直发车';
         if ($type==='ZX')$type='专线';
-        return view('waybill.create',['owners'=>$ownerService->getIntersectPermitting(),'type'=>$type]);
+        return view('transport.waybill.create',['owners'=>$ownerService->getIntersectPermitting(),'type'=>$type]);
     }
 
     public function store(Request $request)
     {
-        if(!Gate::allows('运输管理-录入')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-录入')){ return redirect(url('/'));  }
         $this->validatorWaybill($request,false)->validate();
         /** @var WaybillService */
         $waybill=app('waybillService')->store($request);
-        return redirect('waybill/index')->with('successTip','新运单“'.$waybill->waybill_number.'”录入成功');
+        return redirect('transport/waybill/index')->with('successTip','新运单“'.$waybill->waybill_number.'”录入成功');
     }
 
     public function edit($id,LogisticService $logisticService,CarTypeService $carTypeService,UnitService $unitService)
@@ -104,13 +104,13 @@ class WaybillController extends Controller
         $cities=app("RegionService")->getSelection(2);
         $units=$unitService->getSelection();
         $carTypes=$carTypeService->getSelection();
-        return view('waybill/edit',['waybill'=>$waybill,'logistics'=>$logisticService->getSelection(["id","name"],"物流"),'cities'=>$cities,'units'=>$units,'carTypes'=>$carTypes]);
+        return view('transport.waybill.edit',['waybill'=>$waybill,'logistics'=>$logisticService->getSelection(["id","name"],"物流"),'cities'=>$cities,'units'=>$units,'carTypes'=>$carTypes]);
     }
 
     public function update(Request $request, $id,WaybillPriceModelService $waybillPriceModelService,
                            LogisticService $logisticService,WaybillPayoffService $waybillPayoffService)
     {
-        if(!Gate::allows('运输管理-调度')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-调度')){ return redirect(url('/'));  }
         if (!$request->warehouse_weight && $request->warehouse_weight_unit_id){
             $request->offsetUnset('warehouse_weight_unit_id');
         }
@@ -163,7 +163,7 @@ class WaybillController extends Controller
             $waybillPayoffService->updateOrCreate($waybillPayoffParam);
         }
         app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
-        return redirect('waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”调度成功');
+        return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”调度成功');
     }
 
     public function checkWaybillPriceModel($logistic_id,$destination_city_id,$carrier_weight,$carrier_weight_unit_id){
@@ -343,12 +343,12 @@ class WaybillController extends Controller
         $waybill->fill($data);
         if ($waybill->save()){
             app('LogService')->log(__METHOD__,__FUNCTION__,json_encode($waybill),Auth::user()['id']);
-            return redirect('waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”修改成功');
+            return redirect('transport/waybill/index')->with('successTip','运单“'.$waybill->waybill_number.'”修改成功');
         }
     }
 
     public function waybillAudit(Request $request){
-        if(!Gate::allows('运输管理-运单审核')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-运单审核')){ return redirect(url('/'));  }
         $id=$request->input('id');
         $waybill=app('waybillService')->find($id);
         $isAudit=WaybillAuditLog::whereRaw('waybill_id = ? and audit_stage = ?',[$id,"运单阶段"])->first();
@@ -372,10 +372,10 @@ class WaybillController extends Controller
         if(!Gate::allows('运输管理-编辑')){ return redirect(url('/'));  }
         $waybill=app('waybillService')->find($id);
         $owners=app("OwnerService")->getIntersectPermitting();
-        return view('waybill.waybillEdit',['waybill'=>$waybill,'owners'=>$owners]);
+        return view('transport.waybill.waybillEdit',['waybill'=>$waybill,'owners'=>$owners]);
     }
     public function waybillRetreatAudit(Request $request){
-        if(!Gate::allows('运输管理-调度')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-调度')){ return redirect(url('/'));  }
         $id=$request->input('id');
         $waybill=app('waybillService')->find($id);
         WaybillAuditLog::query()->whereRaw('waybill_id = ? and audit_stage = ?',[$id,"运单阶段"])->delete();
@@ -385,7 +385,7 @@ class WaybillController extends Controller
         return ['success'=>$result,'status'=>$waybill->status];
     }
     public function waybillEndAudit(Request $request){
-        if(!Gate::allows('运输管理-调度审核')){ return redirect(url('/'));  }
+        if(!Gate::allows('运输管理-运单-调度审核')){ return redirect(url('/'));  }
         $id=$request->input('id');
         $waybill=Waybill::query()->with(["owner","logistic","originationCity","destinationCity","carType",'priceModel',"amountUnit",
             "warehouseWeightUnit","carrierWeightUnit","warehouseWeightUnitOther","carrierWeightUnitOther"])->find($id);
@@ -485,7 +485,7 @@ class WaybillController extends Controller
     }
 
     public function upload(Request $request){
-        if(!Gate::allows('运输管理-图片上传')){ return '没有权限';  }
+        if(!Gate::allows('运输管理-运单-图片上传')){ return '没有权限';  }
         $file=$request->file('file');
         $waybill_number=$request->input('waybill_number');
         $waybill=Waybill::query()->where('waybill_number',$waybill_number)->first();
@@ -535,7 +535,7 @@ class WaybillController extends Controller
     //批量上传图片
     public function batchUploadImages()
     {
-        $this->gate("运输管理-图片上传");
+        $this->gate("运输管理-运单-图片上传");
         ini_set('max_execution_time',1000);
         ini_set('memory_limit','100M');
         $images = request("images");
@@ -596,7 +596,7 @@ class WaybillController extends Controller
 
     //删除照片
     public function deleteImg(Request $request){
-        if(!Gate::allows('运输管理-图片删除')){ return '没有权限';  }
+        if(!Gate::allows('运输管理-运单-图片删除')){ return '没有权限';  }
         $ids=$request->input('ids');
         $uploadFiles=UploadFile::where('table_name','waybills')->whereIn('table_id',$ids)->get();
         foreach ($uploadFiles as $uploadFile){
@@ -613,7 +613,7 @@ class WaybillController extends Controller
     }
 
     public function export(){
-        $this->gate('运输管理-查询');
+        $this->gate('运输管理-运单-查询');
         if (request("checkAllSign")){
             request()->offsetUnset("checkAllSign");
             $waybills = app('waybillService')->get(request()->input());
@@ -687,7 +687,7 @@ class WaybillController extends Controller
             $carrierIds=array_column($carriersUsers->toArray(),'logistic_id');
             $waybills=$waybills->whereIn("logistic_id",$carrierIds);
         }
-        return view('waybill.delivering',compact('waybills'));
+        return view('transport.waybill.delivering',compact('waybills'));
     }
     //承运商提交
     public function storeCarrierBill(Request $request){
@@ -819,7 +819,7 @@ class WaybillController extends Controller
 
     // 运单删除 软删除
     public function destroy(int $id){
-        if(!GAte::allows('运输管理-删除')){return['success'=>0,'status'=>'没有权限'];}
+        if(!GAte::allows('运输管理-运单-删除')){return['success'=>0,'status'=>'没有权限'];}
         if(is_null($id)){return ['success'=>'0','status'=>'传入id为空'];}
         $result =  Waybill::where('id',$id)->delete();
         return ['success'=>$result,'status'=>$result];
@@ -827,7 +827,7 @@ class WaybillController extends Controller
 
     // 回收站
     public function recycle(Request $request){
-        if(!Gate::allows('运输管理-删除')){return redirect('/');}
+        if(!Gate::allows('运输管理-运单-删除')){return redirect('/');}
         $paginate = $request->input('paginate')??50;
         /** @var Collection $waybills */
         $waybills = Waybill::query()->with(['owner','order.owner','logistic','amountUnit','warehouseWeightUnit','carrierWeightUnit',
@@ -838,12 +838,12 @@ class WaybillController extends Controller
         $total = $waybills->count();
         $paginateParams = [];
         $paginateParams['paginate'] = $paginate;
-        return view('waybill.recycle',compact('waybills','total','paginateParams'));
+        return view('transport.waybill.recycle',compact('waybills','total','paginateParams'));
     }
 
     // 软删除恢复
     public function apiRestoreSelected(Request $request){
-        if(!Gate::allows('运输管理-删除')){return ['success'=>'false','fail_info'=>'没有权限'];}
+        if(!Gate::allows('运输管理-运单-删除')){return ['success'=>'false','fail_info'=>'没有权限'];}
         $ids = $request->input('ids')??'';
         if($ids == ''){return ['success'=>'false','fail_info'=>'没有可恢复对象'];}
         $waybills =  Waybill::withTrashed()->whereIn('id',$ids)->get();
@@ -855,7 +855,7 @@ class WaybillController extends Controller
     }
     // 修改运费
     public function changeFee(Request $request){
-        if(!Gate::allows('运输管理-运费')){return ['success'=>'false','fail_info'=>'没有权限'];}
+        if(!Gate::allows('运输管理-运单-运费')){return ['success'=>'false','fail_info'=>'没有权限'];}
         $wayBillId = $request->input('id');
         $waybillFee = $request->input('fee');
         if(is_null($wayBillId) or is_null($waybillFee)){
@@ -867,7 +867,7 @@ class WaybillController extends Controller
     }
     // 修改运输收费
     public function changeCharge(Request $request){
-        if(!Gate::allows('运输管理-运单编辑')){return ['success'=>'false','fail_info'=>'没有权限'];}
+        if(!Gate::allows('运输管理-运单-运单编辑')){return ['success'=>'false','fail_info'=>'没有权限'];}
         $wayBillId = $request->id;
         $waybillCharge = $request->input('charge');
         if(is_null($wayBillId) or is_null($waybillCharge)){
@@ -881,7 +881,7 @@ class WaybillController extends Controller
     public function waybillOnTop(Request $request){
         $id =  $request->input('id');
         $detail =  $request->input('detail');
-        if(!Gate::allows('运输管理-置顶')){return ['success'=>'false','fail_info'=>'没有权限'];}
+        if(!Gate::allows('运输管理-运单-置顶')){return ['success'=>'false','fail_info'=>'没有权限'];}
         if(is_null($id)){
             return  ['success'=>'false','fail_info'=>'传参错误'];
         }
@@ -897,7 +897,7 @@ class WaybillController extends Controller
     // 取消置顶
     public function cancelOnTop(Request $request){
         $id =  $request->input('id');
-        if(!Gate::allows('运输管理-置顶')){return ['success'=>'false','fail_info'=>'没有权限'];}
+        if(!Gate::allows('运输管理-运单-置顶')){return ['success'=>'false','fail_info'=>'没有权限'];}
         if(is_null($id)){
             return  ['success'=>'false','fail_info'=>'传参错误'];
         }

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

@@ -37,6 +37,6 @@ class WaybillFinancialExceptedController extends Controller
             $type='ZX';
         }
         $waybillFinancialSnapshots=$this->conditionQuery($request,$waybillFinancialSnapshots);
-        return view('waybill.waybillFinancialSnapshot.index',['waybillFinancialSnapshots'=>$waybillFinancialSnapshots,'filterData'=>$request->input(),'type'=>$type,'excepted'=>true]);
+        return view('transport.waybill.waybillFinancialSnapshot.index',['waybillFinancialSnapshots'=>$waybillFinancialSnapshots,'filterData'=>$request->input(),'type'=>$type,'excepted'=>true]);
     }
 }

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

@@ -40,7 +40,7 @@ class WaybillFinancialSnapshotsController extends Controller
             $type='ZX';
         }
         $waybillFinancialSnapshots=$this->conditionQuery($request,$waybillFinancialSnapshots);
-        return view('waybill.waybillFinancialSnapshot.index',['waybillFinancialSnapshots'=>$waybillFinancialSnapshots,'filterData'=>$request->input(),'type'=>$type]);
+        return view('transport.waybill.waybillFinancialSnapshot.index',['waybillFinancialSnapshots'=>$waybillFinancialSnapshots,'filterData'=>$request->input(),'type'=>$type]);
     }
     public function export(Request $request){
         if(!Gate::allows('财务报表-查询')){ return '没有权限';  }

+ 110 - 0
app/Http/Requests/DischargeTask/DischargeTaskRequest.php

@@ -0,0 +1,110 @@
+<?php
+
+
+namespace App\Http\Requests\DischargeTask;
+
+use App\Traits\RequestApiFormValidation;
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Request;
+use Illuminate\Support\Facades\Route;
+
+
+class DischargeTaskRequest extends FormRequest
+{
+    use RequestApiFormValidation;
+
+    protected $deleteApiRules =[
+        'id' => 'required'
+    ];
+    protected $deleteApiMessage =[
+        'id.required' => '参数错误'
+    ];
+    protected $storeApiRules =[
+        'owner_id' => 'required',
+        'type' => 'required',
+        'numbers' => 'required',
+        'income_unit' => 'required',
+        'income_amount' => 'required',
+        'income_unit_price' => 'required',
+    ];
+    protected $storeApiMessage =[
+        'owner_id.required' => '货物为必选项',
+        'type.required' => '任务类型为必选项',
+        'numbers.required' => '入库单号为必填项',
+        'income_amount.required' => '数量为必填项',
+        'income_unit.required' => '单位为必选项',
+        'income_unit_price.required'=> '单价为必填项',
+    ];
+    protected $updateApiRules =[
+        'owner_id' => 'required',
+        'type' => 'required',
+        'numbers' => 'required',
+        'income_unit' => 'required',
+        'income_amount' => 'required',
+        'income_unit_price' => 'required',
+    ];
+    protected $updateApiMessage =[
+        'owner_id.required' => '货物为必选项',
+        'type.required' => '任务类型为必选项',
+        'numbers.required' => '入库单号为必填项',
+        'income_amount.required' => '数量为必填项',
+        'income_unit.required' => '单位为必选项',
+        'income_unit_price.required'=> '单价为必填项',
+    ];
+    protected $updateTaskFacilitatorApiRules =[
+        'id' => 'required',
+        'facilitator_id' => 'required',
+        'expenditure_amount' => 'required',
+        'expenditure_unit' => 'required',
+        'expenditure_unit_price' => 'required',
+    ];
+    protected  $updateTaskFacilitatorApiMessage =[
+        'id.required'=>'未选中卸货任务',
+        'facilitator_id.required' => '服务商为必选项',
+        'expenditure_amount.required' => '数量为必填项',
+        'expenditure_unit.required' => '单位为必选项',
+        'expenditure_unit_price.required' => '单价为必填项',
+    ];
+
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    public function rules(): array
+    {
+        $currentRoute = Route::getCurrentRoute();
+        $routeName = $currentRoute->getName();
+        switch ($routeName){
+            case 'discharge.deleteApi':
+                return $this->deleteApiRules;
+            case 'discharge.storeApi':
+                return $this->storeApiRules;
+            case 'discharge.updateApi':
+                return $this->updateApiRules;
+            case 'discharge.updateTaskFacilitatorApi':
+                return $this->updateTaskFacilitatorApiRules;
+            default :
+                return [];
+        }
+    }
+
+    public function messages(): array
+    {
+        $currentRoute = Route::getCurrentRoute();
+        $routeName = $currentRoute->getName();
+        switch ($routeName){
+            case 'discharge.deleteApi':
+                return $this->deleteApiMessage;
+            case 'discharge.storeApi':
+                return $this->storeApiMessage;
+            case 'discharge.updateApi':
+                return $this->updateApiMessage;
+            case 'discharge.updateTaskFacilitatorApi':
+                return $this->updateTaskFacilitatorApiMessage;
+            default :
+                return [];
+        }
+    }
+
+}

+ 74 - 0
app/Http/Requests/DischargeTask/FacilitatorRequest.php

@@ -0,0 +1,74 @@
+<?php
+
+
+namespace App\Http\Requests\DischargeTask;
+use App\Traits\RequestApiFormValidation;
+use  Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Route;
+
+class FacilitatorRequest extends FormRequest
+{
+    use RequestApiFormValidation;
+
+    protected $deleteApiRules = [
+        'id' => 'required'
+    ];
+
+    protected $deleteApiMessage = [
+        'id.required' => "没有对应的服务商"
+    ];
+
+    protected $storeApiRules = [
+        'name' => 'required|min:2'
+    ];
+
+    protected $storeApiMessage = [
+        'id.required' => "服务商名称不能为空",
+        'name.min' => '服务商名称长度不能小于2'
+    ];
+
+    protected $updateApiMessage = [
+        'name.required' => '服务商名称不能为空',
+        'name.min' => '服务商名称长度不能小于2'
+    ];
+
+    protected $updateApiRules = [
+        'name.' => 'required|min:2'
+    ];
+
+
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    public function rules(): array
+    {
+        $routeName = Route::currentRouteName();
+        switch ($routeName){
+            case 'facilitator.storeApi':
+                return $this->storeApiRules;
+            case 'facilitator.updateApi':
+                return $this->updateApiRules;
+            case 'facilitator.destroyApi':
+                return $this->deleteApiRules;
+            default :
+                return [];
+        }
+    }
+
+    public function massage():array
+    {
+        $routeName = Route::currentRouteName();
+        switch ($routeName){
+            case 'facilitator.storeApi':
+                return $this->storeApiMessage;
+            case 'facilitator.updateApi':
+                return $this->updateApiMessage;
+            case 'facilitator.destroyApi':
+                return $this->deleteApiMessage;
+            default :
+                return [];
+        }
+    }
+}

+ 75 - 101
app/OrderIssue.php

@@ -7,6 +7,10 @@ use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Database\Eloquent\Relations\HasOne;
+
 
 use App\Traits\ModelLogChanging;
 
@@ -23,7 +27,7 @@ class OrderIssue extends Model
     use SoftDeletes;
 
     protected $fillable = [
-        'order_id', 'created_at', 'rejected_bill_id',
+        'order_id', 'created_at', 'rejected_bill_id','user_owner_group_id',
         'rejecting_status', 'result_explain','logistic_number_return',
         'situation_explain', 'order_issue_type_id', 'second_order_id',
         'is_new_rejecting','second_client_no','second_logistic_number',
@@ -47,42 +51,47 @@ class OrderIssue extends Model
      */
     protected $appends = [];
 
-    public function order()
+    public function order(): \Illuminate\Database\Eloquent\Relations\BelongsTo
     {
         return $this->belongsTo(Order::class, 'order_id', 'id');
     }
 
-    public function rejectedBills()
+    public function rejectedBills(): BelongsToMany
     {
         return $this->belongsToMany(RejectedBill::class,'order_issue_rejected_bill','order_issue_id','logistic_number_return','id','logistic_number_return');
     }
 
-    public function orderIssueRejectedBills()
+    public function orderIssueRejectedBills(): HasMany
     {
         return $this->hasMany(OrderIssueRejectedBill::class);
     }
 
-    public function issueType()
+    public function issueType(): BelongsTo
     {
         return $this->belongsTo('App\OrderIssueType', 'order_issue_type_id', 'id');
     }
 
-    public function logs()
+    public function logs(): HasMany
     {
         return $this->hasMany('App\OrderIssueProcessLog', 'order_issue_id', 'id');
     }
 
-    public function top()
+    public function top(): HasOne
     {
         return $this->hasOne('App\OrderIssueOnTop', 'order_issue_id', 'id');
     }
 
-    public function userWorkGroup()
+    public function userWorkGroup(): BelongsTo
     {
         return $this->belongsTo('App\UserWorkgroup', 'user_workgroup_id', 'id');
     }
 
-    public function secondOrder()
+    public function userOwnerGroup(): BelongsTo
+    {
+        return $this->belongsTo(UserOwnerGroup::class);
+    }
+
+    public function secondOrder(): HasOne
     {
         return $this->hasOne('App\Order', 'client_code', 'second_client_no');
     }
@@ -97,7 +106,7 @@ class OrderIssue extends Model
         return $this->logs->where('type', '结束')->last();
     }
 
-    public function getProcessingTimeAttribute()
+    public function getProcessingTimeAttribute(): ?string
     {
         $createLogs = $this->getCreateLogAttribute();
         $endLogs = $this->getEndLogAttribute();
@@ -125,103 +134,68 @@ class OrderIssue extends Model
      */
     public function syncRejectingStatus()
     {
-        if(!$this->order_id)return;
-        $rejectedItems = [];
-        $orderItems = [];
-        $rejectedBills = $this->rejectedBills;
-        if(!$rejectedBills)return;
-        $rejectedBillItems = RejectedBillItem::query()->with('quality')
-            ->whereIn('id_rejected_bill',function($query)use($rejectedBills){
-                $query->from('rejected_bills')->select('id')->whereIn('logistic_number_return',$rejectedBills->map(function($rejectedBil){
-                    return $rejectedBil->logistic_number_return;
-                }));
-        })->get();
-
-        if($rejectedBillItems->count()===0){
-            $this->update(['rejecting_status' => '未退回']);
-            return;
-        }
+        $this->syncRejectedBillStatus($this);
+    }
 
-        if($rejectedBillItems->where('quality.name','残次')->count()>0){
-            $this->update(['rejecting_status' => '差异退回']);
-            return;
-        }
-        $barcodeGoods = data_get($rejectedBillItems,'*.barcode_goods');
-        $commodityBarcodes = CommodityBarcode::query()->with('commodity')->whereIn('code',$barcodeGoods)->get();
-        $commodities = Commodity::query()->whereIn('sku',$barcodeGoods)->get();
-
-        foreach ($rejectedBillItems as $item) {
-            $barcode_goods = (string)$item->barcode_goods;
-            $commodity = $commodities->where('sku',$barcode_goods)->first();
-            if(!$commodity){
-                $commodityBarcode = $commodityBarcodes->where('code',$barcode_goods)->first();
-                $barcode_goods = $commodityBarcode->commodity->sku ?? $barcode_goods;
-            }
-            if (!isset($rejectedItems[$barcode_goods])){
-                $rejectedItems[$barcode_goods] = 0;
-            }
-            $rejectedItems[(string)$barcode_goods] += $item->amount;
+    public function syncRejectedBillStatus($orderIssue)
+    {
+        if (!$orderIssue->order_id) return;
+        $orderIssueMap = [];
+        $rejectedMap = [];
+        $owner_id = $orderIssue->order->owner_id;
+
+        // 获取对应订单的所有商品
+        $orderPackageQuery = OrderPackage::query()->selectRaw("id")->where('order_id', $orderIssue->order_id);
+        $orderPackageCommodities = OrderPackageCommodities::query()->with('commodity')->whereIn('order_package_id', $orderPackageQuery)->get();
+        foreach ($orderPackageCommodities as $orderPackageCommodity) {
+            $code = $orderPackageCommodity->commodity->sku;
+            if (empty($orderIssueMap[$code])) $orderIssueMap[$code] = $orderPackageCommodity->amount;
+            else $orderIssueMap[$code] += $orderPackageCommodity->amount;
         }
 
-        $items = OrderPackageCommodities::query()->with('commodity')
-            ->whereIn('order_package_id',function($query){
-                $query->from('order_packages')->selectRaw('id')->where('order_id',$this->order_id);
-            })->get();
-
-        if(count($items) == 0){
-            $this->update(['rejecting_status' => '无']);
-            return;
-        }
-        if (count($items) > 0) {
-            foreach ($items as $item) {
-                $sku = $item['commodity']['sku'];
-                if (! isset($orderItems[$sku]) ?? false){
-                    $orderItems[$sku] = 0;
+        // 获取对应退回单的所有商品
+        $orderIssueRejectedBillQuery = OrderIssueRejectedBill::query()->selectRaw("logistic_number_return")->where("order_issue_id", $orderIssue->id);
+        $RejectedBills = RejectedBill::query()->with('items.quality')->whereIn("logistic_number_return", $orderIssueRejectedBillQuery)->get();
+        /** @var RejectedBill $rejectedBill */
+        foreach ($RejectedBills as $rejectedBill) {
+            foreach ($rejectedBill->items as $item) {
+                $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;
                 }
-                $orderItems[$sku] += $item->amount;
+                $qualityName = $item->quality->name;
+                if (empty($rejectedMap[$code]) || empty($rejectedMap[$code][$qualityName])) $rejectedMap[$code][$qualityName] = $item->amount;
+                else $rejectedMap[$code][$qualityName] += $item->amount;
             }
-        } else {
-            $this->update(['rejecting_status' => '无']);
-            return;
-        }
-        $rejectedExcess = 0;    // 退回差异
-        $rejectedReview = 0;    // 退回复核  $rejectedItems == $orderItems
-        foreach ($rejectedItems as $key => $items) {
-            if ($orderItems[$key] ?? false) {
-                if ($rejectedItems[$key] == $orderItems[$key])
-                    $rejectedReview++;
-            } else
-                $rejectedExcess++;
-        }
-        if ($rejectedExcess > 0) {
-            $this->update(['rejecting_status' => '差异退回']);
-            return;
-        }
-        // 全部退回 部分退回 超量退回 差异退回 未退回 无
-        $isExcess = 0; // 超量 $orderItems < $rejectedItems
-        $isDiff = 0;   // 部分 $orderItems > $rejectedItems
-        $isAccord = 0; // 相同 $orderItems == $rejectedItems
-        $isLack = 0;   // 缺少 $orderItems != $rejectedItems
-        foreach ($orderItems as $key => $item) {
-            if ($rejectedItems[$key] ?? false) {
-                if ($orderItems[$key] < $rejectedItems[$key])
-                    $isExcess++;
-                else if ($orderItems[$key] > $rejectedItems[$key])
-                    $isDiff++;
-                else if ($orderItems[$key] == $rejectedItems[$key])
-                    $isAccord++;
-            } else
-                $isLack++;
         }
+        // 比较
+        $status = $this->getRejectingStatus($orderIssueMap, $rejectedMap);
+        $this->update(['rejecting_status' => $status]);
+    }
 
-        if($isAccord == $rejectedReview && $isLack == 0 && $isExcess == 0 && $isDiff==0 && $rejectedExcess == 0 )
-            $this->update(['rejecting_status' => '全部退回']);
-        else if($isExcess > 0 && $isAccord ==  $rejectedReview && $isDiff == 0 && $isLack == 0)
-            $this->update(['rejecting_status' => '超量退回']);
-        else if($isDiff >=0 && $isAccord == $rejectedReview && $isLack >=0 && $rejectedExcess ==0 && $isExcess==0)
-            $this->update(['rejecting_status' => '部分退回']);
-        else if($isLack >= 0 && $rejectedExcess>=0 && $isDiff>=0 && $isLack>=0 && $isExcess>=0 && $rejectedReview>=0)
-            $this->update(['rejecting_status' => '差异退回']);
+    private function getRejectingStatus($orderIssueMap, $rejectedMap): string
+    {
+        //未退回,差异退回,全部退回,超量退回,部分退回
+        if (count($rejectedMap) == 0) return "未退回";
+        $equal = 0;
+        $portion = 0;
+        foreach ($rejectedMap as $key => $map) {
+            if (isset($map['残次']) && $map['残次'] > 0) return "差异退回";
+            if (empty($orderIssueMap[$key])) return "差异退回";
+            if(isset($rejectedMap[$key]['正品']) && isset($orderIssueMap[$key]['正品'])){
+                if ( $rejectedMap[$key]['正品'] < $orderIssueMap[$key]) $portion += 1;
+                if ( $rejectedMap[$key]['正品'] > $orderIssueMap[$key]) return "超量退回";                    // 超量退回
+                if ( $rejectedMap[$key]['正品'] == $orderIssueMap[$key]) $equal += 1;
+            }
+        }
+        if ($equal == count($orderIssueMap) && $equal == count($rejectedMap)  && $portion == 0) return "全部退回";        // 全部退回
+        if ($portion > 0) return "部分退回";                                                            // 部分退回
+        return "无";
     }
 
     public function delete()
@@ -321,7 +295,7 @@ class OrderIssue extends Model
             $query->with(['shop', 'logistic', 'owner', 'packages.commodities.commodity.barcodes']);
         },'orderIssueRejectedBills.rejectedBill'=>function($query){
             $query->with(['owner','logistic','user','items.quality']);
-        },'userWorkgroups']);
+        },'userWorkgroups','userOwnerGroup']);
 
     }
 

+ 8 - 0
app/Providers/AppServiceProvider.php

@@ -15,6 +15,8 @@ use App\Services\CustomerLogService;
 use App\Services\CustomerLogStatusService;
 use App\Services\CustomerService;
 use App\Services\DepositoryService;
+use App\Services\FacilitatorService;
+use App\Services\DischargeTaskDossierService;
 use App\Services\FeatureService;
 use App\Services\ForeignHaiRoboticsService;
 use App\Services\InventoryAccountMissionService;
@@ -96,6 +98,7 @@ use App\Services\OrderFreezeService;
 use App\Services\RegionService;
 use App\Services\UserWorkgroupService;
 use App\Services\DeliveryAppointment;
+use App\Services\DischargeTaskService;
 use App\Services\DeliveryAppointmentService;
 use Illuminate\Queue\Events\JobFailed;
 use Illuminate\Support\Facades\Queue;
@@ -148,6 +151,7 @@ class AppServiceProvider extends ServiceProvider
 
     private function loadingService(){
         app()->singleton('AllInventoryService',AllInventoryService::class);
+        app()->singleton('ApiUserService',\App\Services\api\UserService::class);
         app()->singleton('AuthorityService',AuthorityService::class);
         app()->singleton('BatchService',BatchService::class);
         app()->singleton('BatchUpdateService', BatchUpdateService::class);
@@ -165,6 +169,9 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('DeliveryAppointment',DeliveryAppointment::class);
         app()->singleton('DeliveryAppointmentService',DeliveryAppointmentService::class);
         app()->singleton('DepositoryService',DepositoryService::class);
+        app()->singleton('DischargeTaskDossierService',DischargeTaskDossierService::class);
+        app()->singleton('DischargeTaskService',DischargeTaskService::class);
+        app()->singleton('FacilitatorService',FacilitatorService::class);
         app()->singleton('FeatureService',FeatureService::class);
         app()->singleton('ForeignHaiRoboticsService',ForeignHaiRoboticsService::class);
         app()->singleton('InventoryAccountMissionService',InventoryAccountMissionService::class);
@@ -196,6 +203,7 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('OwnerAreaReportService',OwnerAreaReportService::class);
         app()->singleton('OwnerBillReportService',OwnerBillReportService::class);
         app()->singleton('OwnerFeeDetailService',OwnerFeeDetailService::class);
+        app()->singleton('OwnerMaterialService',OwnerMaterialService::class);
         app()->singleton('OwnerPriceDirectLogisticService',OwnerPriceDirectLogisticService::class);
         app()->singleton('OwnerPriceExpressService',OwnerPriceExpressService::class);
         app()->singleton('OwnerPriceLogisticService',OwnerPriceLogisticService::class);

+ 148 - 0
app/Services/DischargeTaskService.php

@@ -0,0 +1,148 @@
+<?php
+
+namespace App\Services;
+
+use App\Facilitator;
+use App\Traits\ServiceAppAop;
+use App\DischargeTask;
+use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Collection;
+
+class DischargeTaskService
+{
+    use ServiceAppAop;
+
+    protected $modelClass = DischargeTask::class;
+
+    // 编辑卸货任务
+    public function updateDischargeTask(DischargeTask $dischargeTask, array $param): array
+    {
+        if ($dischargeTask->status == 3) return ['success' => false, 'message' => '已完成的卸货任务不可进行编辑'];
+        if(!empty($param['status']) && $param['status'] > 0 && $dischargeTask->facilitator_id == 0)
+            return ['success' => false, 'message' => '未指定服务商的卸货任务,不可进行当前编辑'];
+        // 归档入口
+        $bool = $dischargeTask->update($param);
+        if ($bool){
+            $dischargeTask->refresh();
+            $dischargeTask->loadMissing('owner','facilitator');
+            return ['success' => true, 'data' => $dischargeTask];
+        }
+        else return ['success' => false];
+    }
+
+    // 删除卸货任务
+    public function deleteDischargeTask(DischargeTask $dischargeTask): array
+    {
+        if ($dischargeTask->status == 3) return ['success' => false, 'message' => '已完成的卸货任务不可进行删除'];
+        try {
+            $dischargeTask->delete();
+            return ['success' => true];
+        } catch (\Exception $e) {
+            return ['success' => false, 'message' => $e->getMessage()];
+        }
+    }
+
+    // 指定服务商
+    public function updateTaskFacilitator(DischargeTask $dischargeTask, array $param): array
+    {
+        unset($param['owner'],$param['income_at']);
+        if ($param['id']) unset($param['id']);
+        if ($dischargeTask->status >= 1) return ['success' => false, 'message' => '当前任务状态不可修改'];
+        $param['expenditure_total_cost'] = $param['expenditure_unit_price'] * $param['expenditure_amount'];
+        if (empty($param['expenditure_at'])) $param['expenditure_at'] = now();
+        if (empty($param['status'])) $param['status'] = 1;
+        $bool = $dischargeTask->update($param);
+        if ($bool == 1) {
+            $dischargeTask->loadMissing('owner','facilitator');
+            return ['success' => true, 'data' => $dischargeTask];
+        } else return ['success' => false];
+    }
+
+    // 创建卸货任务
+    public function createTask(array $param): array
+    {
+        if (isset($param['id'])) unset($param['id']);
+        if (empty($param['income_total_cost'])) $param['income_total_cost'] = $param['income_unit_price'] * $param['income_amount'];
+        if (empty($param['income_at'])) $param['income_at'] = now();
+        if (empty($param['status'])) $param['status'] = 0;
+        $dischargeTask = DischargeTask::query()->create($param);
+        $dischargeTask->loadMissing('owner');
+        return ['success' => true, 'data' => $dischargeTask];
+    }
+
+    // 卸货任务
+    public function getJson(Collection $dischargeTasks): array
+    {
+        $json = [];
+        foreach ($dischargeTasks as $dischargeTask) {
+            /** @var DischargeTask $dischargeTask */
+            /** @var Carbon $date */
+            $date = $dischargeTask['created_at'];
+            $json[] = [
+                $date->toDateTimeString(),
+                $dischargeTask->owner->name ?? '',
+                DischargeTask::types[$dischargeTask['type']] ?? '',
+                $dischargeTask->numbers ?? '',
+                ($dischargeTask['income_amount']).'',
+                DischargeTask::units[$dischargeTask['income_unit']] ?? '',
+                $dischargeTask->income_unit_price ?? '',
+                $dischargeTask->income_total_cost ?? '',
+                DischargeTask::status[$dischargeTask['status']] ?? '',
+                $dischargeTask->income_remark  ?? ' ',
+            ];
+        }
+        return $json;
+    }
+
+    // 结算报表
+    public function getStatementsJson(Collection $dischargeTasks): array
+    {
+        $json = [];
+        foreach ($dischargeTasks as $dischargeTask) {
+            /** @var DischargeTask $dischargeTask */
+            /** @var Carbon $date */
+            $date = $dischargeTask['created_at'];
+            $json[] = [
+                $date->toDateTimeString(),                          //日期
+                $dischargeTask->owner->name ?? '',                  // 客户名称
+                DischargeTask::types[$dischargeTask['type']] ?? '',   // 作业名称
+                $dischargeTask['numbers'],                            // 入库单号
+                // --- 收入信息
+                ($dischargeTask['income_amount']).'',                                  // 数量
+                DischargeTask::units[$dischargeTask['income_unit']] ?? '',        // 单位
+                $dischargeTask['income_unit_price'],                              // 收入单价
+                $dischargeTask['income_total_cost'],                              // 收入合计
+                // --- 支出信息
+                $dischargeTask->facilitator->name ?? '',                  // 服务商
+                ($dischargeTask['expenditure_amount']).'',                             // 数量
+                DischargeTask::units[$dischargeTask['expenditure_unit']] ?? '',   // 单位
+                $dischargeTask['expenditure_unit_price'],                         // 支出单价
+                $dischargeTask['expenditure_total_cost'],                         // 支出合计
+                // --- 其他信息
+                DischargeTask::status[$dischargeTask['status']] ?? '',    // 状态
+                $dischargeTask->income_remark ?? '',                          // 收入备注
+                $dischargeTask->expenditure_remark ?? '',                     // 支出备注
+            ];
+        }
+        return $json;
+    }
+
+    // 服务商对账单
+    public function getFacilitatorStatementsJson(Collection $dischargeTasks): array
+    {
+        $json = [];
+        foreach ($dischargeTasks as $dischargeTask) {
+            /** @var Carbon $date */
+            $date = $dischargeTask->created_at;
+            $json[] = [
+                $date->toDateTimeString(),                           // 日期
+                $dischargeTask->facilitator->name ?? '',      // 服务商
+                $dischargeTask['expenditure_amount'],                             // 数量
+                DischargeTask::units[$dischargeTask['expenditure_unit']] ?? '',   // 单位
+                $dischargeTask['expenditure_unit_price'],                         // 支出单价
+                $dischargeTask['expenditure_total_cost'],                         // 支出合计
+            ];
+        }
+        return $json;
+    }
+}

+ 13 - 0
app/Services/FacilitatorService.php

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

+ 23 - 4
app/Services/WaybillService.php

@@ -4,6 +4,7 @@ namespace App\Services;
 
 use App\OwnerFeeDetail;
 use App\Services\common\QueryService;
+use App\Traits\ModelSearchWay;
 use App\Waybill;
 use App\WaybillAuditLog;
 use Illuminate\Database\Eloquent\Builder;
@@ -17,6 +18,7 @@ use App\Traits\ServiceAppAop;
 class WaybillService
 {
     use ServiceAppAop;
+    use ModelSearchWay;
     protected $modelClass=Waybill::class;
     /**
      * @param array $param
@@ -75,12 +77,29 @@ class WaybillService
             });
             unset($param["recipient_mobile"]);
         }
+
+        if($param['carrier_bill'] ?? false){    // 承运商单号
+            $this->searchWay($waybills,$param['carrier_bill'],'waybills.carrier_bill');
+            unset($param['carrier_bill']);
+        }
+        if($param['waybill_number'] ?? false) { // 运单号
+            $this->searchWay($waybills,$param['waybill_number'],'waybills.waybill_number');
+            unset($param['waybill_number']);
+        }
+        if($param['source_bill'] ?? false) {// 上游单号
+            $this->searchWay($waybills,$param['source_bill'],'waybills.source_bill');
+            unset($param['source_bill']);
+        }
+        if($param['wms_bill_number']?? false){ // wms单号
+            $this->searchWay($waybills,$param['wms_bill_number'],'waybills.wms_bill_number');
+            unset($param['wms_bill_number']);
+        }
         $columnQueryRules=[
-            'waybill_number' => ['like' => ''],
-            'carrier_bill' => ['like' => ''],
-            'wms_bill_number' => ['like' => ''],
+//            'waybill_number' => ['like' => ''],
+//            'carrier_bill' => ['like' => ''],
+//            'wms_bill_number' => ['like' => ''],
             'origination' => ['like' => ''],
-            'source_bill' => ['like' => ''],
+//            'source_bill' => ['like' => ''],
             'car_owner_info' => ['like' => ''],
             'created_at_start' => ['alias' => 'created_at' , 'startDate' => ':00'],
             'created_at_end' => ['alias' => 'created_at' , 'endDate' => ':59'],

+ 26 - 0
app/Traits/ModelSearchWay.php

@@ -0,0 +1,26 @@
+<?php
+
+
+namespace App\Traits;
+
+
+trait ModelSearchWay
+{
+    private function isSearchLike($str)
+    {
+        if (substr($str, 0, 1) == "%" || substr($str, strlen($str) - 1, 1) == "%") {
+            return true;
+        }
+        return false;
+    }
+
+    private function searchWay($query, $param, $column)
+    {
+        if ($this->isSearchLike($param)) {
+            $query->where($column, 'like', $param);
+        } else {
+            $query->whereIn($column, array_filter(preg_split('/[,, ]+/is', $param)));
+        }
+        return $query;
+    }
+}

+ 15 - 0
database/factories/CommodityBarcodeFactory.php

@@ -0,0 +1,15 @@
+<?php
+
+/** @var Factory $factory */
+
+use App\CommodityBarcode;
+use Faker\Generator as Faker;
+use Illuminate\Database\Eloquent\Factory;
+
+$factory->define(CommodityBarcode::class, function (Faker $faker) {
+    return [
+        'code'=> $faker->title(10).$faker->uuid,
+        'commodity_id'=>$faker->numberBetween(10,150000),
+        'created_at'=> now(),
+    ];
+});

+ 27 - 0
database/factories/DischargeTaskFactory.php

@@ -0,0 +1,27 @@
+<?php
+
+/** @var Factory $factory */
+
+use App\DischargeTask;
+use Faker\Generator as Faker;
+use Illuminate\Database\Eloquent\Factory;
+
+$factory->define(DischargeTask::class, function (Faker $faker) {
+    return [
+         'owner_id' => $faker->numberBetween(0, 10),
+        'type' => $faker->numberBetween(0, 1),
+        'numbers' => $faker->name(11),
+        'status' => $faker->numberBetween(0, 3),
+        'income_amount' => $faker->numberBetween(0, 20),
+        'income_unit' => $faker->numberBetween(0, 2),
+        'income_unit_price' => $faker->numberBetween(0, 10),
+        'income_total_cost' => $faker->numberBetween(0, 100),
+        'income_remark' => $faker->title(),
+        'discharge_provider_id' => $faker->numberBetween(0, 10),
+        'expenditure_amount' => $faker->numberBetween(0, 20),
+        'expenditure_unit' => $faker->numberBetween(0, 2),
+        'expenditure_unit_price' => $faker->numberBetween(0, 10),
+        'expenditure_total_cost' => $faker->numberBetween(0, 100),
+        'expenditure_remark' => $faker->title(),
+    ];
+});

+ 13 - 0
database/factories/FacilitatorFactory.php

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

+ 2 - 1
database/factories/OrderFactory.php

@@ -22,6 +22,7 @@ $factory->define(Order::class, function (Faker $faker) {
         'district'=>$faker->secondaryAddress,
         'address' => $faker->address,
         'wms_status' => $wms_status[rand(0,2)],
-        'wms_edittime' => $faker->dateTimeBetween( '-30 hour', 'now',  null)
+        'wms_edittime' => $faker->dateTimeBetween( '-30 hour', 'now',  null),
+        'owner_id' => $faker->numberBetween(0,10)
     ];
 });

+ 1 - 1
database/factories/OrderIssueFactory.php

@@ -17,7 +17,7 @@ $factory->define(OrderIssue::class, function (Faker $faker) {
         'order_id' =>function(){
             return factory(\App\Order::class)->create()->id;
         },
-        'created_at' => $faker->date('y-m-d'),
+        'created_at' => now(),
         'rejected_bill_id' => 0,
         'rejecting_status' => $rejecting_status[rand(0,count($rejecting_status)-1)],
         'result_explain' => $faker->text(20),

+ 27 - 0
database/factories/RejectedBillFactory.php

@@ -0,0 +1,27 @@
+<?php
+
+/** @var Factory $factory */
+
+use App\RejectedBill;
+use Faker\Generator as Faker;
+use Illuminate\Database\Eloquent\Factory;
+
+$factory->define(RejectedBill::class, function (Faker $faker) {
+    return [
+        'id_owner' => $faker->numberBetween(0),
+        'order_number' =>$faker->title(10),
+        'sender' => $faker->name,
+        'mobile_sender' => $faker->phoneNumber,
+        'logistic_number' => $faker->name,
+        'logistic_number_return' => $faker->name(2).$faker->numberBetween(100000000,999999999),
+        'id_logistic_return' => $faker->numberBetween(),
+//        'is_loaded' => null,
+        'fee_collected' => null,
+        'remark' => null,
+        'id_operator' => null,
+        'is_checked' => false,
+        'is_finished' => null,
+        'checked_numbers' => null,
+        'common_01' => null
+    ];
+});

+ 23 - 0
database/factories/RejectedBillItemFactory.php

@@ -0,0 +1,23 @@
+<?php
+
+/** @var Factory $factory */
+
+use App\RejectedBillItem;
+use Faker\Generator as Faker;
+use Illuminate\Database\Eloquent\Factory;
+
+$factory->define(RejectedBillItem::class, function (Faker $faker) {
+    return [
+        'id_rejected_bill' => $faker->numberBetween(0),
+        'barcode_goods' => $faker->colorName,
+        'name_goods' => $faker->name,
+        'amount' => $faker->numberBetween(0, 10),
+        'id_quality_label' => 1,
+        'batch_number' => null,
+        'validity_at' => null,
+        'made_at' => null,
+//        'is_checked' => null,
+        'remark' => null,
+        'is_loaded' => null
+    ];
+});

+ 53 - 0
database/migrations/2021_03_18_162505_create_discharge_tasks_table.php

@@ -0,0 +1,53 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateDischargeTasksTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('discharge_tasks', function (Blueprint $table) {
+
+            $table->bigIncrements('id');
+            $table->bigInteger('owner_id')->comment('货主id');
+            $table->bigInteger('facilitator_id')->default(null)->comment('服务商');
+
+            $table->tinyInteger('type')->comment('作业名称');
+            $table->string('numbers')->comment('入库单号');
+            $table->tinyInteger('status')->comment('状态');
+
+            $table->integer('income_amount')->comment('收入数量');
+            $table->tinyInteger('income_unit')->comment('收入单位');
+            $table->decimal('income_unit_price')->comment('收入单价');
+            $table->decimal('income_total_cost')->comment('收入合计');
+            $table->string('income_remark')->comment('收入描述');
+            $table->timestamp('income_at')->comment('任务创建时间');
+
+            $table->integer('expenditure_amount')->comment('支出数量');
+            $table->tinyInteger('expenditure_unit')->comment('支出单位');
+            $table->decimal('expenditure_unit_price')->comment('支出单价');
+            $table->decimal('expenditure_total_cost')->comment('支出合计');
+            $table->string('expenditure_remark')->comment('支出描述');
+            $table->timestamp('expenditure_at')->comment('任务接受时间');
+
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('discharge_tasks');
+    }
+}

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

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

+ 67 - 0
database/migrations/2021_03_19_102545_change_waybill_auth_and_add_discharge_task_auth.php

@@ -0,0 +1,67 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use app\Authority;
+
+class ChangeWaybillAuthAndAddDischargeTaskAuth extends Migration
+{
+    private $auths = [
+        '运输管理-卸货',
+        '运输管理-卸货-查询',
+        '运输管理-卸货-编辑',
+        '运输管理-卸货-创建',
+        '运输管理-卸货-删除',
+
+        '运输管理-卸货-结算报表-查询',
+
+        '服务商',
+        '服务商-查询',
+        '服务商-创建',
+        '服务商-编辑',
+        '服务商-删除',
+
+        '服务商-对账单-查询',
+
+    ];
+
+    private $changeAuths = [
+        '运输管理-查询' => '运输管理-运单-查询',
+        '运输管理-删除' => '运输管理-运单-删除',
+        '运输管理-运单审核' => '运输管理-运单-运单审核',
+        '运输管理-运单编辑' => '运输管理-运单-运单编辑',
+        '运输管理-录入' => '运输管理-运单-录入',
+        '运输管理-可见费用项' => '运输管理-运单-可见费用项',
+        '运输管理-运费' => '运输管理-运单-运费',
+        '运输管理-调度' => '运输管理-运单-调度',
+        '运输管理-置顶' => '运输管理-运单-置顶',
+
+        '运输管理-图片上传' => '运输管理-运单-图片上传',
+        '运输管理-图片删除' => '运输管理-运单-图片删除',
+        '运输管理-发运' => '运输管理-运单-发运',
+
+    ];
+
+    public function up()
+    {
+        foreach ($this->auths as $auth){
+            Authority::query()->firstOrCreate(["name"=>$auth,"alias_name"=>$auth]);
+        }
+        foreach ($this->changeAuths as $name=>$changeName) {
+            Authority::query()->where('name',$name)->update([
+                'name'=> $changeName,
+                'alias_name'=> $changeName,
+            ]);
+        }
+    }
+
+    public function down()
+    {
+        Authority::query()->whereIn('name',$this->auths);
+        foreach ($this->changeAuths as $changeName=>$name) {
+            Authority::query()->where('name',$name)->update([
+                'name'=> $changeName,
+                'alias_name'=> $changeName,
+            ]);
+        }
+    }
+}

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

@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddOrderIssueUserOwnerGroup extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_issues',function(Blueprint $table){
+            $table->integer('user_owner_group_id')->comment('项目组');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+        Schema::table('order_issues',function(Blueprint $table) {
+            $table->dropColumn('user_owner_group_id');
+        });
+    }
+}

+ 18 - 0
database/seeds/DischargeTaskSeeder.php

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

+ 18 - 0
database/seeds/FacilitatorSeeder.php

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

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

@@ -18,8 +18,8 @@
                     <span class="fa fa-calendar-check-o" style="color: #1b4b72"></span>
                     订单管理</a></li> @endcan
         @can('运输管理')
-            <li class="nav-item"><a href="{{url("waybill/index")}}" class="nav-link" target="waybill/index"
-                                    :class="{active:isActive('waybill',1)}">
+            <li class="nav-item"><a href="{{url("transport/waybill/index")}}" class="nav-link" target="transport/waybill/index"
+                                    :class="{active:isActive('transport',1)}">
                     <span class="fa fa-truck" style="color: #4c2584"></span>
                     运输管理</a></li> @endcan
         @can('称重管理')

+ 29 - 0
resources/views/maintenance/facilitator/_create.blade.php

@@ -0,0 +1,29 @@
+<div class="modal" id="createdModal" tabindex="-1">
+    <div class="modal-dialog modal-dialog-centered ">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title text-center">服务商添加</h5>
+                <button type="button" class="close" data-dismiss="modal" @click="createFacilitator={}">
+                    <span>&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form class="form">
+                    <div class="form-group row" >
+                        <label for="add-name" class="col-sm-3 col-form-label text-right">服务商名称</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="text" class="form-control col-sm-12" v-model="createFacilitator.name" placeholder="输入服务商名称" :class="facilitatorError.name? 'is-invalid' :''">
+                            <div class="invalid-feedback" >
+                                @{{ facilitatorError['name'] ? facilitatorError['name'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary"  data-dismiss="modal" @click="createFacilitator={}">关闭</button>
+                <button type="button" class="btn btn-primary" @click="storeFacilitator">提交</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 29 - 0
resources/views/maintenance/facilitator/_edit.blade.php

@@ -0,0 +1,29 @@
+<div class="modal" id="updatedModal" tableindex="-1">
+    <div class="modal-dialog modal-dialog-centered">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title text-center">服务商添加</h5>
+                <button type="button" class="close" data-dismiss="modal" @click="editFacilitator={},selectIndex=null,facilitatorError={}">
+                    <span>&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form class="form">
+                    <div class="form-group row" >
+                        <label for="add-name" class="col-sm-3 col-form-label text-right">服务商名称</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="text" class="form-control col-sm-12" v-model="editFacilitator.name" placeholder="输入服务商名称" :class="facilitatorError.name? 'is-invalid' :''">
+                            <div class="invalid-feedback" >
+                                @{{ facilitatorError['name'] ? facilitatorError['name'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary"  data-dismiss="modal" @click="editFacilitator={},selectIndex=null,facilitatorError={}">关闭</button>
+                <button type="button" class="btn btn-primary" @click="updateFacilitator">提交</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 34 - 0
resources/views/maintenance/facilitator/_table.blade.php

@@ -0,0 +1,34 @@
+<table class="table table-sm table-striped table-bordered table-hover card-body p-0 m-0">
+    <tr class="text-center">
+        <th>序号</th>
+        <th>服务商名称</th>
+        <th>创建时间</th>
+        <th>操作</th>
+    </tr>
+
+    <template v-if="facilitators.length > 0">
+        <tr v-for="(facilitator,index) in facilitators" class="text-center"  @click="selectTr===index+1?selectTr=0:selectTr=index+1" :class="selectTr===index+1?'focusing' : ''">
+            <td>@{{ index+1 }}</td>
+            <td>@{{ facilitator.name }}</td>
+            <td>@{{ facilitator.created_at }}</td>
+            <td>
+                @can('服务商-编辑')
+                <button class="btn btn-sm btn-outline-primary" @click="showUpDateModal(true,index,facilitator)">编辑
+                @endcan
+                </button>
+                @can('服务商-删除')
+                <button class="btn btn-sm btn-outline-danger" @click="destroyFacilitator(facilitator,index)">删除</button>
+                @endcan
+            </td>
+        </tr>
+    </template>
+    <template v-else>
+        <tr>
+            <td colspan="4">
+                <div class="alert alert-info text-lg-center">
+                    服务商数据为空
+                </div>
+            </td>
+        </tr>
+    </template>
+</table>

+ 151 - 0
resources/views/maintenance/facilitator/index.blade.php

@@ -0,0 +1,151 @@
+@extends('layouts.app')
+
+@section('title','服务商')
+
+@section('content')
+    <nav class="nav2">
+        @component('maintenance.menu')@endcomponent
+    </nav>
+    <div class="container-fluid d-none" id="facilitator">
+        <div class="card">
+            @can('服务商-创建')
+            @include('maintenance.facilitator._create')
+            @endcan
+            @can('服务商-编辑')
+            @include('maintenance.facilitator._edit')
+            @endcan
+            <div class="card-body">
+                <div class="row pull-left m-1">
+                    <button class="btn btn-outline-info mb-1 mr-3" @click="showCreatedModal(true)"><span class="fa fa-plus"></span>&nbsp;新&nbsp;&nbsp;增</button>
+                </div>
+            </div>
+            @include('maintenance.facilitator._table')
+        </div>
+    </div>
+@endsection
+
+@section('lastScript')
+    <script>
+        let facilitatorVue = new Vue({
+            el:'#facilitator',
+            data:{
+                facilitators:{!! $facilitators->toJson() !!}['data'],
+                checkData:[],
+                createFacilitator:{},
+                editFacilitator:{},
+                selectIndex:null,
+                facilitatorError:{},
+                selectTr:0,
+            },
+            watch:{
+                checkData: {
+                    handler() {
+                        if (this.facilitators.length === this.checkData.length) {
+                            document.querySelector('#selectAll').checked = true;
+                        } else {
+                            document.querySelector('#selectAll').checked = false;
+                        }
+                    },
+                    deep: true
+                },
+            },
+            created(){
+
+            },
+            mounted() {
+                $('#facilitator').removeClass('d-none');
+            },
+            methods:{
+                checkAll(e) {
+                    if (!e.target.checked) this.checkData = [];
+                    else {
+                        this.providerStatements.forEach((item, i) => {
+                            if (this.checkData.indexOf(item.id) === -1) this.checkData.push(item.id);
+                        });
+                    }
+                },
+                // 显示隐藏添加页面
+                showCreatedModal(isDisplay){
+                    this.createFacilitator = {};
+                    if(isDisplay){
+                        $('#createdModal').modal('show');
+                    }else{
+                        $('#createdModal').modal('hide');
+                    }
+                },
+                // 显示隐藏更新页面
+                showUpDateModal(isDisplay,index = null,facilitator = {}){
+                    this.selectIndex = index;
+                    this.editFacilitator = JSON.parse(JSON.stringify(facilitator));
+                    if(isDisplay){
+                        $('#updatedModal').modal('show');
+                    }else{
+                        this.selectIndex = null;
+                        $('#updatedModal').modal('hide');
+                    }
+                },
+                // 创建服务商
+                storeFacilitator(){
+                    let url = '{{url('apiLocal/facilitator/store')}}';
+                    tempTip.setIndex(999);
+                    tempTip.setDuration(1999);
+                    axios.post(url,this.createFacilitator).then(res=>{
+                        if(res.data.success){
+                            this.facilitators.unshift(res.data.data);
+                            tempTip.showSuccess('添加服务商成功');
+                            this.showCreatedModal(false)
+                            return ;
+                        }else if(res.data.error){
+                            this.facilitatorError = res.data.error;
+                            return
+                        }
+                        tempTip.show(res.data.data);
+                    }).catch(err=>{
+                        tempTip.show('服务商添加异常'+err);
+                    });
+                },
+                // 更新服务商
+                updateFacilitator(){
+                    let url = '{{url('apiLocal/facilitator/update')}}';
+                    tempTip.setIndex(999);
+                    tempTip.setDuration(1999);
+                    axios.put(url,this.editFacilitator).then(res=>{
+                        if(res.data.success){
+                            this.$set(this.facilitators,this.selectIndex,res.data.data);
+                            tempTip.showSuccess('服务商更新成功');
+                            this.showUpDateModal(false);
+                            return ;
+                        }else if(res.data.error){
+                            this.facilitatorError = res.data.error;
+                            return
+                        }
+                        tempTip.show(res.data.data);
+                    }).catch(err=>{
+                        tempTip.show(''+err);
+                    });
+                },
+                // 删除服务商
+                destroyFacilitator(facilitator,index){
+                    let url = '{{url('apiLocal/facilitator/destroy?id=')}}'+facilitator['id'];
+                    tempTip.setIndex(999);
+                    tempTip.setDuration(1999);
+                    axios.delete(url).then(res=>{
+                        if(res.data.success){
+                            tempTip.showSuccess("服务商删除成功");
+                            this.$delete(this.facilitators,index);
+                            return ;
+                        }else if(res.data.error){
+                            tempTip.show(res.data.error.id[0]);
+                            return ;
+                        }
+                        tempTip.show(res.data.data ?? '删除异常');
+                    }).catch(err=>{
+                        tempTip.show(err);
+                    })
+                }
+            }
+        });
+
+    </script>
+@endsection
+

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

@@ -123,6 +123,11 @@
                 <li class="nav-item">
                     <a class="nav-link text-muted" href="{{url('maintenance/configuration')}}" :class="{active:isActive('configuration',2)}">系统配置</a>
                 </li>@endcan
+            @can('服务商')
+                <li class="nav-item">
+                    <a class="nav-link text-muted" href="{{url('maintenance/facilitator')}}" :class="{active:isActive('facilitator',2)}">服务商</a>
+                </li>
+            @endcan
         </ul>
     </div>
 </div>

+ 10 - 0
resources/views/order/issue/edit.blade.php

@@ -133,6 +133,15 @@
                         </select>
                     </div>
                 </div>
+                <div class="form-group row">
+                    <label class="col-2 col-form-label text-right">事故责任方</label>
+                    <div class="col-8">
+                        <select name="user_owner_group_id" class="form-control" id="user_owner_group_id" v-model="orderIssues.user_owner_group_id">
+                            <option value></option>
+                            <option v-for="userOwnerGroup in userOwnerGroups" :value="userOwnerGroup.id">@{{ userOwnerGroup.name }}</option>
+                        </select>
+                    </div>
+                </div>
                 <div class="form-group row">
                     <label class="col-2 col-form-label text-right"></label>
                     <div class="col-8">
@@ -158,6 +167,7 @@
                 owners:{!! $owners  !!},
                 logistics:{!! $logistics !!},
                 userWorkgroup: {!! $userWorkgroup !!},
+                userOwnerGroups:{!! $userOwnerGroups !!},
                 shops:{!! $shops !!},
                 orderIssueType:{!! $orderIssueType !!},
                 rejectingStatus: ['无', '未退回', '全部退回', '部分退回', '差异退回', '超量退回'],

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

@@ -160,7 +160,8 @@
                         <th class="three-layer  align-middle" rowspan="2" style="min-width: 120px">宝时赔偿金额</th>
                         <th class="three-layer  align-middle" rowspan="2" style="min-width: 120px">宝时快递减免</th>
                         @cannot('订单管理-问题件-客户不可见')
-                        <th class="three-layer  align-middle" rowspan="2" style="min-width: 200px">事故责任方</th>
+                        <th class="three-layer  align-middle" rowspan="2" style="min-width: 200px">仓库组责任方</th>
+                        <th class="three-layer  align-middle" rowspan="2" style="min-width: 200px">项目组责任方</th>
                         <th class="align-middle" rowspan="2" style="min-width: 120px">操作</th>
                         @endcannot
                     </tr>
@@ -417,7 +418,7 @@
                                             <td class="text-muted" style="min-width: 170px">@{{ log.created_at }}</td>
                                             @can('订单管理-问题件-处理结果删除')
                                                 <td style="" class="m-0 p-0 border-0">
-                                                    <button type="button" class="btn btn-sm btn-outline-danger m-0 del-btn invisible" @click="deleteOrderIssueLog(log,orderIssue.id)">删</button>
+                                                    <button type="button" class="btn btn-sm btn-outline-danger m-0 del-btn invisible" @click="deleteOrderIssueLog(log,orderIssue,index,logIndex)">删</button>
                                                 </td>
                                             @endcan
                                         </template>
@@ -580,6 +581,16 @@
                                 </table>
 
                             </td>
+                        <td>
+                            @can('订单管理-问题件-编辑')
+                                <select v-model="orderIssue.user_owner_group_id" class="form-control form-control-sm" @change="updateOrderIssue(orderIssue,'user_owner_group_id',$event)">
+                                    <option ></option>
+                                    <option v-for="(userOwnerGroup,index) in userOwnerGroups" :value="userOwnerGroup.name">@{{ userOwnerGroup.value }}</option>
+                                </select>
+                            @else
+                                @{{ orderIssue.user_owner_group ?? orderIssue.user_owner_group.name : '' }}
+                            @endcan
+                        </td>
                             <td>
                                 @can('订单管理-问题件-编辑')
                                     <a :href="'edit/'+orderIssue.id"  class="btn btn-sm btn-outline-primary" target="_blank">改</a>
@@ -778,6 +789,7 @@
                         @foreach($userWorkgroup as $item)
                     {name:{{$item->id}},value:'{{$item->name}}'},
                     @endforeach],
+                userOwnerGroups:{!! $userOwnerGroups !!},
                 rejectingStatus: [
                     {name:'无',value:'无'},
                     {name:'未退回',value:'未退回'},
@@ -826,6 +838,9 @@
                     _this.regroupLogs(orderIssue);
                     _this.regroupUserGroup(orderIssue);
                 });
+                this.userOwnerGroups.forEach(function(item,index,array){
+                    array[index] = {name:item.id,value:item.name};
+                });
             },
             mounted: function () {
                 $(".tooltipTarget").tooltip({'trigger':'hover'});
@@ -903,6 +918,7 @@
                     {name: 'rejectingStatus', type: 'select', tip: '退单状态',placeholder: '退单状态',data:this.rejectingStatus},
                     {name: 'sendOrderClientCode', type: 'input', tip: '二次客户订单号',placeholder: '二次客户订单号'},
                     {name: 'sendOrderLogisticNumber', type: 'input', tip: '二次运单号',placeholder: '二次运单号'},
+                    {name: 'user_owner_group_id', type: 'select', tip: '项目责任方',placeholder: '项目责任方',data:this.userOwnerGroups},
                 ]];
                 this.form = new query({
                     el: '#form_div',
@@ -1232,8 +1248,7 @@
                         tempTip.show('网络异常:' + err);
                     });
                 },
-                deleteOrderIssueLog(log, OrderIssueId) {
-                    let _this = this;
+                deleteOrderIssueLog(log, orderIssue,index,logIndex) {
                     if(!confirm('是否删除当前记录'))return;
                     if(log.type === '创建'){
                         tempTip.show('创建记录不能删除');
@@ -1241,13 +1256,8 @@
                     }
                     axios.post("{{url('apiLocal/order/issue/log/destroy')}}", {id: log.id}).then(function (res) {
                         if (res.data.success) {
-                            _this.orderIssues.forEach(function (orderIssue) {
-                                if (orderIssue.id == OrderIssueId) {
-                                    orderIssue.logs.forEach(function (item, index) {
-                                        if (item.id == log.id)orderIssue.logs.splice(index, 1);
-                                    });
-                                }
-                            })
+                            if(log.type ==='结束')orderIssue.final_status = '';
+                            orderIssue.logs.splice(logIndex,1);
                             tempTip.setDuration(2000);
                             tempTip.showSuccess('删除成功');
                             return;

+ 2 - 11
resources/views/process/index.blade.php

@@ -165,10 +165,10 @@
         <table class="table table-sm text-nowrap table-bordered" id="headerParent">
             <tr class="row-even p-0" id="header"></tr>
             <template>
-            <tr v-for="(processOne,i) in processes" :class="count(i,processes)%2==0?'row-even':''" :id="processOne.id?processOne.id:processes[i-1].id+'-2'"
+            <tr v-for="(processOne,i) in processes" :class="[(count(i,processes)%2===0?'row-even':'' ),selectTr===i+1?'focusing':'']" :id="processOne.id?processOne.id:processes[i-1].id+'-2'"
                 :name="'process_table_'+count(i,processes)" @mouseover="changeStyle('process_table_'+count(i,processes),true)"
                 @mouseout="changeStyle('process_table_'+count(i,processes),false)"
-                @click="selectTableRow(i,$event)"
+                @click="selectTr===i+1?(selectTr=0):selectTr=i+1"
             >
                 <td v-if="processOne.id" :rowspan="processOne.is_multi_row?2:''">
                     <input class="checkItem" type="checkbox" :value="processOne.id" v-model="checkData">
@@ -596,15 +596,6 @@
                 },0);
             },
             methods: {
-                selectTableRow(id,e){
-                    $('#headerParent tr[class=focusing]').removeClass('focusing')
-                    if (id === this.selectTr) {
-                        this.selectTr = '';
-                        return;
-                    }
-                    this.selectTr = id;
-                    $(e.target).parent('tr').addClass('focusing')
-                },
                 arrayFilter: function (processesContents, process) {
                     if (!process.is_multi_row && process.id) return processesContents;
                     let array = [];

+ 35 - 0
resources/views/transport/discharge/facilitator/_table.blade.php

@@ -0,0 +1,35 @@
+<table class="table table-sm table-striped table-bordered table-hover card-body p-0 m-0">
+    <tr class="text-center">
+        <th><input type="checkbox" class="form-check" name="selectAll" id="selectAll" @click="checkAll" ></th>
+        <th>序号</th>
+        <th>日期</th>
+        <th>服务商</th>
+        <th>数量</th>
+        <th>单位</th>
+        <th>单价</th>
+        <th>总金额合计</th>
+    </tr>
+    <template v-if="facilitatorStatements.length>0">
+        <tr v-for="(facilitatorStatement,index) in facilitatorStatements" :key="index" class="text-center" @click="selectTr===index+1?selectTr=0:selectTr=index+1" :class="selectTr===index+1?'focusing' : ''">
+            <td><input type="checkbox" class="form-check" :value="facilitatorStatement.id" v-model="checkData"></td>
+            <td>@{{index+1}}</td>
+            <td>@{{ facilitatorStatement.created_at }}</td>
+            <td>@{{ facilitatorStatement.facilitator ? facilitatorStatement.facilitator.name : '' }}</td>
+            <td>@{{ facilitatorStatement.expenditure_amount }}</td>
+            <td>@{{ facilitatorStatement.expenditure_unit }}</td>
+            <td>@{{ facilitatorStatement.expenditure_unit_price }}</td>
+            <td>@{{ facilitatorStatement.expenditure_total_cost }}</td>
+        </tr>
+    </template>
+    <template v-else>
+        <tr>
+            <td colspan="8">
+                <div class='alert alert-info text-lg-center' >
+                    服务商对账单数据为空
+                </div>
+            </td>
+        </tr>
+    </template>
+    {{ $facilitatorStatements->withQueryString()->links() }}
+</table>
+<hr>

+ 106 - 0
resources/views/transport/discharge/facilitator/index.blade.php

@@ -0,0 +1,106 @@
+@extends('layouts.app')
+
+@section('title','卸货服务商')
+
+@section('content')
+    <div id="nav2">
+        @component('transport.menu')@endcomponent
+        @component('transport.discharge.menu')@endcomponent
+        @component('transport.discharge.facilitator.menu')@endcomponent
+    </div>
+    <div id="list" class="d-none container-fluid">
+        <div id="form_div"  style="min-width: 2250px"></div>
+        <div class="form-inline mt-1" id="btn">
+            <span class="dropdown">
+                <button type="button" class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget"
+                        :class="[checkData.length>0?'btn-dark text-light':'']"
+                        data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">导出Excel
+                </button>
+                <div class="dropdown-menu">
+                    <a class="dropdown-item" @click="Export(false)" href="javascript:">导出勾选内容</a>
+                    <a class="dropdown-item" @click="Export(true)" href="javascript:">导出所有页</a>
+                </div>
+            </span>
+            @include('transport.discharge.facilitator._table')
+        </div>
+    </div>
+@endsection
+
+@section('lastScript')
+    <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+
+    <script>
+        let ProviderVue = new Vue({
+            el:"#list",
+            data:{
+                facilitatorStatements:{!! $facilitatorStatements->toJson() !!}['data'],
+                facilitators:{!! $facilitators !!},
+                units:{0:'m3',1:'吨',2:'托',3:'件'},
+                checkData:[],
+                selectTr:0,
+            },
+            watch: {
+                checkData: {
+                    handler() {
+                        if (this.checkData.length === this.facilitatorStatements.length) {
+                            document.querySelector('#selectAll').checked = true;
+                        } else {
+                            document.querySelector('#selectAll').checked = false;
+                        }
+                    },
+                    deep: true
+                },
+            },
+            created(){
+                let _this = this;
+                this.facilitatorStatements.forEach(function(facilitatorStatement,index,array){
+                    array[index]['expenditure_unit'] = _this.units[facilitatorStatement['expenditure_unit']];
+                });
+                this.facilitators.forEach(function(provider,index,array){
+                    array[index] = {
+                        name:provider.id,
+                        value:provider.name,
+                    }
+                });
+            },
+            mounted(){
+                let _this = this;
+                $('#list').removeClass('d-none');
+                $(".tooltipTarget").tooltip({'trigger': 'hover'});
+                let data = [[
+                    {
+                        name: 'facilitator_id', type: 'select_multiple_select', tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的服务商'],
+                        placeholder: ['服务商', '服务商'],
+                        data: _this.facilitators
+                    },
+                    {name: 'created_at_start', type: 'dateTime', tip: '创建开始日期'},
+                    {name: 'created_at_end', type: 'dateTime', tip: '创建结束日期'},
+                ]];
+                this.form = new query({
+                    el: '#form_div',
+                    condition: data,
+                    appendDom : "btn",
+                    paginations:[ 50, 100, 200, 500,1000,20],
+                })
+                this.form.init();
+            },
+            methods:{
+                checkAll(e) {
+                    if (!e.target.checked) this.checkData = [];
+                    else {
+                        this.facilitatorStatements.forEach((item, i) => {
+                            if (this.checkData.indexOf(item['id']) === -1) this.checkData.push(item['id']);
+                        });
+                    }
+                },
+                Export(isExportAll) {
+                    let url = '{{url('transport/discharge/facilitator/export')}}';
+                    let token = '{{ csrf_token() }}';
+                    excelExport(isExportAll, this.checkData, url, this.sum, token);
+                },
+            }
+        })
+    </script>
+
+@endsection

+ 17 - 0
resources/views/transport/discharge/facilitator/menu.blade.php

@@ -0,0 +1,17 @@
+<div class="container-fluid" >
+
+    <div class="card">
+        <ul class="nav nav-pills">
+            @can('服务商-查询')
+            <li class="nav-item">
+                <a target="transport/discharge/provider/index" class="nav-link" href="{{url('transport/discharge/facilitator/index')}}" :class="{active:isActive('index',4)}">对账单</a>
+            </li>
+            @endcan
+            @can('服务商')
+            <li class="nav-item">
+                <a target="maintenance/facilitator" class="nav-link text-dark" href="{{url('maintenance/facilitator')}}" :class="{active:isActive('facilitator',2)}">基础设置</a>
+            </li>
+            @endcan
+        </ul>
+    </div>
+</div>

+ 21 - 0
resources/views/transport/discharge/menu.blade.php

@@ -0,0 +1,21 @@
+<div class="container-fluid nav3" >
+    <div class="card">
+        <ul class="nav nav-pills">
+            @can('运输管理-卸货')
+            <li class="nav-item">
+                <a target="transport/discharge/task" class="nav-link" href="{{url('transport/discharge/task/index')}}" :class="{active:isActive('task',3)}">卸货任务</a>
+            </li>
+            @endcan
+            @can('运输管理-卸货-结算报表-查询')
+            <li class="nav-item">
+                <a target="transport/discharge/statement" class="nav-link" href="{{url('transport/discharge/statement/index')}}" :class="{active:isActive('statement',3)}">计算报表</a>
+            </li>
+            @endcan
+            @can('服务商-对账单-查询')
+            <li class="nav-item">
+                <a target="transport/discharge/provider" class="nav-link" href="{{url('transport/discharge/facilitator/index')}}" :class="{active:isActive('facilitator',3)}">服务商</a>
+            </li>
+            @endcan
+        </ul>
+    </div>
+</div>

+ 59 - 0
resources/views/transport/discharge/statement/_table.blade.php

@@ -0,0 +1,59 @@
+<table class="table table-sm table-striped table-bordered table-hover card-body p-0 m-0">
+    <tr class="text-center">
+        <th class="" colspan="1"></th>
+        <th class="td-helpful" colspan="4">作业信息</th>
+        <th class="td-cool" colspan="4">收入信息</th>
+        <th class="" colspan="5">支出信息</th>
+        <th class="td-yellow" colspan="3">其他信息</th>
+    </tr>
+    <tr class="text-center" >
+        <th><input type="checkbox" class="form-check" name="selectAll" id="selectAll" @click="checkAll"/></th>
+        <th class="td-helpful">序号</th>
+        <th class="td-helpful">日期</th>
+        <th class="td-helpful">作业名称</th>
+        <th class="td-helpful">入库单号</th>
+        <th class="td-cool">数量</th>
+        <th class="td-cool">单位</th>
+        <th class="td-cool">收入单价</th>
+        <th class="td-cool">收入合计</th>
+        <th>服务商</th>
+        <th>数量</th>
+        <th>单位</th>
+        <th>支出单价</th>
+        <th>支出合计</th>
+        <th class="td-yellow">状态</th>
+        <th class="td-yellow">收入备注</th>
+        <th class="td-yellow">支出备注</th>
+    </tr>
+    <template v-if="dischargeStatements.length > 0">
+        <tr v-for="(dischargeTask,index) in dischargeStatements" class="text-center"  @click="selectTr===index+1?selectTr=0:selectTr=index+1" :class="selectTr===index+1?'focusing' : ''">
+            <td ><input type="checkbox" class="form-check" :value="dischargeTask.id" v-model="checkData"></td>
+            <td class="td-helpful">@{{ index+1 }}</td>
+            <td class="td-helpful">@{{ dischargeTask.created_at }}</td>
+            <td class="td-helpful">@{{ dischargeTask.type }}</td>
+            <td class="td-helpful">@{{ dischargeTask.numbers }}</td>
+            <td class="td-cool">@{{ dischargeTask.income_amount }}</td>
+            <td class="td-cool">@{{ dischargeTask.income_unit }}</td>
+            <td class="td-cool">@{{ dischargeTask.income_unit_price }}</td>
+            <td class="td-cool">@{{ dischargeTask.income_total_cost }}</td>
+
+            <td>@{{ dischargeTask.facilitator ? dischargeTask.facilitator.name : ''  }}</td>
+            <td>@{{ dischargeTask.expenditure_amount }}</td>
+            <td>@{{ dischargeTask.expenditure_unit }}</td>
+            <td>@{{ dischargeTask.expenditure_unit_price }}</td>
+            <td class="">@{{ dischargeTask.expenditure_total_cost }}</td>
+            <td class="td-yellow">@{{ dischargeTask.status }}</td>
+            <td class="td-yellow">@{{ dischargeTask.income_remark }}</td>
+            <td class="td-yellow">@{{ dischargeTask.expenditure_remark }}</td>
+        </tr>
+    </template>
+
+    <template v-else>
+        <tr>
+           <td colspan="17">
+               <div class='alert alert-info text-lg-center'>结算报表数据为空</div>
+           </td>
+        </tr>
+    </template>
+</table>
+<hr>

+ 110 - 0
resources/views/transport/discharge/statement/index.blade.php

@@ -0,0 +1,110 @@
+@extends('layouts.app')
+
+@section('title','结算报表')
+
+@section('content')
+    <div id="nav2">
+        @component('transport.menu')@endcomponent
+        @component('transport.discharge.menu')@endcomponent
+    </div>
+    <div id="list" class="d-none container-fluid">
+        <div id="form_div" style="min-width: 2250px"></div>
+
+        <div class="form-inline mt-1" id="btn">
+            <span class="dropdown">
+                <button type="button" class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget"
+                        :class="[checkData.length>0?'btn-dark text-light':'']"
+                        data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">导出Excel
+                </button>
+                <div class="dropdown-menu">
+                    <a class="dropdown-item" @click="StatementsExport(false)" href="javascript:">导出勾选内容</a>
+                    <a class="dropdown-item" @click="StatementsExport(true)" href="javascript:">导出所有页</a>
+                </div>
+            </span>
+            @include('transport.discharge.statement._table')
+        </div>
+    </div>
+@endsection
+
+@section('lastScript')
+    <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+    <script>
+        let statementVue = new Vue({
+            el: '#list',
+            data: {
+                dischargeStatements: {!! $dischargeStatements->toJson() !!}['data'],
+                facilitators:{!! $facilitators !!},
+                owners:{!! $owners !!},
+                checkData: [],
+                taskTypes: {0: "装车", 1: "卸车"},
+                units: {0: 'm3', 1: '吨', 2: '件', 3: '托'},
+                status: {0: '创建', 1: '接单', 2: '作业中', 3: '完成'},
+                selectTr:0,
+            },
+            created() {
+                let _this = this;
+                this.dischargeStatements.forEach(function (item, index, array) {
+                    array[index]['status'] = _this.status[item['status']];
+                    array[index]['income_unit'] = _this.units[item['income_unit']];
+                    array[index]['expenditure_unit'] = _this.units[item['expenditure_unit']];
+                    array[index]['type'] = _this.taskTypes[item['type']];
+                });
+                this.owners.forEach(function (item, index, array) {
+                    array[index] = {name: item.id, value: item.name,};
+                })
+                this.facilitators.forEach(function(item, index, array){
+                    array[index] = {name:item.id,value:item.name};
+                })
+            },
+            mounted() {
+                $('#list').removeClass('d-none');
+                $(".tooltipTarget").tooltip({'trigger': 'hover'});
+                // 货主 创建日期 入库单号 状态 入库备注
+                let _this = this;
+                let status = [{name: 0, value: '创建'}, {name: 1, value: '接单'}, {name: 2, value: '作业中'}, {name: 3, value: '完成'}];
+                let data = [[
+                    {
+                        name: 'owner_id', type: 'select_multiple_select', tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的客户'],
+                        placeholder: ['货主', '定位或多选货主'],
+                        data: _this.owners
+                    },
+                    {name: 'created_at_start', type: 'dateTime', tip: '创建开始日期'},
+                    {name: 'created_at_end', type: 'dateTime', tip: '创建结束日期'},
+                    {name: 'numbers', type: 'input', tip: '入库单号', placeholder: '入库单号'},
+                    {name: 'status', type: 'select', tip: '状态', data: status, placeholder: '状态'},
+                ], [
+                    {
+                        name: 'facilitator_id', type: 'select_multiple_select', tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的服务商'],
+                        placeholder: ['服务商', '定位或多选服务商'],
+                        data: _this.facilitators
+                    },
+                    {name: 'income_remark', type: 'input', tip: '备注', data: _this.status, placeholder: '支出备注'},
+                    {name: 'income_remark', type: 'input', tip: '备注', data: _this.status, placeholder: '收入备注'},
+                ]];
+                this.form = new query({
+                    el: '#form_div',
+                    condition: data,
+                    appendDom: "btn",
+                    paginations: [50, 100, 200, 500, 1000, 20],
+                })
+                this.form.init();
+            },
+            methods: {
+                checkAll(e) {
+                    if (!e.target.checked) this.checkData = [];
+                    else {
+                        this.dischargeStatements.forEach((item, i) => {
+                            if (this.checkData.indexOf(item['id']) === -1) this.checkData.push(item['id']);
+                        });
+                    }
+                },
+                StatementsExport(isExportAll) {
+                    let url = '{{url('transport/discharge/statement/export')}}';
+                    let token = '{{ csrf_token() }}';
+                    excelExport(isExportAll, this.checkData, url, this.sum, token);
+                }
+            }
+        });
+    </script>
+@endsection

+ 12 - 0
resources/views/transport/discharge/statement/menu.blade.php

@@ -0,0 +1,12 @@
+<div class="container-fluid">
+    <div class="card">
+        <ul class="nav nav-pills">
+            @can('服务商-对账单-查询')
+            <li class="nav-item">
+                <a target="transport/discharge/statement/index" class="nav-link" href="{{url('transport/discharge/statement/index')}}" :class="{active:isActive('recycle',2)}">查询</a>
+            </li>
+            @endcan
+        </ul>
+
+    </div>
+</div>

+ 120 - 0
resources/views/transport/discharge/task/_createTask.blade.php

@@ -0,0 +1,120 @@
+<div class="modal fade" id="createdModal">
+    <div class="modal-dialog modal-dialog-centered modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title text-center text-uppercase">
+                    <span v-show="isUpdate">卸货任务修改</span>
+                    <span v-show="!isUpdate">卸货任务添加</span>
+                </h5>
+                <button type="button" class="close" data-dismiss="modal" @click="addTask={},isUpdate=false,taskError={}">
+                    <span>&times;</span>
+                </button>
+            </div>
+
+            <div class="modal-body">
+                <form class="form">
+                    <div class="form-group row">
+                        <label for="addTask-owner-id" class="col-sm-3 col-form-label text-right">货主</label>
+                        <div class="col-sm-5">
+                            <select id="addTask-owner-id" class="form-control" v-model="addTask.owner_id" :class="taskError.owner_id? 'is-invalid' :''">
+                                <option v-for="(owner,index) in ownerFilter" :value="owner.name" :key="owner+index">@{{ owner.value }}</option>
+                            </select>
+                            <div class="invalid-feedback" >
+                                @{{ taskError['owner_id'] ? taskError['owner_id'][0] : '' }}
+                            </div>
+                        </div>
+                        <div class="col-3 ">
+                            <input class="form-control " placeholder="输入货主进行刷选" @change="filterOwner($event)">
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="addTask-created-at" class="col-sm-3 col-form-label text-right">预约日期</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="date" id="addTask-created-at" class="form-control col-9" name="size" v-model="addTask.income_at" >
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="addTask-type" class="col-sm-3 col-form-label text-right" >作业名称</label>
+                        <div class="col-sm-9 form-inline">
+                            <select id="addTask-type" class="form-control col-4" v-model="addTask.type" :class="taskError.type? 'is-invalid' :''">
+                                <option v-for="(type,index) in taskTypes" :value="type.name" :key="type+index">@{{
+                                    type.value }}
+                                </option>
+                            </select>
+                            <div class="invalid-feedback" >
+                                @{{ taskError['type'] ? taskError['type'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="addTask-numbers" class="col-sm-3 col-form-label text-right">入库单</label>
+                        <div class="col-sm-9 form-inline" >
+                            <input type="text" id="addTask-numbers" class="form-control col-9" name="size" v-model="addTask.numbers" :class="taskError.numbers? 'is-invalid' :''">
+                            <div class="invalid-feedback" >
+                                @{{ taskError['numbers'] ? taskError['numbers'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="addTask-amount" class="col-sm-3 col-form-label text-right">数量</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="number" id="addTask-amount" class="form-control col-9" name="size" v-model="addTask.income_amount" :class="taskError.income_amount? 'is-invalid' :''">
+                            <div class="invalid-feedback" >
+                                @{{ taskError['income_amount'] ? taskError['income_amount'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="addTask-amount" class="col-sm-3 col-form-label text-right">单位</label>
+                        <div class="col-sm-9 form-inline">
+                            <select id="addTask-type" class="form-control col-4" v-model="addTask.income_unit" :class="taskError.income_unit? 'is-invalid' :''">
+                                <option v-for="(unit,index) in units" :value="unit.name" :key="unit+index">@{{ unit.value }}</option>
+                            </select>
+                            <div class="invalid-feedback" >
+                                @{{ taskError['income_unit'] ? taskError['income_unit'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="addTask-income-unit-price" class="col-sm-3 col-form-label text-right">单价</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="number" id="addTask-income-unit-price" class="form-control col-9" v-model="addTask.income_unit_price" :class="taskError.income_unit_price? 'is-invalid' :''">
+                            <div class="invalid-feedback" >
+                                @{{ taskError['income_unit_price'] ? taskError['income_unit_price'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row" v-show="isUpdate">
+                        <label for="addTask-income-total-cost" class="col-sm-3 col-form-label text-right">总价</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="number" id="addTask-income-total-cost" class="form-control col-9" v-model="addTask.income_total_cost">
+                        </div>
+                    </div>
+
+
+                    <div class="form-group row">
+                        <label for="addTask-amount" class="col-sm-3 col-form-label text-right">备注</label>
+                        <div class="col-sm-9 form-inline">
+                            <textarea class="form-control col-9" v-model="addTask.income_remark"></textarea>
+                        </div>
+                    </div>
+                </form>
+            </div>
+
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal" @click="addTask={},isUpdate=false,taskError={}">关闭</button>
+                <button type="button" class="btn btn-primary" v-show="isUpdate" @click="updateCurrentTask(addTask,selectIndex)">提交
+                </button>
+                <button type="button" class="btn btn-primary" v-show="!isUpdate" @click="createTask">创建</button>
+            </div>
+        </div>
+    </div>
+
+</div>

+ 86 - 0
resources/views/transport/discharge/task/_executeTask.blade.php

@@ -0,0 +1,86 @@
+<div class="modal fade" id="executingTaskModal">
+    <div class="modal-dialog modal-dialog-centered modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title text-center text-uppercase">
+                    卸货任务服务商指定
+                </h5>
+                <button type="button" class="close" data-dismiss="modal" @click="executingTack={},selectIndex = null,taskError={}">
+                    <span>&times;</span>
+                </button>
+            </div>
+
+            <div class="modal-body">
+                <form class="form">
+                    <div class="form-group row">
+                        <label for="executingTack-owner-id" class="col-sm-3 col-form-label text-right">服务商</label>
+                        <div class="col-sm-5">
+                            <select id="executingTack-owner-id" class="form-control" v-model="executingTack.facilitator_id" :class="taskError.facilitator_id? 'is-invalid' :''">
+                                <option v-for="(providers,index) in facilitatorsFilter" :value="providers.id" :key="providers+index">@{{ providers.name }}</option>
+                            </select>
+                            <div class="invalid-feedback" >
+                                @{{ taskError['facilitator_id'] ? taskError['facilitator_id'][0] : '' }}
+                            </div>
+                        </div>
+                        <div class="col-sm-3">
+                            <input class="form-control" placeholder="输入服务商进行刷选" @change="filterProviders($event)">
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="executingTack-created-at" class="col-sm-3 col-form-label text-right">卸货日期</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="date" id="executingTack-created-at"  class="form-control col-9" name="size" v-model="executingTack.expenditure_at">
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="executingTack-amount" class="col-sm-3 col-form-label text-right">数量</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="number" id="executingTack-amount" class="form-control col-9" name="size" v-model="executingTack.expenditure_amount" :class="taskError.facilitator_id? 'is-invalid' :''">
+                            <div class="invalid-feedback" >
+                                @{{ taskError['facilitator_id'] ? taskError['facilitator_id'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="executingTack-amount" class="col-sm-3 col-form-label text-right">单位</label>
+                        <div class="col-sm-9 form-inline">
+                            <select id="executingTack-type" class="form-control col-4" v-model="executingTack.expenditure_unit" :class="taskError.expenditure_unit? 'is-invalid' :''">
+                                <option v-for="(unit,index) in units" :value="unit.name" :key="unit+index">@{{ unit.value }}</option>
+                            </select>
+                            <div class="invalid-feedback" >
+                                @{{ taskError['expenditure_unit'] ? taskError['expenditure_unit'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="executingTack-expenditure-unit-price" class="col-sm-3 col-form-label text-right">外派单价</label>
+                        <div class="col-sm-9 form-inline">
+                            <input type="number" id="executingTack-expenditure-unit-price" class="form-control col-9"  v-model="executingTack.expenditure_unit_price" :class="taskError.expenditure_unit_price? 'is-invalid' :''">
+                            <div class="invalid-feedback" >
+                                @{{ taskError['expenditure_unit_price'] ? taskError['expenditure_unit_price'][0] : '' }}
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="form-group row">
+                        <label for="executingTack-amount" class="col-sm-3 col-form-label text-right">备注</label>
+                        <div class="col-sm-9 form-inline">
+                            <textarea class="form-control col-9"  v-model="executingTack.expenditure_remark"></textarea>
+                        </div>
+                    </div>
+
+                </form>
+            </div>
+
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary"  data-dismiss="modal" @click="executingTack={},selectIndex = null,taskError={}">关闭</button>
+                <button type="button" class="btn btn-primary"  @click="executedTask(executingTack,selectIndex)">提交</button>
+            </div>
+        </div>
+    </div>
+
+</div>

+ 103 - 0
resources/views/transport/discharge/task/_table.blade.php

@@ -0,0 +1,103 @@
+<table class="table table-sm table-striped table-bordered table-hover card-body p-0 m-0">
+    <tr class="text-center">
+        <th><input type="checkbox" class="form-check" name="selectAll" id="selectAll" @click="checkAll"></th>
+        <th>序号</th>
+        <th>日期</th>
+        <th>客户名称</th>
+        <th>作业名称</th>
+        <th>入库单号</th>
+        <th>数量</th>
+        <th>单位</th>
+        <th>单价</th>
+        <th>收费</th>
+        <th>状态</th>
+        <th>备注</th>
+        <th>操作</th>
+    </tr>
+    <template v-if="dischargeTasks.length > 0">
+        <tr v-for="(dischargeTask,index) in dischargeTasks" :key="index" class="text-center"  @click="selectTr===index+1?selectTr=0:selectTr=index+1" :class="selectTr===index+1?'focusing' : ''">
+            <td><input type="checkbox" class="form-check" :value="dischargeTask.id" v-model="checkData"></td>
+            <td>
+                @{{index+1}}
+                <template v-if="dischargeTask.status===0">
+                    <span class="badge badge-pill badge-secondary">未指定服务商</span>
+                </template>
+                <template v-else-if="dischargeTask.status===1">
+                    <span class="badge badge-pill badge-warning">任务未进行</span>
+                </template>
+                <template v-else-if="dischargeTask.status===2">
+                    <span class="badge badge-pill badge-success">进行中</span>
+                </template>
+                <template v-else-if="dischargeTask.status===3">
+                    <span class="badge badge-pill badge-light">完成</span>
+                </template>
+            </td>
+            <td>@{{ dischargeTask.created_at }}</td>
+            <td>@{{ dischargeTask.owner ? dischargeTask.owner.name : '' }}</td>
+            <td>
+                @can('运输管理-卸货-编辑')
+                    <select :value="dischargeTask.type" class="form-control form-control-sm" :disabled="dischargeTask.status>0" @change="updateCurrentTaskColumn(dischargeTask,index,'type',$event)">
+                        <option v-for="(type,i) in taskTypes" :value="type.name">@{{ type.value }}</option>
+                    </select>
+                @else
+                    <span v-html="getType(dischargeTask.type)"></span>
+                @endcan
+            </td>
+            <td>
+                @can('运输管理-卸货-编辑')
+                    <input type="text" :value="dischargeTask.numbers" class="form-control form-control-sm" :disabled="dischargeTask.status>0" @change="updateCurrentTaskColumn(dischargeTask,index,'numbers',$event)">
+                @else
+                    @{{ dischargeTask.numbers }}
+                @endcan
+            </td>
+            <td>@{{ dischargeTask.income_amount }}</td>
+            <td>
+                @can('运输管理-卸货-编辑')
+                    <select  :value="dischargeTask.income_unit" class="form-control form-control-sm" :disabled="dischargeTask.status>0" @change="updateCurrentTaskColumn(dischargeTask,index,'income_unit',$event)">
+                        <option v-for="(unit,i) in units" :value="unit.name" v-html="unit.value"></option>
+                    </select>
+                @else
+                    <span v-html="getUnit(dischargeTask.income_unit)"></span>
+                @endcan
+            </td>
+            <td>@{{ dischargeTask.income_unit_price }}</td>
+            <td>@{{ dischargeTask.income_total_cost }}</td>
+            <td>
+                @can('运输管理-卸货-编辑')
+                    {{--  dischargeTask.status===3 完成时不可编辑状态 --}}
+                    <select :value="dischargeTask.status" class="form-control form-control-sm" :disabled="dischargeTask.status===3" @change="updateCurrentTaskColumn(dischargeTask,index,'status',$event)">
+                        <option v-for="(type,i) in status" :value="type.name" v-html="type.value" :disabled="dischargeTask.status > type.name"></option>
+                    </select>
+                @else
+                    <span>@{{ dischargeTask.status }}</span>
+                @endcan
+            </td>
+            <td>
+                @can('运输管理-卸货-编辑')
+                    <textarea class="form-control" cols="15" rows="2" :value="dischargeTask.income_remark" :disabled="dischargeTask.status>0" @change="updateCurrentTaskColumn(dischargeTask,index,'income_remark',$event)"></textarea>
+                @else
+                    @{{ dischargeTask.income_remark }}
+                @endcan
+            </td>
+            <td>
+                @can('运输管理-卸货-编辑')
+                <button class="btn btn-sm btn-outline-primary" @click="showExecutingTaskModal(index,true,dischargeTask)" v-show="dischargeTask.status===0">指定服务商</button>
+                @endcan
+                @can('运输管理-卸货-编辑')
+                <button class="btn btn-sm btn-outline-primary" @click="showUpdateTaskModal(index,true,dischargeTask)" v-show="dischargeTask.status<=1">编辑</button>
+                @endcan
+                @can('运输管理-卸货-删除')
+                <button class="btn btn-sm btn-outline-danger" @click="deleteTask(index,dischargeTask)">删除</button>
+                @endcan
+            </td>
+        </tr>
+    </template>
+    <template v-else>
+        <tr>
+            <td colspan="13">
+                <div class="alert alert-info text-lg-center">卸货任务数据为空</div>
+            </td>
+        </tr>
+    </template>
+    {{ $dischargeTasks->withQueryString()->links() }}
+</table>

+ 333 - 0
resources/views/transport/discharge/task/index.blade.php

@@ -0,0 +1,333 @@
+@extends('layouts.app')
+
+@section('title','卸货任务')
+
+@section('content')
+    <div id="nav2">
+        @component('transport.menu')@endcomponent
+        @component('transport.discharge.menu')@endcomponent
+        @component('transport.discharge.task.menu')@endcomponent
+    </div>
+    <div id="list" class="d-none container-fluid">
+        <div id="form_div"  style="min-width: 2250px"></div>
+
+        <div class="form-inline mt-1" id="btn">
+            <span class="dropdown">
+                <button type="button" class="btn btn-outline-dark btn-sm form-control-sm dropdown-toggle tooltipTarget"
+                        :class="[checkData.length>0?'btn-dark text-light':'']"
+                        data-toggle="dropdown" title="导出所有页将会以搜索条件得到的筛选结果,将其全部记录(每一页)导出">导出Excel
+                </button>
+                <div class="dropdown-menu">
+                    <a class="dropdown-item" @click="dischargeTaskExport(false)" href="javascript:">导出勾选内容</a>
+                    <a class="dropdown-item" @click="dischargeTaskExport(true)" href="javascript:">导出所有页</a>
+                </div>
+            </span>
+            <span class="ml-1">
+                @can('运输管理-卸货-创建')
+                <button type="button" class="btn btn-outline-dark btn-sm form-control-sm tooltipTarget" @click="showCreateTaskModal(true)" style="background: #dad7e8;">创建任务</button>
+                @endcan
+            </span>
+        </div>
+        @include('transport.discharge.task._table')
+        @can('运输管理-卸货-创建')
+        @include('transport.discharge.task._createTask')
+        @endcan
+        @can('运输管理-卸货-编辑')
+        @include('transport.discharge.task._executeTask')
+        @endcan
+    </div>
+@endsection
+
+@section('lastScript')
+    <script type="text/javascript" src="{{mix('js/queryForm/queryForm.js')}}"></script>
+    <script type="text/javascript" src="{{mix('js/queryForm/export.js')}}"></script>
+    <script>
+        let dischargeTaskVue = new Vue({
+            el: "#list",
+            data: {
+                dischargeTasks: {!! $dischargeTasks->toJson()!!}['data'],
+                owners:{!! $owners !!},
+                ownerFilter: [],
+                facilitators:{!! $facilitators !!},
+                facilitatorsFilter: [],
+                addTask: {income_at:null},
+                executingTack: {},
+                taskError:{},
+                taskTypes: [
+                    {name: 0, value: "装车"},
+                    {name: 1, value: "卸车"},
+                ],
+                units: [
+                    {name: 0, value: 'm3'},
+                    {name: 1, value: '吨'},
+                    {name: 2, value: '件'},
+                    {name: 3, value: '托'},
+                ],
+                status: [
+                    {name: 0, value: '创建'},
+                    {name: 1, value: '接单'},
+                    {name: 2, value: '作业中'},
+                    {name: 3, value: '完成'},
+                ],
+                isUpdate: false,
+                checkData: [],
+                selectIndex: '',
+                selectTr:0,
+            },
+            created() {
+                this.owners.forEach(function (owner, index, array) {
+                    array[index] = {
+                        name: owner.id,
+                        value: owner.name,
+                    };
+                });
+                this.ownerFilter = JSON.parse(JSON.stringify(this.owners));
+                this.facilitatorsFilter = JSON.parse(JSON.stringify(this.facilitators));
+            },
+            mounted() {
+                $('#list').removeClass('d-none');
+                $(".tooltipTarget").tooltip({'trigger': 'hover'});
+                let _this = this;
+                let data = [[
+                    {
+                        name: 'owner_id', type: 'select_multiple_select', tip: ['输入关键词快速定位下拉列表,回车确定', '选择要显示的客户'],
+                        placeholder: ['货主', '定位或多选货主'],
+                        data: _this.owners
+                    },
+                    {name: 'created_at_start', type: 'dateTime', tip: '创建开始日期'},
+                    {name: 'created_at_end', type: 'dateTime', tip: '创建结束日期'},
+                    {name: 'numbers', type: 'input', tip: '入库单号',placeholder:'入库单号'},
+                    {name: 'status', type: 'select', tip: '状态' , data: _this.status,placeholder:'状态'},
+                    {name: 'income_remark', type: 'input', tip: '备注' , data: _this.status,placeholder:'备注'}
+                ]];
+                this.form = new query({
+                    el: '#form_div',
+                    condition: data,
+                    appendDom : "btn",
+                    paginations:[ 50, 100, 200, 500,1000,20],
+                })
+                this.form.init();
+            },
+            watch: {
+                checkData: {
+                    handler() {
+                        if (this.checkData.length === this.dischargeTasks.length) {
+                            document.querySelector('#selectAll').checked = true;
+                        } else {
+                            document.querySelector('#selectAll').checked = false;
+                        }
+                    },
+                    deep: true
+                },
+            },
+            methods: {
+                getUnit(type) {
+                    let unit = ''
+                    this.units.forEach(function (item) {
+                        if (item.name === type) unit = item.value;
+                    });
+                    return unit;
+                },
+                getType(value) {
+                    let type = ''
+                    this.taskTypes.forEach(function (item) {
+                        if (item.name === value) type = item.value;
+                    });
+                    return type;
+                },
+                getStatus(value) {
+                    let status = '';
+                    this.status.forEach(function (item) {
+                        if (item.name === value) status = item.value;
+                    })
+                    return status;
+                },
+                checkAll(e) {
+                    if (!e.target.checked) this.checkData = [];
+                    else {
+                        this.dischargeTasks.forEach((el, i) => {
+                            if (this.checkData.indexOf(el['id']) === -1) this.checkData.push(el['id']);
+                        });
+                    }
+                },
+                // 创建任务 modals
+                showCreateTaskModal(isDisplay) {
+                    if (isDisplay){
+                        if(!this.isUpdate)this.addTask.income_at = moment().format('YYYY-MM-DD');
+                        $("#createdModal").modal('show');
+                    } else {
+                        this.isUpdate = false;
+                        $("#createdModal").modal('hide');
+                    }
+                },
+                // 执行任务 modal
+                showExecutingTaskModal(index, isDisplay, task) {
+                    this.executingTack = JSON.parse(JSON.stringify(task));
+                    this.selectIndex = index;
+                    if (isDisplay) {
+                        this.executingTack.expenditure_at = moment().format('YYYY-MM-DD');
+                        this.isUpdate = true;
+                        $("#executingTaskModal").modal('show');
+                    } else {
+                        this.isUpdate = false;
+                        this.selectIndex = null;
+                        $("#executingTaskModal").modal('hide');
+                    }
+                },
+                // 编辑任务 modal
+                showUpdateTaskModal(index, isDisplay, task) {
+                    this.isUpdate = true;
+                    this.selectIndex = Number(index);
+                    this.addTask = JSON.parse(JSON.stringify(task));
+                    this.showCreateTaskModal(isDisplay)
+                },
+                // 创建任务
+                createTask(index) {
+                    if (this.isUpdate) {
+                        this.updateCurrentTask(index);
+                        return
+                    }
+                    this.addTask['income_total_cost'] = Number(this.addTask['income_unit_price']) * Number(this.addTask.income_amount);
+                    this.addTask['status'] = 0;
+                    let url = '{{url('apiLocal/transport/discharge/task/store')}}';
+                    tempTip.setDuration(2000);
+                    tempTip.setIndex(999);
+                    axios.post(url, this.addTask).then(res => {
+                        if (res.data.success) {
+                            tempTip.showSuccess("添加卸货任务成功")
+                            this.dischargeTasks.unshift(res.data.data);
+                            this.showCreateTaskModal(false);
+                            this.addTask = {};
+                            return ;
+                        }
+                        if(res.data.errors){
+                            this.taskError = res.data.errors ;
+                            return ;
+                        }
+                        tempTip.show(res.data.message ?? (res.data.data ?? '添加卸货任务失败'));
+                    }).catch(err => {
+                        tempTip.show(err);
+                    });
+                },
+                // 执行任务
+                executedTask(dischargeTask, index) {
+                    let url = '{{url('apiLocal/transport/discharge/task/updateFacilitator')}}';
+                    tempTip.setDuration(2000);
+                    tempTip.setIndex(9999);
+                    dischargeTask['income_total_cost'] = Number(dischargeTask['income_unit_price']) * (dischargeTask['income_amount']);
+                    dischargeTask['status'] = 1;
+                    axios.put(url, dischargeTask).then(res => {
+                        if (res.data.success) {
+                            this.$set(this.dischargeTasks, index, res.data.data);
+                            this.showExecutingTaskModal(null,false,null);
+                            tempTip.showSuccess("任务操作成功");
+                            this.selectIndex = null;
+                            this.executingTack = {};
+                            return;
+                        }
+                        if(res.data.errors){
+                            this.taskError = res.data.errors;
+                            return ;
+                        }
+                        tempTip.show(res.data.data);
+                    }).catch(err => {
+                        tempTip.show(err);
+                    })
+                },
+                // 编辑当前任务
+                updateCurrentTask(addTask,index) {
+                    // 更新
+                    let url = '{{url('apiLocal/transport/discharge/task/update')}}';
+                    tempTip.setDuration(2000);
+                    tempTip.setIndex(2000);
+                    axios.put(url, addTask).then(res => {
+                        if (res.data.success) {
+                            tempTip.showSuccess("修改成功")
+                            this.showCreateTaskModal(false);
+                            this.$set(this.dischargeTasks, index, res.data.data);
+                            this.addTask = {};
+                            this.selectIndex = null;
+                            return;
+                        }
+                        res.data.message ? tempTip.show(res.data.message) : null;
+                    }).catch(err => {
+                        tempTip.show(err);
+                    });
+                    this.selectIndex = null;
+                },
+                updateCurrentTaskColumn(task,index,column,$e){
+                    let url = '{{url('apiLocal/transport/discharge/task/updateColumn')}}';
+                    tempTip.setDuration(2000);
+                    tempTip.setIndex(99);
+                    let value = $($e.target).val();
+                    let data = {id:task.id};
+                    data[column] = value;
+                    window.axios.put(url, data).then(res => {
+                        if (res.data.success) {
+                            this.$set(this.dischargeTasks, index, res.data.data);
+                            tempTip.showSuccess("修改成功")
+                            this.addTask = {};
+                            this.selectIndex = null;
+                            return;
+                        }else if(res.data.errors){
+                            tempTip.show(res.data.errors);
+                            return;
+                        }
+                        tempTip.show(res.data.data)
+                        this.$set(this.dischargeTasks, index, task);
+                    }).catch(err => {
+                        tempTip.show(err);
+                    });
+                    this.selectIndex = null;
+                },
+                // 删除当前任务
+                deleteTask(index, dischargeTask) {
+                    if (!confirm("是否删除当前任务")) {
+                        return
+                    }
+                    let url = '{{url('apiLocal/transport/discharge/task/delete/?id=')}}'+dischargeTask['id'];
+                    tempTip.setDuration(2000);
+                    tempTip.setIndex(99);
+                    axios.delete(url).then(res => {
+                        if (res.data.success) {
+                            this.$delete(this.dischargeTasks, index);
+                            tempTip.showSuccess('删除成功')
+                            return
+                        }
+                        tempTip.show('删除失败!' + res.data.data)
+                    }).catch(err => {
+                        tempTip.show(err);
+                    });
+                },
+                // 下载
+                dischargeTaskExport(isExportAll) {
+                    let url = '{{url('transport/discharge/task/export')}}';
+                    let token = '{{ csrf_token() }}';
+                    excelExport(isExportAll, this.checkData, url, this.sum, token);
+                },
+                // 筛选货主
+                filterOwner(e) {
+                    let value = $(e.target).val();
+                    if (value === '') this.ownerFilter = JSON.parse(JSON.stringify(this.owners));
+                    else {
+                        this.ownerFilter = this.owners.filter(function (owner) {
+                            return owner.name.indexOf(value) !== -1;
+                        });
+                    }
+                },
+                // 筛选服务商
+                filterProviders(e) {
+                    let value = $(e.target).val();
+                    if (value === '') this.facilitatorsFilter = JSON.parse(JSON.stringify(this.facilitators));
+                    else {
+                        this.facilitatorsFilter = this.facilitators.filter(function (providers) {
+                            return providers.name.indexOf(value) !== -1;
+                        });
+                    }
+                }
+
+            }
+        })
+    </script>
+
+@endsection

+ 11 - 0
resources/views/transport/discharge/task/menu.blade.php

@@ -0,0 +1,11 @@
+<div class="container-fluid">
+    <div class="card">
+        <ul class="nav nav-pills">
+            @can('运输管理-卸货-查询')
+            <li class="nav-item">
+                <a target="transport/discharge/task" class="nav-link" href="{{url('transport/discharge/task/index')}}" :class="{active:isActive('task',3)}">查询</a>
+            </li>
+            @endcan
+        </ul>
+    </div>
+</div>

+ 18 - 0
resources/views/transport/menu.blade.php

@@ -0,0 +1,18 @@
+<div class="container-fluid nav2" >
+    <div class="card">
+        <ul class="nav nav-pills">
+            @can('运输管理-运单-查询')
+            <li class="nav-item">
+                <a target="transport/waybill/index" class="nav-link" href="{{url('transport/waybill/index')}}" :class="{active:isActive('waybill',2)}">运单</a>
+            </li>
+            @endcan
+
+            <!--  权限 ***  -->
+            @can('运输管理-卸货')
+            <li class="nav-item">
+                <a target="transport/discharge/task/index" class="nav-link" href="{{url('transport/discharge/task/index')}}" :class="{active:isActive('discharge',2)}">卸货</a>
+            </li>
+            @endcan
+        </ul>
+    </div>
+</div>

+ 48 - 0
resources/views/transport/waybill/_batchUploadImg.blade.php

@@ -0,0 +1,48 @@
+<div class="modal fade" tabindex="-1" role="dialog" id="batchUploadImg">
+    <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
+        <div class="modal-content">
+            <div class="modal-header">
+                <div class="pull-left ml-2 small text-primary">
+                    选择文件时使用SHIFT键或CTRL键可多选
+                </div>
+                <button type="button" class="close" data-dismiss="modal">&times;</button>
+            </div>
+            <div class="modal-body">
+                <label hidden><input type="file" @change="uploadFiles($event)" multiple="multiple" id="uploadImg" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"></label>
+                <div class="container-fluid">
+                    <div class="text-center small row mb-1" v-if="batchUploadError.length>0">
+                        <div class="col-3 text-danger">部分上传失败:</div>
+                        <div class="col-8">
+                            <b v-for="err in batchUploadError">@{{ err }}<br></b>
+                        </div>
+                    </div>
+                    <div class="row">
+                        <div class="col-8 text-center offset-2 border border-2 rounded" style="min-height: 100px;cursor: pointer"
+                        @click="selectedFile()" v-if="images.length<1">
+                            <div class="h1 text-secondary mt-3">
+                                <span class="fa fa-plus"></span>
+                            </div>
+                        </div>
+                        <div class="col-3 border border-2 rounded" v-for="(img,i) in images">
+                            <div class="w-100 row m-1 h-25">
+                                <div class="text-center small col-9">
+                                    <span class="text-wrap">@{{ img.name }}(<span class="text-info">@{{ img.size | size }}</span>)</span>
+                                </div>
+                                <span class="col-3 h4 cursor-pointer text-danger font-weight-bold h-25" @click="delTempImg(i)"> &times;</span>
+                            </div>
+                            <div class="w-100 m-0 text-center h-50 overflow-hidden">
+                                <img class="img-fluid" :src="img.src" alt="img.name"/>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button class="btn btn-info text-white mr-1" @click="selectedFile()" v-if="images.length>0">
+                    <span class="fa fa-image"></span>
+                    继续添加</button>
+                <button class="btn btn-success" @click="batchUploadImages()">开始上传</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 2 - 1
resources/views/waybill/authorityMenu.blade.php → resources/views/transport/waybill/authorityMenu.blade.php

@@ -3,6 +3,7 @@
 
 @section('content')
     <span id="nav2">
-        @component('waybill.menu')@endcomponent
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')@endcomponent
     </span>
 @endsection

+ 10 - 9
resources/views/waybill/create.blade.php → resources/views/transport/waybill/create.blade.php

@@ -3,16 +3,17 @@
 
 @section('content')
     <div id="nav2">
-        @component('waybill.menu')@endcomponent
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')@endcomponent
         <div class="container-fluid nav3">
             <div class="card menu-third" >
                 <ul class="nav nav-pills">
-                    @can('运输管理-录入')
+                    @can('运输管理-运单-录入')
                         <li class="nav-item">
-                            <a class="nav-link @if($type=='专线') active @endif" href="{{url('waybill/create?type=ZX')}}" >专线</a>
+                            <a class="nav-link @if($type=='专线') active @endif" href="{{url('transport/waybill/create?type=ZX')}}" >专线</a>
                         </li>
                         <li class="nav-item">
-                            <a class="nav-link @if($type=='直发车') active @endif" href="{{url('waybill/create?type=ZF')}}">直发车</a>
+                            <a class="nav-link @if($type=='直发车') active @endif" href="{{url('transport/waybill/create?type=ZF')}}">直发车</a>
                         </li> @endcan
                 </ul>
             </div>
@@ -21,13 +22,13 @@
     <div class="container-fluid" id="list">
         <div class="card col-md-8 offset-md-2">
             <div class="card-body">
-                <form method="POST" action="{{ url('waybill') }}">
+                <form method="POST" action="{{ url('transport/waybill') }}">
                     @csrf
                     <label hidden><input name="type" value="{{$type}}"></label>
                     <div class="h5 text-center mb-3">
                         <ul class="nav nav-tabs">
-                            <li class="nav-item offset-5"><a class="nav-link @if($type=='专线') active @endif" href="{{url('waybill/create?type=ZX')}}">专线</a></li>
-                            <li class="nav-item"><a class="nav-link @if($type!='专线') active @endif" href="{{url('waybill/create?type=ZF')}}">直发车</a></li>
+                            <li class="nav-item offset-5"><a class="nav-link @if($type=='专线') active @endif" href="{{url('transport/waybill/create?type=ZX')}}">专线</a></li>
+                            <li class="nav-item"><a class="nav-link @if($type!='专线') active @endif" href="{{url('transport/waybill/create?type=ZF')}}">直发车</a></li>
                         </ul>
                     </div>
                     <div class="form-group row">
@@ -112,7 +113,7 @@
                         </div>
                     </div>
                     {{--zengjun start--}}
-{{--                    @can('运输管理-运费')--}}
+{{--                    @can('运输管理-运单-运费')--}}
                         <div class="form-group row">
                             <label for="charge" class="col-2 col-form-label text-right ">运输收费(元)</label>
                             <div class="col-8">
@@ -230,7 +231,7 @@
                     this._codeGetOrder(val);
                 },
                 _codeGetOrder(val){
-                    let url = "{{url('waybill/seekOrder')}}";
+                    let url = "{{url('transport/waybill/seekOrder')}}";
                     window.tempTip.postBasicRequest(url,{code:val},res=>{
                         this.order = res;
                         this.model.order_id = res.id;

+ 9 - 6
resources/views/waybill/delivering.blade.php → resources/views/transport/waybill/delivering.blade.php

@@ -2,13 +2,16 @@
 @section('title')发运-运输管理@endsection
 
 @section('content')
-    @component('waybill.menu')@endcomponent
+    <div id="nav2">
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')@endcomponent
+    </div>
     <div id="list" class=" container-fluid">
-        <form method="GET" action="{{url('waybill/delivering')}}" id="form">
-            <div class="text-nowrap mb-0" style="background: #fff;">
+        <form method="GET" action="{{url('transport/waybill/delivering')}}" id="form">
+            计费模型  <div class="text-nowrap mb-0" style="background: #fff;">
                 <div v-if="isBeingFilterConditions">
                     <div><div class="col" style="padding:0">
-                            <a  href="{{url('waybill/delivering')}}"><span class="btn btn-warning text-dark">清除筛选</span></a>
+                            <a  href="{{url('transport/waybill/delivering')}}"><span class="btn btn-warning text-dark">清除筛选</span></a>
                         </div>
                     </div>
                 </div>
@@ -295,7 +298,7 @@
                 }
             },
             waybillExport(checkAllSign){
-                let url = '{{url('waybill/deliveringExport')}}';
+                let url = '{{url('transport/waybill/deliveringExport')}}';
                 let token='{{ csrf_token() }}';
                 excelExport(checkAllSign,this.checkData,url,this.sum,token);
             },
@@ -316,7 +319,7 @@
                 data['carrier_weight'] = $("#carrier_weight"+waybill_id).val();//体积
                 data['carrier_weight_other'] = $("#carrier_weight_other"+waybill_id).val();//重量
                 if (_this.errors["_"+data['id']])_this.errors["_"+data['id']]={};
-                axios.post("{{url('waybill/storeCarrierBill')}}",data)
+                axios.post("{{url('transport/waybill/storeCarrierBill')}}",data)
                     .then(function (response) {
                         if (response.data.error){
                             tempTip.setDuration(3000);

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

@@ -2,7 +2,8 @@
 
 @section('content')
     <div id="nav2">
-        @component('waybill.menu')
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')
             <li class="nav-item">
                 <a class="nav-link" href="{{URL::current()}}" :class="{active:isActive('edit',3)}">调度</a>
             </li>
@@ -330,7 +331,7 @@
                                        name="car_owner_info" autocomplete="off" v-model="waybill.car_owner_info" id="car_owner_info" >
                             </div>
                         </div>
-                        @can('运输管理-运费')
+                        @can('运输管理-运单-运费')
                         <div class="form-group row">
                             <label for="fee" class="col-2 col-form-label text-right text-primary">运费(元) </label>
                             <div class="col-8">

+ 28 - 28
resources/views/waybill/index.blade.php → resources/views/transport/waybill/index.blade.php

@@ -3,28 +3,28 @@
 
 @section('content')
     <div id="nav2">
-        @component('waybill.menu')
-        @endcomponent
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')@endcomponent
     </div>
     <div class="container-fluid" style="min-width: 1500px;">
         <div class="d-none" id="list">
 
-            @include("waybill._batchUploadImg")
+            @include("transport.waybill._batchUploadImg")
 
             <div class="container-fluid nav3">
                 <div class="card menu-third" >
                     <ul class="nav nav-pills">
-                        @can('运输管理-查询')
+                        @can('运输管理-运单-查询')
                         <li class="nav-item">
-                            <a class="nav-link @if($uriType=='') active @endif" href="{{url('waybill/index')}}">全部</a>
+                            <a class="nav-link @if($uriType=='') active @endif" href="{{url('transport/waybill/index')}}">全部</a>
                         </li> @endcan
-                        @can('运输管理-查询')
+                        @can('运输管理-运单-查询')
                         <li class="nav-item">
-                            <a class="nav-link @if($uriType=='专线') active @endif" href="{{url('waybill/index?uriType=专线')}}">专线</a>
+                            <a class="nav-link @if($uriType=='专线') active @endif" href="{{url('transport/waybill/index?uriType=专线')}}">专线</a>
                         </li> @endcan
-                        @can('运输管理-查询')
+                        @can('运输管理-运单-查询')
                         <li class="nav-item">
-                            <a class="nav-link @if($uriType=='直发车') active @endif" href="{{url('waybill/index?uriType=直发车')}}">直发车</a>
+                            <a class="nav-link @if($uriType=='直发车') active @endif" href="{{url('transport/waybill/index?uriType=直发车')}}">直发车</a>
                         </li> @endcan
                     </ul>
                 </div>
@@ -40,7 +40,7 @@
                     <a class="dropdown-item" @click="waybillExport(true)" href="javascript:">导出所有页</a>
                 </div>
             </span>
-            @can('运输管理-图片上传')<button class="btn btn-sm btn-outline-info" data-target="#batchUploadImg" data-toggle="modal">批量上传图片</button>@endcan
+            @can('运输管理-运单-图片上传')<button class="btn btn-sm btn-outline-info" data-target="#batchUploadImg" data-toggle="modal">批量上传图片</button>@endcan
             <div>
                 @if(Session::has('successTip'))
                     <div class="alert alert-success h1">{{Session::get('successTip')}}</div>
@@ -53,10 +53,10 @@
             <table class="table table-striped table-sm table-bordered table-hover text-nowrap waybill-table" style="background: #fff;" id="headerParent">
                 <tr>
                     <th class="table-header-layer-1" colspan="4"></th>
-                    <th class="table-header-layer-1" colspan="11"><span class="fa fa-file-text-o"></span> 运单信息</th>
+                    <th class="table-header-layer-1" colspan="12"><span class="fa fa-file-text-o"></span> 运单信息</th>
                     <th class="table-header-layer-1" colspan="16"><span class="fa fa-truck"></span> 运输信息</th>
                     <th class="table-header-layer-1" colspan="5"><span class="fa fa-rmb"></span> 费用信息
-                    @can('运输管理-删除')
+                    @can('运输管理-运单-删除')
                         <th class="table-header-layer-1" colspan="1"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
                     @endcan
                 </tr>
@@ -69,7 +69,7 @@
                     </td>
                     <td>
                         <span v-if=waybill.status==="未审核"||waybill.status==="待重审">
-                            @can('运输管理-运单审核')
+                            @can('运输管理-运单-运单审核')
                                 <button class="btn btn-outline-primary btn-sm" @click="waybillAudit(waybill.id,waybill.waybill_number)">审核</button>
                             @endcan
                             @can('运输管理-编辑')
@@ -77,21 +77,21 @@
                             @endcan
                         </span>
                         <span v-if=waybill.status==="已审核">
-                            @can('运输管理-调度')
+                            @can('运输管理-运单-调度')
                                 <button class="btn btn-outline-secondary btn-sm" @click="waybillRetreatAudit(waybill.id,waybill.waybill_number)">取消审核</button>
                                 <a target="_blank" class="btn btn-outline-secondary btn-sm" :href= "('{{url('waybill')}}/'+waybill.id+'/edit')">调度</a>
                             @endcan
                         </span>
                         <span v-if=waybill.status==="待终审">
-                            @can('运输管理-调度审核')
+                            @can('运输管理-运单-调度审核')
                                 <button class="btn btn-outline-success btn-sm" @click="waybillEndAudit(waybill.id,waybill.waybill_number)">完结</button>
                             @endcan
-                            @can('运输管理-调度')
+                            @can('运输管理-运单-调度')
                                 <a target="_blank" class="btn btn-outline-secondary btn-sm" :href= "('{{url('waybill')}}/'+waybill.id+'/edit')">改调度</a>
                             @endcan
                         </span>
                     </td>
-                    @can('运输管理-置顶')
+                    @can('运输管理-运单-置顶')
                         <td class="td-warm text-muted" v-if="waybill.remark" style="height: 55px">
                             <button type="button" class="btn btn-sm btn-outline-danger " @click="cancelOnTop($event)" :data_id="waybill.id"  style="opacity: 0.75">取消</button>
                         </td>
@@ -132,7 +132,7 @@
                         @{{waybill.wms_bill_number}}
                     </td>
                     <td class="td-warm">@{{waybill.waybill_number}}</td>
-                    @can('运输管理-运单编辑')
+                    @can('运输管理-运单-运单编辑')
                     <td class="td-warm" >
                         <span v-if="waybill.charge" class="btn-sm btn-outline-secondary btn" @click="waybillChargeCheck($event)" :data_id="waybill.id">@{{waybill.charge|money}}</span>
                         <input v-else type="number" class="form-control form-control-sm" @blur="addWaybillCharge($event)" onfocus="$(this).css('width','85px')" :value="waybill.charge" :data_id="waybill.id" >
@@ -147,7 +147,7 @@
                         <div align="center" @mouseleave="removeCommonImg('common_img_'+waybill.id)" @mouseenter="commonImg('img_'+waybill.id,waybill.url,waybill.suffix)">
                             <img v-if="waybill.url" :id="'img_'+waybill.id"  :src="waybill.url+'-thumbnail.'+waybill.suffix"
                                     {{--:data-src="waybill.url+'-thumbnail.'+waybill.suffix" src="{{url('icon/img404-thumbnail.jpg')}}"--}}>
-                            @can('运输管理-图片上传')<div v-if="!waybill.url">
+                            @can('运输管理-运单-图片上传')<div v-if="!waybill.url">
                                 <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(waybill.waybill_number)" value="上传照片 "/>
                                 <input type="file" @change="submitFile($event,waybill.waybill_number)" :id="waybill.waybill_number"
                                        style="display: none" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
@@ -193,8 +193,8 @@
                     <td class="td-cool"><span v-if="waybill.carrier_weight_other">@{{waybill.carrier_weight_other|filterZero}}  @{{waybill.carrier_weight_unit_other}}</span></td>
                     <td class="td-cool"><span v-if="waybill.amount">@{{waybill.amount}} @{{waybill.amount_unit_name }}</span></td>
                     <td class="td-cool">@{{waybill.mileage|km}} </td>
-                    @can('运输管理-可见费用项')
-                        @can('运输管理-运费')
+                    @can('运输管理-运单-可见费用项')
+                        @can('运输管理-运单-运费')
                             <td class="td-helpful" v-if="waybill.fee">
                                 <span v-if="waybill.type==='专线'"></span>
                                 <span v-else-if="waybill.fee" class="btn-sm btn-outline-secondary btn" @click="waybillFeeCheck($event)" :data_id="waybill.id">@{{waybill.fee|money}}</span>
@@ -210,7 +210,7 @@
                     @endcan
                     <td class="td-helpful">@{{waybill.deliver_at}}</td>
                     <td class="td-helpful"><span v-html="waybill.dispatch_remark"></span></td>
-                    @can('运输管理-删除')
+                    @can('运输管理-运单-删除')
                         <td class="td-operation">
                             <button type="button" class="btn btn-outline-danger btn-sm" @click="waybillDestroy(waybill.id,waybill.waybill_number,i)">删</button>
                         </td>
@@ -338,7 +338,7 @@
                         mileage:'{{$waybill->mileage}}',
                         amount:'{{$waybill->amount}}',
                         @if($waybill->carType)carType:{!! $waybill->carType !!},car_owner_info:'{{$waybill->car_owner_info}}',@endif
-                        @can('运输管理-可见费用项') fee:'{{$waybill->fee}}',
+                        @can('运输管理-运单-可见费用项') fee:'{{$waybill->fee}}',
                         pick_up_fee:'{{$waybill->pick_up_fee}}',other_fee:'{{$waybill->other_fee}}',
                         collect_fee:'{{$waybill->collect_fee}}', @endcan
                         deliver_at:'{{$waybill->deliver_at}}',
@@ -442,7 +442,7 @@
                 let column = [
                     {name:'cloneCheckAll',customization:true,type:'checkAll',column:'id',
                         dom:$('#cloneCheckAll').removeClass('d-none'), neglect: true},
-                    @can('运输管理-编辑','运输管理-运单审核','运输管理-调度','运输管理-编辑')
+                    @can('运输管理-编辑','运输管理-运单-运单审核','运输管理-运单-调度','运输管理-编辑')
                     {name:'operation',value: '操作', neglect: true, class:"td-operation"},@endcan
                     {name:'onTop',value: '置顶', neglect: true, class:"td-operation"},
                     {name:'status',value: '状态', class:"td-operation"},
@@ -457,7 +457,7 @@
                     {name:'charge',value: '运输收费', neglect: true, class:"td-warm"},
                     {name:'other_charge',value: '其他收费', neglect: true, class:"td-warm"},
                     {name:'other_charge_remark',value: '其他收费备注', class:"td-warm"},
-                    @can('运输管理-图片上传'){name:'img',value: '照片', neglect: true, class:"td-warm"},@endcan
+                    @can('运输管理-运单-图片上传'){name:'img',value: '照片', neglect: true, class:"td-warm"},@endcan
                     {name:'recipient',value: '收件人', class:"td-cool"},
                     {name:'recipient_mobile',value: '收件人电话', class:"td-cool"},
                     {name:'origination',value: '始发地', class:"td-cool"},
@@ -474,12 +474,12 @@
                     {name:'carrier_weight_other',value: '承运商计重', neglect: true, class:"td-cool"},
                     {name:'amount',value: '计件', neglect: true, class:"td-cool"},
                     {name:'mileage',value: '里程', neglect: true, class:"td-cool"},
-                    @can('运输管理-运费'){name:'fee',value: '运费', neglect: true, class:"td-helpful"},@endcan
+                    @can('运输管理-运单-运费'){name:'fee',value: '运费', neglect: true, class:"td-helpful"},@endcan
                     {name:'pick_up_fee',value: '提货费', neglect: true, class:"td-helpful"},
                     {name:'other_fee',value: '其他支出', neglect: true, class:"td-helpful"},
                     {name:'deliver_at',value: '发货时间', class:"td-helpful"},
                     {name:'dispatch_remark',value: '调度备注', class:"td-helpful"},
-                    @can('运输管理-删除'){name:'remove',value: '操作', neglect: true, class:"td-delete"},@endcan
+                    @can('运输管理-运单-删除'){name:'remove',value: '操作', neglect: true, class:"td-delete"},@endcan
                 ];
                 let _this = this;
                 setTimeout(function () {
@@ -723,7 +723,7 @@
                         "<img src=\""+url+'-common.'+suffix+"\" style='position: relative;left:-50px;' >" +
                         "</a>" +
                         "</div>"+
-                            @can('运输管理-图片删除')"<button type='button' class='btn btn-sm btn-danger' onclick='vue.btnDeleteImg(this)' value='"+id+"' style='position: relative;float: right;margin-right: 51px;margin-top: -30px;' >删除</button>" +@endcan
+                            @can('运输管理-运单-图片删除')"<button type='button' class='btn btn-sm btn-danger' onclick='vue.btnDeleteImg(this)' value='"+id+"' style='position: relative;float: right;margin-right: 51px;margin-top: -30px;' >删除</button>" +@endcan
                             "</div>"+
                         "</div>");
                 },

+ 34 - 0
resources/views/transport/waybill/menu.blade.php

@@ -0,0 +1,34 @@
+<div class="container-fluid nav3">
+    <div class="card">
+        <ul class="nav nav-pills">
+            @can('运输管理-运单-查询')
+            <li class="nav-item">
+                <a target="transport/waybill/index" class="nav-link" href="{{url('transport/waybill/index')}}" :class="{active:isActive('index',3)}">查询</a>
+            </li> @endcan
+            @can('运输管理-运单-录入')
+            <li class="nav-item">
+                <a target="transport/waybill/create?type=ZX" class="nav-link" href="{{url('transport/waybill/create?type=ZX')}}" :class="{active:isActive('create',3)}">录入</a>
+            </li> @endcan
+            @can('运输管理-运单-发运')
+            <li class="nav-item">
+                <a target="transport/waybill/delivering" class="nav-link" href="{{url('transport/waybill/delivering')}}" :class="{active:isActive('delivering',3)}">发运</a>
+            </li> @endcan
+            {{$slot}}
+            <li class="nav-item">
+                <a target="transport/waybill/relating" class="nav-link text-dark" href="{{url('transport/waybill/relating')}}" :class="{active:isActive('relating',3)}">相关设置</a>
+            </li>
+            @can('财务报表')
+            <li class="nav-item">
+                <a target="transport/waybill/waybillFinancialSnapshot" class="nav-link text-dark" href="{{url('transport/waybill/waybillFinancialSnapshot')}}" :class="{active:isActive('waybillFinancialSnapshot',3)}">财务报表</a>
+            </li>
+            <li class="nav-item">
+                <a target="transport/waybill/waybillFinancialExcepted" class="nav-link text-dark" href="{{url('transport/waybill/waybillFinancialExcepted')}}" :class="{active:isActive('waybillFinancialExcepted',3)}">异常报表</a>
+            </li>@endcan
+            @can('运输管理-运单-删除')
+            <li class="nav-item">
+                <a target="transport/waybill/recycle" class="nav-link" href="{{url('transport/waybill/recycle')}}" :class="{active:isActive('recycle',3)}">回收站</a>
+            </li>
+            @endcan
+        </ul>
+    </div>
+</div>

+ 3 - 3
resources/views/waybill/menuWaybill.blade.php → resources/views/transport/waybill/menuWaybill.blade.php

@@ -3,9 +3,9 @@
 
 @section('content')
     <div id="nav2">
-        @component('waybill.menu')
-        @endcomponent
-        <div class="container-fluid nav3">
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')@endcomponent
+            <div class="container-fluid nav3">
             <div class="card menu-third" >
                 <ul class="nav nav-pills">
                     @can('计费模型')

+ 5 - 4
resources/views/waybill/recycle.blade.php → resources/views/transport/waybill/recycle.blade.php

@@ -3,7 +3,8 @@
 
 @section('content')
     <div id="nav2">
-    @component('waybill.menu')@endcomponent
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')@endcomponent
     </div>
 
     <div class=container-fluid">
@@ -31,7 +32,7 @@
                                 <tr>
                                     <td class="text-muted">选定操作记录:</td>
                                     <td colspan="9">
-                                        @can('运输管理-删除')
+                                        @can('运输管理-运单-删除')
                                             <span class="btn btn-sm" @click="restoreSelected" style="cursor: pointer"
                                                      :class="[waybills_checkBoxes.length > 0?'btn-danger':'btn-outline-danger']">
                                             恢复
@@ -103,7 +104,7 @@
                         <td ><span v-if="waybill.carrier_weight_other">@{{waybill.carrier_weight_other}}  @{{waybill.carrier_weight_unit_other}}</span></td>
                         <td ><span v-if="waybill.amount">@{{waybill.amount}} @{{waybill.amount_unit_name }}</span></td>
                         <td >@{{waybill.mileage|km}}</td>
-                        @can('运输管理-可见费用项')
+                        @can('运输管理-运单-可见费用项')
                             <td ><span v-if="waybill.type=='专线'"></span><span v-else>@{{waybill.fee}}</span></td>
                             <td >@{{waybill.pick_up_fee}}</td>
                             <td >@{{waybill.other_fee}}</td>
@@ -163,7 +164,7 @@
                         mileage:'{{$waybill->mileage}}',
                         amount:'{{$waybill->amount}}',
                         @if($waybill->carType)carType:{!! $waybill->carType !!},car_owner_info:'{{$waybill->car_owner_info}}',@endif
-                        @can('运输管理-可见费用项') fee:'{{$waybill->fee}}',
+                        @can('运输管理-运单-可见费用项') fee:'{{$waybill->fee}}',
                         pick_up_fee:'{{$waybill->pick_up_fee}}',other_fee:'{{$waybill->other_fee}}',
                         collect_fee:'{{$waybill->collect_fee}}', @endcan
                         dispatch_remark:'{{$waybill->dispatch_remark}}',

+ 1 - 1
resources/views/waybill/waybillEdit.blade.php → resources/views/transport/waybill/waybillEdit.blade.php

@@ -2,7 +2,7 @@
 
 @section('content')
     <div id="nav2">
-        @component('waybill.menu')
+        @component('transport.waybill.menu')
             <li class="nav-item">
                 <a class="nav-link" href="{{URL::current()}}" :class="{active:isActive('waybillEdit',2)}">修改</a>
             </li>

+ 7 - 7
resources/views/waybill/waybillFinancialSnapshot/index.blade.php → resources/views/transport/waybill/waybillFinancialSnapshot/index.blade.php

@@ -3,22 +3,22 @@
 
 @section('content')
 <div class="d-none" id="editingPanel">
-
     <div  class="card" id="nav2">
-        @component('waybill.menu')@endcomponent
+        @component('transport.menu')@endcomponent
+        @component('transport.waybill.menu')@endcomponent
 
             <div class="container-fluid nav3">
                 <div class="card menu-third" >
                     <ul class="nav nav-pills">
                         @can('财务报表-查询')
                             <li class="nav-item">
-                                <a class="nav-link @if($type=='') active @endif" href="@if(!isset($excepted)) {{url('waybill/waybillFinancialSnapshot')}} @else {{url('waybill/waybillFinancialExcepted')}} @endif">全部</a>
+                                <a class="nav-link @if($type=='') active @endif" href="@if(!isset($excepted)) {{url('transport/waybill/waybillFinancialSnapshot')}} @else {{url('transport/waybill/waybillFinancialExcepted')}} @endif">全部</a>
                             </li>
                             <li class="nav-item">
-                                <a class="nav-link @if($type=='ZX') active @endif" href="@if(!isset($excepted)) {{url('waybill/waybillFinancialSnapshot?type=ZX')}} @else {{url('waybill/waybillFinancialExcepted?type=ZX')}} @endif">专线</a>
+                                <a class="nav-link @if($type=='ZX') active @endif" href="@if(!isset($excepted)) {{url('transport/waybill/waybillFinancialSnapshot?type=ZX')}} @else {{url('transport/waybill/waybillFinancialExcepted?type=ZX')}} @endif">专线</a>
                             </li>
                             <li class="nav-item">
-                                <a class="nav-link @if($type=='ZF') active @endif" href="@if(!isset($excepted)) {{url('waybill/waybillFinancialSnapshot?type=ZF')}} @else {{url('waybill/waybillFinancialExcepted?type=ZF')}} @endif">直发车</a>
+                                <a class="nav-link @if($type=='ZF') active @endif" href="@if(!isset($excepted)) {{url('transport/waybill/waybillFinancialSnapshot?type=ZF')}} @else {{url('transport/waybill/waybillFinancialExcepted?type=ZF')}} @endif">直发车</a>
                             </li> @endcan
 
                     </ul>
@@ -27,9 +27,9 @@
     </div>
     <div class="card " style="width: 3500px">
     <form  method="get" action="@if(!isset($excepted))
-    @if($type=='ZF'){{url('waybill/waybillFinancialSnapshot?type=ZF')}}@elseif($type=='ZX'){{url('waybill/waybillFinancialSnapshot?type=ZX')}}@else{{url('waybill/waybillFinancialSnapshot')}}@endif
+    @if($type=='ZF'){{url('transport/waybill/waybillFinancialSnapshot?type=ZF')}}@elseif($type=='ZX'){{url('transport/waybill/waybillFinancialSnapshot?type=ZX')}}@else{{url('transport/waybill/waybillFinancialSnapshot')}}@endif
     @else
-    @if($type=='ZF'){{url('waybill/waybillFinancialExcepted?type=ZF')}}@elseif($type=='ZX'){{url('waybill/waybillFinancialExcepted?type=ZX')}}@else{{url('waybill/waybillFinancialExcepted')}}@endif
+    @if($type=='ZF'){{url('transport/waybill/waybillFinancialExcepted?type=ZF')}}@elseif($type=='ZX'){{url('transport/waybill/waybillFinancialExcepted?type=ZX')}}@else{{url('transport/waybill/waybillFinancialExcepted')}}@endif
     @endif ">
     <div class="card-header form-inline">
         <label style="margin-left: 1%"> 开始日期:</label><input style="max-width: 200px" type="date" name="created_at_start" class="form-control form-control-sm"  v-model="filterData.created_at_start">

+ 0 - 35
resources/views/waybill/menu.blade.php

@@ -1,35 +0,0 @@
-
-<div class="container-fluid nav2" id="nav2">
-    <div class="card">
-        <ul class="nav nav-pills">
-            @can('运输管理-查询')
-            <li class="nav-item">
-                <a target="waybill/index" class="nav-link" href="{{url('waybill/index')}}" :class="{active:isActive('index',2)}">查询</a>
-            </li> @endcan
-            @can('运输管理-录入')
-            <li class="nav-item">
-                <a target="waybill/create?type=ZX" class="nav-link" href="{{url('waybill/create?type=ZX')}}" :class="{active:isActive('create',2)}">录入</a>
-            </li> @endcan
-            @can('运输管理-发运')
-            <li class="nav-item">
-                <a target="waybill/delivering" class="nav-link" href="{{url('waybill/delivering')}}" :class="{active:isActive('delivering',2)}">发运</a>
-            </li> @endcan
-            {{$slot}}
-            <li class="nav-item">
-                <a target="waybill/relating" class="nav-link text-dark" href="{{url('waybill/relating')}}" :class="{active:isActive('relating',2)}">相关设置</a>
-            </li>
-            @can('财务报表')
-            <li class="nav-item">
-                <a target="waybill/waybillFinancialSnapshot" class="nav-link text-dark" href="{{url('waybill/waybillFinancialSnapshot')}}" :class="{active:isActive('waybillFinancialSnapshot',2)}">财务报表</a>
-            </li>
-            <li class="nav-item">
-                <a target="waybill/waybillFinancialExcepted" class="nav-link text-dark" href="{{url('waybill/waybillFinancialExcepted')}}" :class="{active:isActive('waybillFinancialExcepted',2)}">异常报表</a>
-            </li>@endcan
-            @can('运输管理-删除')
-            <li class="nav-item">
-                <a target="waybill/recycle" class="nav-link" href="{{url('waybill/recycle')}}" :class="{active:isActive('recycle',2)}">回收站</a>
-            </li>
-            @endcan
-        </ul>
-    </div>
-</div>

+ 22 - 8
routes/apiLocal.php

@@ -26,17 +26,26 @@ Route::post('logistic/logisticNumberReturnIsUnique', 'RejectedBillController@api
 
 Route::post('commodity/getCommodityByBarcode', 'CommodityController@apiGetCommodityByBarcode');
 
-Route::post('waybill/recoverSelected', 'WaybillController@apiRestoreSelected');
-Route::post('waybill/changeFee', 'WaybillController@changeFee');
-Route::post('waybill/changeCharge', 'WaybillController@changeCharge');
-
 Route::post('rejectedBill/getRejectedByLogisticNumberReturn','RejectedController@apiGetRejectedByLogisticNumberReturn');
 
-Route::group(['prefix' => 'order'], function () {
+Route::group(['prefix'=>'transport'],function(){
+    Route::post('waybill/recoverSelected', 'WaybillController@apiRestoreSelected');
+    Route::post('waybill/changeFee', 'WaybillController@changeFee');
+    Route::post('waybill/changeCharge', 'WaybillController@changeCharge');
+    Route::group(['prefix'=>'discharge'],function(){
+        Route::group(['prefix'=>'task'],function() {
+            Route::delete('delete','DischargeTaskController@destroyApi')->name('discharge.deleteApi');;
+            Route::post('store','DischargeTaskController@storeApi')->name('discharge.storeApi');
+            Route::put('update','DischargeTaskController@updateApi')->name('discharge.updateApi');
+            Route::put('updateFacilitator','DischargeTaskController@updateTaskFacilitatorApi')->name('discharge.updateTaskFacilitatorApi');
+            Route::put('updateColumn','DischargeTaskController@updateApi')->name('facilitator.updateColumnApi');
 
+        });
+    });
+});
 
+Route::group(['prefix' => 'order'], function () {
     Route::group(['prefix'=>'issue'],function(){
-
         Route::post('orderIssueHasClientCode', 'OrderIssueController@apiOrderIssueHasClientCode');
         Route::post('orderIssueHasLogisticNumberReturn', 'OrderIssueController@apiOrderIssueHasLogisticNumberReturn');
         Route::post('update', 'OrderIssueController@updateApi');
@@ -71,7 +80,7 @@ Route::group(['prefix' => 'order'], function () {
 
         Route::group(['prefix'=>'log'],function(){
             Route::post('store', 'OrderIssueProcessLogController@apiStore');
-            Route::post('destroy', 'OrderIssueProcessLogController@apiDestroy');
+            Route::post('destroy', 'OrderIssueProcessLogController@destroyApi')->name('order.issue.log.destroyApi');
             Route::post('batchStore','OrderIssueProcessLogController@batchStoreApi');
         });
         Route::group(['prefix'=>'recycle'],function(){
@@ -140,4 +149,9 @@ Route::group(['prefix' => 'configuration'],function(){
     Route::delete('{id}','ConfigurationController@destroyApi');
 });
 
-
+/** 服务商 */
+Route::group(['prefix'=>'facilitator'],function(){
+    Route::post('store','FacilitatorController@storeApi')->name('facilitator.storeApi');
+    Route::put('update','FacilitatorController@updateApi')->name('facilitator.updateApi');
+    Route::delete('destroy','FacilitatorController@destroyApi')->name('facilitator.destroyApi');
+});

+ 56 - 1
routes/web.php

@@ -220,6 +220,8 @@ Route::group(['prefix'=>'maintenance'],function(){
     Route::get('supplier','SupplierController@index');
     /** 系统配置 */
     Route::get('configuration','ConfigurationController@index');
+    /** 服务商 */
+    Route::resource('facilitator','FacilitatorController');
 
     Route::get('syncRedisLogs','LogController@syncRedisLogs');
     Route::get('region', 'RegionController@index');
@@ -256,6 +258,59 @@ Route::group(['prefix'=>'maintenance'],function(){
 });
 Route::get('maintenance', function () {return view('maintenance.index');});
 
+Route::group(['prefix'=>'transport'],function(){
+    /** 运单 */
+    Route::group(['prefix'=>'waybill'],function(){
+        /** 置顶 */
+        Route::group(['prefix'=>'ontop'],function(){
+            Route::post('top','WaybillController@waybillOnTop');
+            Route::post('cancel','WaybillController@cancelOnTop');
+        });
+        /** 判断 */
+        Route::group(['prefix'=>'is'],function(){
+            Route::post('waybillPriceModel','WaybillController@isWaybillPriceModel');
+        });
+        Route::post('deleteImg','WaybillController@deleteImg');
+        Route::post('seekOrder','WaybillController@seekOrder');
+        Route::post('upload','WaybillController@upload');
+        Route::get('relating',function (){return view('transport.waybill.menuWaybill');});
+        Route::get('recycle', 'WaybillController@recycle');
+        Route::post('refreshWaveHouseWeight','WaybillController@refreshWaveHouseWeight');
+        Route::get('index','WaybillController@index');
+        Route::get('delivering','WaybillController@delivering');
+        Route::any('deliveringExport','WaybillController@deliveringExport');
+        Route::post('storeCarrierBill','WaybillController@storeCarrierBill');
+        Route::post('addCounty','WaybillController@addCounty');
+        Route::any('waybillAudit','WaybillController@waybillAudit');
+        Route::any('waybillEdit/{id}','WaybillController@waybillEdit');
+        Route::any('waybillRetreatAudit','WaybillController@waybillRetreatAudit');
+        Route::any('waybillEndAudit','WaybillController@waybillEndAudit');
+        Route::any('export','WaybillController@export');
+        Route::any('waybillUpdate/{id}','WaybillController@waybillUpdate');
+        Route::post('batchUploadImages','WaybillController@batchUploadImages');
+        Route::resource('waybillFinancialSnapshot','WaybillFinancialSnapshotsController');
+        Route::resource('waybillFinancialExcepted','WaybillFinancialExceptedController');
+    });
+    Route::resource('waybill','WaybillController');
+    /** 卸货 */
+    Route::group(['prefix'=>'discharge'],function(){
+        /** 卸货任务 */
+        Route::group(['prefix'=>'task'],function(){
+            Route::get('index','DischargeTaskController@index');
+            Route::any('export','DischargeTaskController@export');
+        });
+        /** 结算报表 */
+        Route::group(['prefix'=>'statement'],function(){
+            Route::get('index','DischargeTaskController@statementIndex');
+            Route::any('export','DischargeTaskController@exportStatements');
+        });
+        /** 服务商  对账单*/
+        Route::group(['prefix'=>'facilitator'],function(){
+            Route::get('index','FacilitatorController@statementIndex');
+            Route::any('export','FacilitatorController@exportStatement');
+        });
+    });
+});
 /** 运输 */
 Route::group(['prefix'=>'waybill'],function(){
     /** 置顶 */
@@ -270,7 +325,7 @@ Route::group(['prefix'=>'waybill'],function(){
     Route::post('deleteImg','WaybillController@deleteImg');
     Route::post('seekOrder','WaybillController@seekOrder');
     Route::post('upload','WaybillController@upload');
-    Route::get('relating',function (){return view('waybill.menuWaybill');});
+    Route::get('relating',function (){return view('transport.waybill.menuWaybill');});
     Route::get('recycle', 'WaybillController@recycle');
     Route::post('refreshWaveHouseWeight','WaybillController@refreshWaveHouseWeight');
     Route::get('index','WaybillController@index');

+ 7 - 7
tests/codeCoverage/Http/Controllers/WaybillsController.php.html

@@ -408,7 +408,7 @@
      <tr><td><div align="right"><a name="26"></a><a href="#26">26</a></div></td><td class="codeLine"></td></tr>
      <tr><td><div align="right"><a name="27"></a><a href="#27">27</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">index</span><span class="keyword">(</span><span class="default">Request</span><span class="default">&nbsp;</span><span class="default">$request</span><span class="keyword">)</span></td></tr>
      <tr><td><div align="right"><a name="28"></a><a href="#28">28</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
-     <tr class="covered-by-large-tests popin" data-title="2 tests cover line 29" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testIndex&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Feature\FromTest::testDelete&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="29"></a><a href="#29">29</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-查询'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+     <tr class="covered-by-large-tests popin" data-title="2 tests cover line 29" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testIndex&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Feature\FromTest::testDelete&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="29"></a><a href="#29">29</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单-查询'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 30" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testIndex&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="30"></a><a href="#30">30</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$data</span><span class="keyword">=</span><span class="default">$request</span><span class="default">-&gt;</span><span class="default">input</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 31" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testIndex&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="31"></a><a href="#31">31</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="default">&nbsp;</span><span class="keyword">(</span><span class="default">$data</span><span class="default">&nbsp;</span><span class="default">!=</span><span class="default">&nbsp;</span><span class="default">null</span><span class="default">&nbsp;</span><span class="keyword">)</span><span class="default">&nbsp;</span><span class="keyword">{</span></td></tr>
      <tr class="danger"><td><div align="right"><a name="32"></a><a href="#32">32</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$today</span><span class="keyword">=</span><span class="default">Carbon</span><span class="default">::</span><span class="default">now</span><span class="keyword">(</span><span class="keyword">)</span><span class="default">-&gt;</span><span class="default">subDays</span><span class="keyword">(</span><span class="default">15</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
@@ -455,14 +455,14 @@
      <tr class="warning"><td><div align="right"><a name="73"></a><a href="#73">73</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr><td><div align="right"><a name="74"></a><a href="#74">74</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">create</span><span class="keyword">(</span><span class="keyword">)</span></td></tr>
      <tr><td><div align="right"><a name="75"></a><a href="#75">75</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
-     <tr class="covered-by-large-tests popin" data-title="1 test covers line 76" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testCreate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="76"></a><a href="#76">76</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-录入'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+     <tr class="covered-by-large-tests popin" data-title="1 test covers line 76" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testCreate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="76"></a><a href="#76">76</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单-录入'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 77" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testCreate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="77"></a><a href="#77">77</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$owners</span><span class="keyword">=</span><span class="default">Owner</span><span class="default">::</span><span class="default">get</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 78" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testCreate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="78"></a><a href="#78">78</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">view</span><span class="keyword">(</span><span class="default">'waybill.create'</span><span class="keyword">,</span><span class="keyword">[</span><span class="default">'owners'</span><span class="default">=&gt;</span><span class="default">$owners</span><span class="keyword">]</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="warning"><td><div align="right"><a name="79"></a><a href="#79">79</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr><td><div align="right"><a name="80"></a><a href="#80">80</a></div></td><td class="codeLine"></td></tr>
      <tr><td><div align="right"><a name="81"></a><a href="#81">81</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">store</span><span class="keyword">(</span><span class="default">Request</span><span class="default">&nbsp;</span><span class="default">$request</span><span class="keyword">)</span></td></tr>
      <tr><td><div align="right"><a name="82"></a><a href="#82">82</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
-     <tr class="covered-by-large-tests popin" data-title="1 test covers line 83" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testStore&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="83"></a><a href="#83">83</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-录入'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+     <tr class="covered-by-large-tests popin" data-title="1 test covers line 83" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testStore&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="83"></a><a href="#83">83</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单-录入'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 84" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testStore&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="84"></a><a href="#84">84</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">validatorWaybill</span><span class="keyword">(</span><span class="default">$request</span><span class="keyword">)</span><span class="default">-&gt;</span><span class="default">validate</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 85" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testStore&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="85"></a><a href="#85">85</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$data</span><span class="keyword">=</span><span class="default">$request</span><span class="default">-&gt;</span><span class="default">input</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr><td><div align="right"><a name="86"></a><a href="#86">86</a></div></td><td class="codeLine"></td></tr>
@@ -507,7 +507,7 @@
      <tr><td><div align="right"><a name="125"></a><a href="#125">125</a></div></td><td class="codeLine"></td></tr>
      <tr><td><div align="right"><a name="126"></a><a href="#126">126</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">update</span><span class="keyword">(</span><span class="default">Request</span><span class="default">&nbsp;</span><span class="default">$request</span><span class="keyword">,</span><span class="default">&nbsp;</span><span class="default">$id</span><span class="keyword">)</span></td></tr>
      <tr><td><div align="right"><a name="127"></a><a href="#127">127</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
-     <tr class="covered-by-large-tests popin" data-title="2 tests cover line 128" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testUpdate&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillUpdate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="128"></a><a href="#128">128</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-调度'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+     <tr class="covered-by-large-tests popin" data-title="2 tests cover line 128" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testUpdate&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillUpdate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="128"></a><a href="#128">128</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单-调度'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="2 tests cover line 129" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testUpdate&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillUpdate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="129"></a><a href="#129">129</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">validatorWaybillDispatch</span><span class="keyword">(</span><span class="default">$request</span><span class="keyword">)</span><span class="default">-&gt;</span><span class="default">validate</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="2 tests cover line 130" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testUpdate&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillUpdate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="130"></a><a href="#130">130</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$data</span><span class="keyword">=</span><span class="default">$request</span><span class="default">-&gt;</span><span class="default">input</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="2 tests cover line 131" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testUpdate&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillUpdate&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="131"></a><a href="#131">131</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$waybill</span><span class="keyword">=</span><span class="default">Waybill</span><span class="default">::</span><span class="default">find</span><span class="keyword">(</span><span class="default">$id</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
@@ -574,7 +574,7 @@
      <tr class="danger"><td><div align="right"><a name="192"></a><a href="#192">192</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr><td><div align="right"><a name="193"></a><a href="#193">193</a></div></td><td class="codeLine"></td></tr>
      <tr><td><div align="right"><a name="194"></a><a href="#194">194</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">waybillAudit</span><span class="keyword">(</span><span class="default">Request</span><span class="default">&nbsp;</span><span class="default">$request</span><span class="keyword">)</span><span class="keyword">{</span></td></tr>
-     <tr class="covered-by-large-tests popin" data-title="1 test covers line 195" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="195"></a><a href="#195">195</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单审核'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+     <tr class="covered-by-large-tests popin" data-title="1 test covers line 195" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="195"></a><a href="#195">195</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单-运单审核'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 196" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="196"></a><a href="#196">196</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$id</span><span class="keyword">=</span><span class="default">$request</span><span class="default">-&gt;</span><span class="default">input</span><span class="keyword">(</span><span class="default">'id'</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 197" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="197"></a><a href="#197">197</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$waybill</span><span class="keyword">=</span><span class="default">Waybill</span><span class="default">::</span><span class="default">find</span><span class="keyword">(</span><span class="default">$id</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 198" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="198"></a><a href="#198">198</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$isAudit</span><span class="keyword">=</span><span class="default">WaybillAuditLog</span><span class="default">::</span><span class="default">whereRaw</span><span class="keyword">(</span><span class="default">'waybill_id&nbsp;=&nbsp;?&nbsp;and&nbsp;audit_stage&nbsp;=&nbsp;?'</span><span class="keyword">,</span><span class="keyword">[</span><span class="default">$id</span><span class="keyword">,</span><span class="default">&quot;运单阶段&quot;</span><span class="keyword">]</span><span class="keyword">)</span><span class="default">-&gt;</span><span class="default">first</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
@@ -601,7 +601,7 @@
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 219" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillEdit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="219"></a><a href="#219">219</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">view</span><span class="keyword">(</span><span class="default">'waybill.waybillEdit'</span><span class="keyword">,</span><span class="keyword">[</span><span class="default">'waybill'</span><span class="default">=&gt;</span><span class="default">$waybill</span><span class="keyword">,</span><span class="default">'owners'</span><span class="default">=&gt;</span><span class="default">$owners</span><span class="keyword">]</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="warning"><td><div align="right"><a name="220"></a><a href="#220">220</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr><td><div align="right"><a name="221"></a><a href="#221">221</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">waybillRetreatAudit</span><span class="keyword">(</span><span class="default">Request</span><span class="default">&nbsp;</span><span class="default">$request</span><span class="keyword">)</span><span class="keyword">{</span></td></tr>
-     <tr class="covered-by-large-tests popin" data-title="1 test covers line 222" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillRetreatAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="222"></a><a href="#222">222</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-调度'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+     <tr class="covered-by-large-tests popin" data-title="1 test covers line 222" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillRetreatAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="222"></a><a href="#222">222</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单-调度'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 223" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillRetreatAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="223"></a><a href="#223">223</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$id</span><span class="keyword">=</span><span class="default">$request</span><span class="default">-&gt;</span><span class="default">input</span><span class="keyword">(</span><span class="default">'id'</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 224" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillRetreatAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="224"></a><a href="#224">224</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$waybill</span><span class="keyword">=</span><span class="default">Waybill</span><span class="default">::</span><span class="default">find</span><span class="keyword">(</span><span class="default">$id</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 225" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillRetreatAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="225"></a><a href="#225">225</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">WaybillAuditLog</span><span class="default">::</span><span class="default">whereRaw</span><span class="keyword">(</span><span class="default">'waybill_id&nbsp;=&nbsp;?&nbsp;and&nbsp;audit_stage&nbsp;=&nbsp;?'</span><span class="keyword">,</span><span class="keyword">[</span><span class="default">$id</span><span class="keyword">,</span><span class="default">&quot;运单阶段&quot;</span><span class="keyword">]</span><span class="keyword">)</span><span class="default">-&gt;</span><span class="default">delete</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
@@ -611,7 +611,7 @@
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 229" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillRetreatAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="229"></a><a href="#229">229</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="keyword">[</span><span class="default">'success'</span><span class="default">=&gt;</span><span class="default">$result</span><span class="keyword">,</span><span class="default">'state'</span><span class="default">=&gt;</span><span class="default">$waybill</span><span class="default">-&gt;</span><span class="default">state</span><span class="keyword">]</span><span class="keyword">;</span></td></tr>
      <tr class="warning"><td><div align="right"><a name="230"></a><a href="#230">230</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr><td><div align="right"><a name="231"></a><a href="#231">231</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">waybillEndAudit</span><span class="keyword">(</span><span class="default">Request</span><span class="default">&nbsp;</span><span class="default">$request</span><span class="keyword">)</span><span class="keyword">{</span></td></tr>
-     <tr class="covered-by-large-tests popin" data-title="1 test covers line 232" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillEndAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="232"></a><a href="#232">232</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-调度审核'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+     <tr class="covered-by-large-tests popin" data-title="1 test covers line 232" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillEndAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="232"></a><a href="#232">232</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="keyword">(</span><span class="keyword">!</span><span class="default">Gate</span><span class="default">::</span><span class="default">allows</span><span class="keyword">(</span><span class="default">'运输管理-运单-调度审核'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">{</span><span class="default">&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">redirect</span><span class="keyword">(</span><span class="default">url</span><span class="keyword">(</span><span class="default">'/'</span><span class="keyword">)</span><span class="keyword">)</span><span class="keyword">;</span><span class="default">&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 233" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillEndAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="233"></a><a href="#233">233</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$id</span><span class="keyword">=</span><span class="default">$request</span><span class="default">-&gt;</span><span class="default">input</span><span class="keyword">(</span><span class="default">'id'</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 234" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillEndAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="234"></a><a href="#234">234</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$waybill</span><span class="keyword">=</span><span class="default">Waybill</span><span class="default">::</span><span class="default">find</span><span class="keyword">(</span><span class="default">$id</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
      <tr class="covered-by-large-tests popin" data-title="1 test covers line 235" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;Tests\Unit\WaybillTest::testWaybillEndAudit&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="235"></a><a href="#235">235</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$isAudit</span><span class="keyword">=</span><span class="default">WaybillAuditLog</span><span class="default">::</span><span class="default">whereRaw</span><span class="keyword">(</span><span class="default">'waybill_id&nbsp;=&nbsp;?&nbsp;and&nbsp;audit_stage&nbsp;=&nbsp;?'</span><span class="keyword">,</span><span class="keyword">[</span><span class="default">$id</span><span class="keyword">,</span><span class="default">&quot;调度阶段&quot;</span><span class="keyword">]</span><span class="keyword">)</span><span class="default">-&gt;</span><span class="default">first</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>

+ 92 - 0
tests/old/OrderIssueTest.php

@@ -0,0 +1,92 @@
+<?php
+
+namespace Tests\Unit;
+
+use App\Authority;
+use App\Commodity;
+use App\CommodityBarcode;
+use App\MeasuringMachine;
+use App\Order;
+use App\OrderIssue;
+use App\OrderIssueRejectedBill;
+use App\OrderPackage;
+use App\OrderPackageCommodities;
+use App\RejectedBill;
+use App\RejectedBillItem;
+use App\Role;
+use App\User;
+use Illuminate\Support\Facades\DB;
+use Tests\TestCase;
+use Illuminate\Foundation\Testing\WithFaker;
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use function Matrix\add;
+
+class OrderIssueTest extends TestCase
+{
+
+    public function getTestResult()
+    {
+        $orderIssue = factory(OrderIssue::class)->create(['rejecting_status' => '未退回']);
+        $orderPackage = factory(OrderPackage::class)->create(['order_id' => $orderIssue->order->id]);
+        $commodities = factory(Commodity::class)->times(3)->create(['owner_id' => $orderIssue->order->owner_id]);
+        $orderPackageCommodities = collect();
+        $commodities_barcodes = collect();
+        foreach ($commodities as $commodity) {
+            $commodities_barcode = factory(CommodityBarcode::class)->create(['commodity_id' => $commodity->id]);
+            $commodities_barcodes->push($commodities_barcode);
+            $orderPackageCommodity = factory(OrderPackageCommodities::class)->create(['order_package_id' => $orderPackage->id, 'amount' => 1, 'commodity_id' => $commodity->id]);
+            $orderPackageCommodities->push($orderPackageCommodity);
+        }
+        $rejectedBill = factory(RejectedBill::class)->create(['logistic_number_return' => $orderIssue->logistic_number_return]);
+        $rejectedBill_items = collect();
+        foreach ($commodities_barcodes as $commodities_barcode) {
+            $item = factory(RejectedBillItem::class)->create(['id_rejected_bill' => $rejectedBill->id, 'barcode_goods' => $commodities_barcode->code, 'amount' => 1]);
+            $rejectedBill_items->push($item);
+        }
+        $orderIssueRejectedBill = factory(OrderIssueRejectedBill::class)->create(['order_issue_id' => $orderIssue->id, 'logistic_number_return' => $rejectedBill->logistic_number_return]);
+        return [
+            'orderIssue' => $orderIssue,
+            'orderPackage' => $orderPackage,
+            'commodities' => $commodities,
+            'orderPackageCommodities' => $orderPackageCommodities,
+            'rejectedBill' => $rejectedBill,
+            'rejectedBill_items' => $rejectedBill_items,
+        ];
+    }
+
+    public function destroyResult(array $arr)
+    {
+        if($arr['orderIssue']){
+            $arr['orderIssue']->order->delete();
+            $arr['orderIssue']->delete();
+        }
+        if($arr['orderPackage'])$arr['orderPackage']->delete();
+        if($arr['commodities']){
+            foreach ($arr['commodities'] as $commodity) {
+                CommodityBarcode::query()->where('commodity_id',$commodity->id)->delete();
+                $commodity->delete();
+            }
+        }
+        if($arr['rejectedBill'])$arr['rejectedBill']->delete();
+        if($arr['rejectedBill_items']){
+            foreach ($arr['rejectedBill_items'] as $rejectedBill_item) {
+                $rejectedBill_item->delete();
+            }
+        }
+        OrderIssueRejectedBill::query()->where('Order_Issue_Id',$arr['orderIssue']->id)->delete();
+    }
+
+
+    public function testSyncRejectingStatusComparisonIsEqual()
+    {
+        $arr = $this->getTestResult();
+        $orderIssue = $arr['orderIssue'];
+        $orderIssue->syncRejectingStatus();
+        $orderIssue->refresh();
+        $this->assertEquals($orderIssue->rejecting_status, "全部退回");
+        $this->destroyResult($arr);
+    }
+
+
+
+}

+ 19 - 0
yarn.lock

@@ -1376,6 +1376,11 @@ base64-arraybuffer@0.1.5:
   resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
   integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
 
+base64-arraybuffer@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.npm.taobao.org/base64-arraybuffer/download/base64-arraybuffer-0.2.0.tgz#4b944fac0191aa5907afe2d8c999ccc57ce80f45"
+  integrity sha1-S5RPrAGRqlkHr+LYyZnMxXzoD0U=
+
 base64-js@^1.0.2:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
@@ -2275,6 +2280,13 @@ css-declaration-sorter@^4.0.1:
     postcss "^7.0.1"
     timsort "^0.3.0"
 
+css-line-break@1.1.1:
+  version "1.1.1"
+  resolved "https://registry.npm.taobao.org/css-line-break/download/css-line-break-1.1.1.tgz#d5e9bdd297840099eb0503c7310fd34927a026ef"
+  integrity sha1-1em90peEAJnrBQPHMQ/TSSegJu8=
+  dependencies:
+    base64-arraybuffer "^0.2.0"
+
 css-loader@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-1.0.1.tgz#6885bb5233b35ec47b006057da01cc640b6b79fe"
@@ -3686,6 +3698,13 @@ html-minifier@^3.5.8:
     relateurl "0.2.x"
     uglify-js "3.4.x"
 
+html2canvas@^1.0.0-rc.7:
+  version "1.0.0-rc.7"
+  resolved "https://registry.npm.taobao.org/html2canvas/download/html2canvas-1.0.0-rc.7.tgz#70c159ce0e63954a91169531894d08ad5627ac98"
+  integrity sha1-cMFZzg5jlUqRFpUxiU0IrVYnrJg=
+  dependencies:
+    css-line-break "1.1.1"
+
 http-deceiver@^1.2.7:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"