正在显示
17 个修改的文件
包含
768 行增加
和
94 行删除
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Controllers\Aside\WorkOrder; | ||
| 4 | + | ||
| 5 | +use App\Enums\Common\Code; | ||
| 6 | +use App\Http\Controllers\Aside\BaseController; | ||
| 7 | +use App\Http\Requests\Aside\WorkOrder\WorkOrderListRequest; | ||
| 8 | +use App\Http\Requests\Aside\WorkOrder\WorkOrderUpdateRequest; | ||
| 9 | +use App\Models\WorkOrder\WorkOrder; | ||
| 10 | +use App\Models\WorkOrder\WorkOrderLog; | ||
| 11 | + | ||
| 12 | +class WorkOrderController extends BaseController | ||
| 13 | +{ | ||
| 14 | + /** | ||
| 15 | + * A端工单列表 | ||
| 16 | + * 显示有我参与的工单列表 | ||
| 17 | + */ | ||
| 18 | + public function index(WorkOrderListRequest $request) | ||
| 19 | + { | ||
| 20 | + /* | ||
| 21 | + * A端工程师工单列表, 查询我的工单 | ||
| 22 | + */ | ||
| 23 | + $request->validated(); | ||
| 24 | + # manage_id 或 engineer_id 是我 | ||
| 25 | + $lists = WorkOrderLog::with([ | ||
| 26 | + 'workOrder.logs.manager:id,name', | ||
| 27 | + ]) | ||
| 28 | + ->where('manage_id', $this->manage['id']) | ||
| 29 | + ->when($request->has('status'), function ($query) use ($request) { | ||
| 30 | + return $query->where('status', $request->input('status')); | ||
| 31 | + }) | ||
| 32 | + ->when($request->has('search'), function ($query) use ($request) { | ||
| 33 | + return $query->whereHas('workOrder', function ($q) use ($request) { | ||
| 34 | + $q->where('product', 'like', '%' . $request->input('search') . '%') | ||
| 35 | + ->orWhere('content', 'like', '%' . $request->input('search') . '%'); | ||
| 36 | + }); | ||
| 37 | + }) | ||
| 38 | + ->orderBy('id', 'desc') | ||
| 39 | + ->paginate($this->row, ['*'], 'page', $this->page); | ||
| 40 | + $this->response('success', Code::SUCCESS, $lists); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * @param WorkOrderListRequest $request | ||
| 46 | + * @return void | ||
| 47 | + * A端管理员的工单列表 | ||
| 48 | + */ | ||
| 49 | + public function manager(WorkOrderListRequest $request) | ||
| 50 | + { | ||
| 51 | + $request->validated(); | ||
| 52 | + // 管理员查看所有工单 | ||
| 53 | + $lists = WorkOrder::with([ | ||
| 54 | + 'user:id,name', | ||
| 55 | + 'manager:id,name', | ||
| 56 | + 'engineer:id,name', | ||
| 57 | + 'logs.manager:id,name', | ||
| 58 | + ]) | ||
| 59 | + ->when($request->has('status'), function ($query) use ($request) { | ||
| 60 | + return $query->where('status', $request->input('status')); | ||
| 61 | + }) | ||
| 62 | + ->when($request->has('search'), function ($query) use ($request) { | ||
| 63 | + return $query->where('product', 'like', '%' . $request->input('search') . '%') | ||
| 64 | + ->orWhere('content', 'like', '%' . $request->input('search') . '%'); | ||
| 65 | + }) | ||
| 66 | + ->orderBy('id', 'desc') | ||
| 67 | + ->paginate($this->row, ['*'], 'page', $this->page); | ||
| 68 | + $this->response('success', Code::SUCCESS, $lists); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * A端工单详情 | ||
| 73 | + * | ||
| 74 | + * @param int $id | ||
| 75 | + * @return \Illuminate\Http\Response | ||
| 76 | + */ | ||
| 77 | + public function show($id) | ||
| 78 | + { | ||
| 79 | + $workOrder = WorkOrder::with([ | ||
| 80 | + 'logs.manager:id,name', | ||
| 81 | + 'user:id,name', | ||
| 82 | + 'manager:id,name', | ||
| 83 | + 'engineer:id,name', | ||
| 84 | + ])->find($id); | ||
| 85 | + | ||
| 86 | + if (!$workOrder) | ||
| 87 | + $this->response('工单不存在', Code::USER_MODEL_NOTFOUND_ERROE); | ||
| 88 | + | ||
| 89 | + // TODO 判断是否有查看工单详情权限,待添加 | ||
| 90 | + $this->response('success', Code::SUCCESS, $workOrder->toArray()); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + /** | ||
| 94 | + * A端更新工单 | ||
| 95 | + * 要么更新状态,要么分配工程师 | ||
| 96 | + */ | ||
| 97 | + public function update(WorkOrderUpdateRequest $request, $id) | ||
| 98 | + { | ||
| 99 | + $request->validated(); | ||
| 100 | + // 更新工单状态 | ||
| 101 | + $workOrder = WorkOrder::find($id); | ||
| 102 | + if (!$workOrder) { | ||
| 103 | + $this->response('工单不存在', Code::USER_MODEL_NOTFOUND_ERROE); | ||
| 104 | + } | ||
| 105 | + if ($request->has('status')) | ||
| 106 | + $workOrder->status = $request->input('status'); | ||
| 107 | + if ($request->has('engineer_id')) | ||
| 108 | + { | ||
| 109 | + try { | ||
| 110 | + // 利用唯一索引去重 | ||
| 111 | + $log = new WorkOrderLog(); | ||
| 112 | + $log->manage_id = $request->input('engineer_id'); | ||
| 113 | + $workOrder->logs()->save($log); | ||
| 114 | + }catch (\Exception $exception){} | ||
| 115 | + $workOrder->engineer_id = $request->input('engineer_id'); | ||
| 116 | + } | ||
| 117 | + $workOrder->save(); | ||
| 118 | + $this->response('success', Code::SUCCESS, $workOrder->toArray()); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Controllers\Bside\WorkOrder; | ||
| 4 | + | ||
| 5 | +use App\Enums\Common\Code; | ||
| 6 | +use App\Http\Controllers\Bside\BaseController; | ||
| 7 | +use App\Http\Requests\Aside\WorkOrder\WorkOrderListRequest; | ||
| 8 | +use App\Http\Requests\Bside\WorkOrder\WorkOrderCreateRequest; | ||
| 9 | +use App\Http\Requests\Bside\WorkOrder\WorkOrderUpdateRequest; | ||
| 10 | +use App\Models\Project\Project; | ||
| 11 | +use App\Models\WorkOrder\WorkOrder; | ||
| 12 | +use App\Models\WorkOrder\WorkOrderLog; | ||
| 13 | +use Illuminate\Support\Facades\DB; | ||
| 14 | + | ||
| 15 | +class WorkOrderController extends BaseController | ||
| 16 | +{ | ||
| 17 | + /** | ||
| 18 | + * B端售后工单列表 | ||
| 19 | + * | ||
| 20 | + * @return \Illuminate\Http\Response | ||
| 21 | + */ | ||
| 22 | + public function index(WorkOrder $workOrder, WorkOrderListRequest $request) | ||
| 23 | + { | ||
| 24 | + $request->validated(); | ||
| 25 | + $where = [ | ||
| 26 | + 'project_id' => $this->user['project_id'], | ||
| 27 | + ]; | ||
| 28 | + // 分页查询 | ||
| 29 | + $lists = $workOrder->where($where) | ||
| 30 | + ->when($request->input('status'), function ($query) use ($request) { | ||
| 31 | + return $query->where('status', $request->input('status')); | ||
| 32 | + }) | ||
| 33 | + ->when($request->input('search'), function ($query) use ($request) { | ||
| 34 | + return $query->where('product', 'like', '%' . $request->input('search') . '%') | ||
| 35 | + ->orWhere('content', 'like', '%' . $request->input('search') . '%'); | ||
| 36 | + }) | ||
| 37 | + ->orderBy('id', 'desc')->paginate($this->row, ['*'], 'page', $this->page); | ||
| 38 | + $this->response('success', Code::SUCCESS, $lists); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * B端用户提交工单 | ||
| 43 | + * | ||
| 44 | + * @return \Illuminate\Http\Response | ||
| 45 | + */ | ||
| 46 | + public function store(WorkOrderCreateRequest $request) | ||
| 47 | + { | ||
| 48 | + $request->validated(); | ||
| 49 | + $result = DB::transaction(function () use ($request) { | ||
| 50 | + $workOrder = new WorkOrder; | ||
| 51 | + $workOrder->product = $request->input('product'); | ||
| 52 | + $workOrder->content = $request->input('content'); | ||
| 53 | + $workOrder->files = json_encode($request->input('files')); | ||
| 54 | + $workOrder->project_user_id = $this->user['id']; | ||
| 55 | + $workOrder->project_id = $this->user['project_id']; | ||
| 56 | + $workOrder->engineer_id = 0; | ||
| 57 | + if ($this->project['type'] == 3){ | ||
| 58 | + // 项目类型是优化推广,项目负责人找优化 | ||
| 59 | + $seo = Project::find($this->user['project_id'])->deploy_optimize; | ||
| 60 | + $workOrder->manage_id = $seo->manager_mid ?? $seo->optimist_mid ?? 0; | ||
| 61 | + }else{ | ||
| 62 | + // 非优化推广项目,项目负责人找技术组长 | ||
| 63 | + $build = Project::find($this->user['project_id'])->deploy_build; | ||
| 64 | + $workOrder->manage_id = $build->leader_mid ?? 0; | ||
| 65 | + } | ||
| 66 | + $workOrder->save(); | ||
| 67 | + // 添加工单日志 | ||
| 68 | + $log = new WorkOrderLog(); | ||
| 69 | + $log->manage_id = $workOrder->manage_id; | ||
| 70 | + $workOrder->logs()->save($log); | ||
| 71 | + return $workOrder; | ||
| 72 | + }); | ||
| 73 | + $this->response('success', Code::SUCCESS, $result->toArray()); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * Display the specified resource. | ||
| 78 | + * | ||
| 79 | + * @param int $id | ||
| 80 | + * @return \Illuminate\Http\Response | ||
| 81 | + */ | ||
| 82 | + public function show($id) | ||
| 83 | + { | ||
| 84 | + $workOrder = WorkOrder::with([ | ||
| 85 | + 'logs.manager:id,name', | ||
| 86 | + 'user:id,name', | ||
| 87 | + 'manager:id,name', | ||
| 88 | + 'engineer:id,name', | ||
| 89 | + ])->find($id); | ||
| 90 | + if (!$workOrder) { | ||
| 91 | + $this->response('error', 404, '工单未找到'); | ||
| 92 | + } | ||
| 93 | + if ($workOrder->project_id != $this->user['project_id'] && $workOrder->engineer_id != $this->user['id']) { | ||
| 94 | + $this->response('error', 403, '无权限查看该工单'); | ||
| 95 | + } | ||
| 96 | + $this->response('success', Code::SUCCESS, $workOrder->toArray()); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * B端用户修改工单,只能是修改工单状态 | ||
| 101 | + * | ||
| 102 | + * @param \Illuminate\Http\Request $request | ||
| 103 | + * @param int $id | ||
| 104 | + * @return \Illuminate\Http\Response | ||
| 105 | + */ | ||
| 106 | + public function update(WorkOrderUpdateRequest $request, $id) | ||
| 107 | + { | ||
| 108 | + $request->validated(); | ||
| 109 | + $workOrder = WorkOrder::find($id); | ||
| 110 | + if (!$workOrder) { | ||
| 111 | + $this->response('error', 404, '工单未找到'); | ||
| 112 | + } | ||
| 113 | + // b端只有自己项目下的账号可以更新工单 | ||
| 114 | + if ($workOrder->project_id != $this->user['project_id']) { | ||
| 115 | + $this->response('error', 403, '无权限更新该工单'); | ||
| 116 | + } | ||
| 117 | + // 更新工单状态 | ||
| 118 | + $workOrder->status = $request->input('status'); | ||
| 119 | + $workOrder->save(); | ||
| 120 | + $this->response('success', Code::SUCCESS); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Requests\Aside\WorkOrder; | ||
| 4 | + | ||
| 5 | +use Illuminate\Foundation\Http\FormRequest; | ||
| 6 | + | ||
| 7 | +class WorkOrderListRequest extends FormRequest | ||
| 8 | +{ | ||
| 9 | + /** | ||
| 10 | + * Determine if the user is authorized to make this request. | ||
| 11 | + * | ||
| 12 | + * @return bool | ||
| 13 | + */ | ||
| 14 | + public function authorize() | ||
| 15 | + { | ||
| 16 | + return true; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * Get the validation rules that apply to the request. | ||
| 21 | + * | ||
| 22 | + * @return array | ||
| 23 | + */ | ||
| 24 | + public function rules() | ||
| 25 | + { | ||
| 26 | + return [ | ||
| 27 | + 'page' => 'nullable|integer', | ||
| 28 | + 'size' => 'nullable|integer', | ||
| 29 | + 'project_id' => 'nullable|integer', // 产品ID | ||
| 30 | + 'status' => 'nullable|in:0,1,2,3|integer', | ||
| 31 | + 'search' => 'nullable|string', // 搜索关键词 | ||
| 32 | + ]; | ||
| 33 | + } | ||
| 34 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Requests\Aside\WorkOrder; | ||
| 4 | + | ||
| 5 | +use Illuminate\Foundation\Http\FormRequest; | ||
| 6 | + | ||
| 7 | +class WorkOrderUpdateRequest extends FormRequest | ||
| 8 | +{ | ||
| 9 | + /** | ||
| 10 | + * Determine if the user is authorized to make this request. | ||
| 11 | + * | ||
| 12 | + * @return bool | ||
| 13 | + */ | ||
| 14 | + public function authorize() | ||
| 15 | + { | ||
| 16 | + return true; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * Get the validation rules that apply to the request. | ||
| 21 | + * | ||
| 22 | + * @return array | ||
| 23 | + * A端更新售后工单 | ||
| 24 | + */ | ||
| 25 | + public function rules() | ||
| 26 | + { | ||
| 27 | + return [ | ||
| 28 | + 'status' => 'nullable|in:0,1,2,3|integer', | ||
| 29 | + 'engineer_id' => 'nullable|integer', | ||
| 30 | + ]; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public function withValidator($validator) | ||
| 34 | + { | ||
| 35 | + $validator->after(function ($validator) { | ||
| 36 | + $status = $this->input('status'); | ||
| 37 | + $engineerId = $this->input('engineer_id'); | ||
| 38 | + if (is_null($status) && is_null($engineerId)) { | ||
| 39 | + $validator->errors()->add('status', 'status 和 engineer_id 不能全是空'); | ||
| 40 | + } | ||
| 41 | + }); | ||
| 42 | + } | ||
| 43 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Requests\Bside\WorkOrder; | ||
| 4 | + | ||
| 5 | +use Illuminate\Foundation\Http\FormRequest; | ||
| 6 | + | ||
| 7 | +class WorkOrderCreateRequest extends FormRequest | ||
| 8 | +{ | ||
| 9 | + /** | ||
| 10 | + * Determine if the user is authorized to make this request. | ||
| 11 | + * | ||
| 12 | + * @return bool | ||
| 13 | + */ | ||
| 14 | + public function authorize() | ||
| 15 | + { | ||
| 16 | + return true; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * Get the validation rules that apply to the request. | ||
| 21 | + * | ||
| 22 | + * @return array | ||
| 23 | + */ | ||
| 24 | + public function rules() | ||
| 25 | + { | ||
| 26 | + return [ | ||
| 27 | + 'product' => 'required|string', | ||
| 28 | + 'content' => 'required|string', | ||
| 29 | + 'files' => 'nullable|array', | ||
| 30 | + ]; | ||
| 31 | + } | ||
| 32 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Requests\Bside\WorkOrder; | ||
| 4 | + | ||
| 5 | +use Illuminate\Foundation\Http\FormRequest; | ||
| 6 | + | ||
| 7 | +class WorkOrderUpdateRequest extends FormRequest | ||
| 8 | +{ | ||
| 9 | + /** | ||
| 10 | + * Determine if the user is authorized to make this request. | ||
| 11 | + * | ||
| 12 | + * @return bool | ||
| 13 | + */ | ||
| 14 | + public function authorize() | ||
| 15 | + { | ||
| 16 | + return true; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * Get the validation rules that apply to the request. | ||
| 21 | + * | ||
| 22 | + * @return array | ||
| 23 | + */ | ||
| 24 | + public function rules() | ||
| 25 | + { | ||
| 26 | + return [ | ||
| 27 | + 'status' => 'required|in:0,1,2,3|integer', | ||
| 28 | + ]; | ||
| 29 | + } | ||
| 30 | +} |
app/Models/WorkOrder/WorkOrder.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Models\WorkOrder; | ||
| 4 | + | ||
| 5 | +use App\Models\Base; | ||
| 6 | +use App\Models\Manage\Manage; | ||
| 7 | +use App\Models\Project\Project; | ||
| 8 | +use App\Models\User\User; | ||
| 9 | + | ||
| 10 | +class WorkOrder extends Base | ||
| 11 | +{ | ||
| 12 | + protected $table = 'gl_work_orders'; | ||
| 13 | + | ||
| 14 | + const STATUS_PEDDING = 0; // 待处理 | ||
| 15 | + const STATUS_PROCESSING = 1; // 处理中 | ||
| 16 | + const STATUS_COMPLETED = 2; // 已完成 | ||
| 17 | + const STATUS_CLOSED = 3; // 已关闭 | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * 工单操作日志 | ||
| 22 | + */ | ||
| 23 | + public function logs() | ||
| 24 | + { | ||
| 25 | + return $this->hasMany(WorkOrderLog::class, 'work_order_id', 'id'); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 提交工单的用户 | ||
| 30 | + */ | ||
| 31 | + public function user() | ||
| 32 | + { | ||
| 33 | + return $this->belongsTo(User::class, 'project_user_id', 'id'); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 工单分配的管理员 | ||
| 38 | + */ | ||
| 39 | + public function manager() | ||
| 40 | + { | ||
| 41 | + return $this->belongsTo(Manage::class, 'manage_id', 'id'); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * 工单分配的工程师 | ||
| 46 | + */ | ||
| 47 | + public function engineer() | ||
| 48 | + { | ||
| 49 | + return $this->belongsTo(Manage::class, 'engineer_id', 'id'); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + /** 工单所属项目 */ | ||
| 53 | + public function project() | ||
| 54 | + { | ||
| 55 | + return $this->belongsTo(Project::class, 'project_id', 'id'); | ||
| 56 | + } | ||
| 57 | +} |
app/Models/WorkOrder/WorkOrderLog.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Models\WorkOrder; | ||
| 4 | + | ||
| 5 | +use App\Models\Base; | ||
| 6 | +use App\Models\Manage\Manage; | ||
| 7 | + | ||
| 8 | +class WorkOrderLog extends Base | ||
| 9 | +{ | ||
| 10 | + protected $table = 'gl_work_order_logs'; | ||
| 11 | + | ||
| 12 | + const STATUS_PEDDING = 0; // 待处理 | ||
| 13 | + const STATUS_PROCESSING = 1; // 处理中 | ||
| 14 | + const STATUS_COMPLETED = 2; // 已完成 | ||
| 15 | + const STATUS_CLOSED = 3; // 已关闭 | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * 所属工单 | ||
| 19 | + */ | ||
| 20 | + public function workOrder() | ||
| 21 | + { | ||
| 22 | + return $this->belongsTo(WorkOrder::class, 'work_order_id'); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * 分配的工单负责人,工程师等 | ||
| 27 | + */ | ||
| 28 | + public function manager() | ||
| 29 | + { | ||
| 30 | + return $this->belongsTo(Manage::class, 'manage_id', 'id'); | ||
| 31 | + } | ||
| 32 | +} |
| @@ -12,6 +12,7 @@ | @@ -12,6 +12,7 @@ | ||
| 12 | "beyondcode/laravel-websockets": "^1.14", | 12 | "beyondcode/laravel-websockets": "^1.14", |
| 13 | "doctrine/dbal": "^3.6", | 13 | "doctrine/dbal": "^3.6", |
| 14 | "fruitcake/laravel-cors": "^2.0", | 14 | "fruitcake/laravel-cors": "^2.0", |
| 15 | + "g4t/swagger": "^4.0", | ||
| 15 | "guzzlehttp/guzzle": "^7.0.1", | 16 | "guzzlehttp/guzzle": "^7.0.1", |
| 16 | "hashids/hashids": "^4.1", | 17 | "hashids/hashids": "^4.1", |
| 17 | "intervention/image": "^2.7", | 18 | "intervention/image": "^2.7", |
config/swagger.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +return [ | ||
| 4 | + /* | ||
| 5 | + |-------------------------------------------------------------------------- | ||
| 6 | + | API Title | ||
| 7 | + |-------------------------------------------------------------------------- | ||
| 8 | + | | ||
| 9 | + | The title of your API documentation. | ||
| 10 | + | | ||
| 11 | + */ | ||
| 12 | + "title" => env("SWAGGER_TITLE", "Globalso V6 Api Documentation"), | ||
| 13 | + | ||
| 14 | + /* | ||
| 15 | + |-------------------------------------------------------------------------- | ||
| 16 | + | API Description | ||
| 17 | + |-------------------------------------------------------------------------- | ||
| 18 | + | | ||
| 19 | + | The description of your API. | ||
| 20 | + | | ||
| 21 | + */ | ||
| 22 | + "description" => env("SWAGGER_DESCRIPTION", "Laravel autogenerate swagger"), | ||
| 23 | + | ||
| 24 | + /* | ||
| 25 | + |-------------------------------------------------------------------------- | ||
| 26 | + | API Email | ||
| 27 | + |-------------------------------------------------------------------------- | ||
| 28 | + | | ||
| 29 | + | The email associated with your API documentation. | ||
| 30 | + | | ||
| 31 | + */ | ||
| 32 | + "email" => env("SWAGGER_EMAIL", "bill@ai.cc"), | ||
| 33 | + | ||
| 34 | + /* | ||
| 35 | + |-------------------------------------------------------------------------- | ||
| 36 | + | API Version | ||
| 37 | + |-------------------------------------------------------------------------- | ||
| 38 | + | | ||
| 39 | + | The version of your API. | ||
| 40 | + | | ||
| 41 | + */ | ||
| 42 | + "version" => env("SWAGGER_VERSION", "3.0.7"), | ||
| 43 | + | ||
| 44 | + /* | ||
| 45 | + |-------------------------------------------------------------------------- | ||
| 46 | + | Documentation Auth | ||
| 47 | + |-------------------------------------------------------------------------- | ||
| 48 | + | | ||
| 49 | + | This options to enable documentation auth | ||
| 50 | + | | ||
| 51 | + */ | ||
| 52 | + "enable_auth" => false, | ||
| 53 | + "username" => "admin", | ||
| 54 | + "password" => "pass", | ||
| 55 | + "sesson_ttl" => 100000, | ||
| 56 | + | ||
| 57 | + /* | ||
| 58 | + |-------------------------------------------------------------------------- | ||
| 59 | + | Enable Response Schema | ||
| 60 | + |-------------------------------------------------------------------------- | ||
| 61 | + | | ||
| 62 | + | Whether to enable response schema or not. | ||
| 63 | + | | ||
| 64 | + */ | ||
| 65 | + "enable_response_schema" => true, | ||
| 66 | + | ||
| 67 | + "suggestions_select_input" => false, | ||
| 68 | + | ||
| 69 | + "load_from_json" => false, | ||
| 70 | + | ||
| 71 | + /* | ||
| 72 | + |-------------------------------------------------------------------------- | ||
| 73 | + | Authentication Middlewares | ||
| 74 | + |-------------------------------------------------------------------------- | ||
| 75 | + | | ||
| 76 | + | List of middleware names used for authentication. | ||
| 77 | + | | ||
| 78 | + */ | ||
| 79 | + "auth_middlewares" => [ | ||
| 80 | + "auth", | ||
| 81 | + "auth:api", | ||
| 82 | + "aloginauth", | ||
| 83 | + "bloginauth", | ||
| 84 | + ], | ||
| 85 | + | ||
| 86 | + /* | ||
| 87 | + |-------------------------------------------------------------------------- | ||
| 88 | + | API URL | ||
| 89 | + |-------------------------------------------------------------------------- | ||
| 90 | + | | ||
| 91 | + | The URL path for accessing your API documentation. | ||
| 92 | + | | ||
| 93 | + */ | ||
| 94 | + "url" => env("SWAGGER_URL", "swagger/documentation"), | ||
| 95 | + | ||
| 96 | + /* | ||
| 97 | + |-------------------------------------------------------------------------- | ||
| 98 | + | Issues URL | ||
| 99 | + |-------------------------------------------------------------------------- | ||
| 100 | + | | ||
| 101 | + | The URL path for accessing issues related to your API documentation. | ||
| 102 | + | | ||
| 103 | + */ | ||
| 104 | + "issues_url" => env("SWAGGER_ISSUE_URL", "swagger/issues"), | ||
| 105 | + | ||
| 106 | + /* | ||
| 107 | + |-------------------------------------------------------------------------- | ||
| 108 | + | Enable Swagger | ||
| 109 | + |-------------------------------------------------------------------------- | ||
| 110 | + | | ||
| 111 | + | Whether Swagger is enabled or not. | ||
| 112 | + | | ||
| 113 | + */ | ||
| 114 | + "enable" => env('SWAGGER_ENABLED', true), | ||
| 115 | + | ||
| 116 | + /* | ||
| 117 | + |-------------------------------------------------------------------------- | ||
| 118 | + | Show Prefix | ||
| 119 | + |-------------------------------------------------------------------------- | ||
| 120 | + | | ||
| 121 | + | List of prefixes to show in Swagger. | ||
| 122 | + | | ||
| 123 | + */ | ||
| 124 | + "show_prefix" => [], | ||
| 125 | + | ||
| 126 | + /* | ||
| 127 | + |-------------------------------------------------------------------------- | ||
| 128 | + | Include Web Routes | ||
| 129 | + |-------------------------------------------------------------------------- | ||
| 130 | + | | ||
| 131 | + | If you want to includes web.php routes, then enable this | ||
| 132 | + | | ||
| 133 | + */ | ||
| 134 | + "include_web_routes" => env('SWAGGER_INCLUDE_WEB_ROUTES', true), | ||
| 135 | + | ||
| 136 | + | ||
| 137 | + /* | ||
| 138 | + |-------------------------------------------------------------------------- | ||
| 139 | + | API Versions | ||
| 140 | + |-------------------------------------------------------------------------- | ||
| 141 | + | | ||
| 142 | + | List of versions to show in Swagger. | ||
| 143 | + | | ||
| 144 | + */ | ||
| 145 | + "versions" => [ | ||
| 146 | + "all", | ||
| 147 | + // "v1" | ||
| 148 | + ], | ||
| 149 | + | ||
| 150 | + "default" => "all", | ||
| 151 | + | ||
| 152 | + | ||
| 153 | + /* | ||
| 154 | + |-------------------------------------------------------------------------- | ||
| 155 | + | Servers | ||
| 156 | + |-------------------------------------------------------------------------- | ||
| 157 | + | | ||
| 158 | + | List of servers associated with your API. | ||
| 159 | + | | ||
| 160 | + */ | ||
| 161 | + "servers" => [ | ||
| 162 | + [ | ||
| 163 | + "url" => env("APP_URL"), | ||
| 164 | + "description" => "localhost" | ||
| 165 | + ] | ||
| 166 | + ], | ||
| 167 | + | ||
| 168 | + | ||
| 169 | + /* | ||
| 170 | + |-------------------------------------------------------------------------- | ||
| 171 | + | Security Schemes | ||
| 172 | + |-------------------------------------------------------------------------- | ||
| 173 | + | | ||
| 174 | + | Security schemes used in your API. | ||
| 175 | + | | ||
| 176 | + */ | ||
| 177 | + "security_schemes" => [ | ||
| 178 | + "APIKeyHeader" => [ | ||
| 179 | + "type" => "apiKey", | ||
| 180 | + "name" => "token", | ||
| 181 | + "in" => "header" | ||
| 182 | + ], | ||
| 183 | + ], | ||
| 184 | + | ||
| 185 | + /* | ||
| 186 | + |-------------------------------------------------------------------------- | ||
| 187 | + | Spatie Query Builder | ||
| 188 | + |-------------------------------------------------------------------------- | ||
| 189 | + | | ||
| 190 | + | Enable it if you using Spatie query builder package to add spatie filters in all GET routes. | ||
| 191 | + | | ||
| 192 | + */ | ||
| 193 | + "spatie_query_builder" => false, | ||
| 194 | + | ||
| 195 | + | ||
| 196 | + /* | ||
| 197 | + |-------------------------------------------------------------------------- | ||
| 198 | + | Status | ||
| 199 | + |-------------------------------------------------------------------------- | ||
| 200 | + | | ||
| 201 | + | HTTP response statuses for various methods. | ||
| 202 | + | | ||
| 203 | + */ | ||
| 204 | + "status" => [ | ||
| 205 | + "GET" => [ | ||
| 206 | + "200" => [ | ||
| 207 | + "description" => "Successful Operation", | ||
| 208 | + ], | ||
| 209 | + "404" => [ | ||
| 210 | + "description" => "Not Found" | ||
| 211 | + ] | ||
| 212 | + ], | ||
| 213 | + "POST" => [ | ||
| 214 | + "200" => [ | ||
| 215 | + "description" => "Successful Operation", | ||
| 216 | + ], | ||
| 217 | + "422" => [ | ||
| 218 | + "description" => "Validation Issues" | ||
| 219 | + ] | ||
| 220 | + ], | ||
| 221 | + "PUT" => [ | ||
| 222 | + "200" => [ | ||
| 223 | + "description" => "Successful Operation", | ||
| 224 | + ], | ||
| 225 | + "404" => [ | ||
| 226 | + "description" => "Not Found" | ||
| 227 | + ], | ||
| 228 | + "405" => [ | ||
| 229 | + "description" => "Validation exception" | ||
| 230 | + ] | ||
| 231 | + ], | ||
| 232 | + "PATCH" => [ | ||
| 233 | + "200" => [ | ||
| 234 | + "description" => "Successful Operation", | ||
| 235 | + ], | ||
| 236 | + "404" => [ | ||
| 237 | + "description" => "Not Found" | ||
| 238 | + ], | ||
| 239 | + "405" => [ | ||
| 240 | + "description" => "Validation exception" | ||
| 241 | + ] | ||
| 242 | + ], | ||
| 243 | + "DELETE" => [ | ||
| 244 | + "200" => [ | ||
| 245 | + "description" => "successful Operation", | ||
| 246 | + ], | ||
| 247 | + "404" => [ | ||
| 248 | + "description" => "page Not Found" | ||
| 249 | + ] | ||
| 250 | + ], | ||
| 251 | + ], | ||
| 252 | + | ||
| 253 | +]; |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -use Illuminate\Database\Migrations\Migration; | ||
| 4 | -use Illuminate\Database\Schema\Blueprint; | ||
| 5 | -use Illuminate\Support\Facades\Schema; | ||
| 6 | - | ||
| 7 | -class CreatePasswordResetsTable extends Migration | ||
| 8 | -{ | ||
| 9 | - /** | ||
| 10 | - * Run the migrations. | ||
| 11 | - * | ||
| 12 | - * @return void | ||
| 13 | - */ | ||
| 14 | - public function up() | ||
| 15 | - { | ||
| 16 | - Schema::create('password_resets', function (Blueprint $table) { | ||
| 17 | - $table->string('email')->index(); | ||
| 18 | - $table->string('token'); | ||
| 19 | - $table->timestamp('created_at')->nullable(); | ||
| 20 | - }); | ||
| 21 | - } | ||
| 22 | - | ||
| 23 | - /** | ||
| 24 | - * Reverse the migrations. | ||
| 25 | - * | ||
| 26 | - * @return void | ||
| 27 | - */ | ||
| 28 | - public function down() | ||
| 29 | - { | ||
| 30 | - Schema::dropIfExists('password_resets'); | ||
| 31 | - } | ||
| 32 | -} |
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -use Illuminate\Database\Migrations\Migration; | ||
| 4 | -use Illuminate\Database\Schema\Blueprint; | ||
| 5 | -use Illuminate\Support\Facades\Schema; | ||
| 6 | - | ||
| 7 | -class CreateFailedJobsTable extends Migration | ||
| 8 | -{ | ||
| 9 | - /** | ||
| 10 | - * Run the migrations. | ||
| 11 | - * | ||
| 12 | - * @return void | ||
| 13 | - */ | ||
| 14 | - public function up() | ||
| 15 | - { | ||
| 16 | - Schema::create('failed_jobs', function (Blueprint $table) { | ||
| 17 | - $table->id(); | ||
| 18 | - $table->string('uuid')->unique(); | ||
| 19 | - $table->text('connection'); | ||
| 20 | - $table->text('queue'); | ||
| 21 | - $table->longText('payload'); | ||
| 22 | - $table->longText('exception'); | ||
| 23 | - $table->timestamp('failed_at')->useCurrent(); | ||
| 24 | - }); | ||
| 25 | - } | ||
| 26 | - | ||
| 27 | - /** | ||
| 28 | - * Reverse the migrations. | ||
| 29 | - * | ||
| 30 | - * @return void | ||
| 31 | - */ | ||
| 32 | - public function down() | ||
| 33 | - { | ||
| 34 | - Schema::dropIfExists('failed_jobs'); | ||
| 35 | - } | ||
| 36 | -} |
| @@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration; | @@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration; | ||
| 4 | use Illuminate\Database\Schema\Blueprint; | 4 | use Illuminate\Database\Schema\Blueprint; |
| 5 | use Illuminate\Support\Facades\Schema; | 5 | use Illuminate\Support\Facades\Schema; |
| 6 | 6 | ||
| 7 | -class CreatePersonalAccessTokensTable extends Migration | 7 | +class CreateWorkOrdersTable extends Migration |
| 8 | { | 8 | { |
| 9 | /** | 9 | /** |
| 10 | * Run the migrations. | 10 | * Run the migrations. |
| @@ -13,15 +13,21 @@ class CreatePersonalAccessTokensTable extends Migration | @@ -13,15 +13,21 @@ class CreatePersonalAccessTokensTable extends Migration | ||
| 13 | */ | 13 | */ |
| 14 | public function up() | 14 | public function up() |
| 15 | { | 15 | { |
| 16 | - Schema::create('personal_access_tokens', function (Blueprint $table) { | 16 | + Schema::create('gl_work_orders', function (Blueprint $table) { |
| 17 | $table->id(); | 17 | $table->id(); |
| 18 | - $table->morphs('tokenable'); | ||
| 19 | - $table->string('name'); | ||
| 20 | - $table->string('token', 64)->unique(); | ||
| 21 | - $table->text('abilities')->nullable(); | ||
| 22 | - $table->timestamp('last_used_at')->nullable(); | ||
| 23 | $table->timestamps(); | 18 | $table->timestamps(); |
| 19 | + $table->string('product')->nullable()->comment('相关产品,工单类型'); | ||
| 20 | + $table->longText('content')->comment('工单图文描述'); | ||
| 21 | + $table->json('files')->nullable()->comment('附件'); | ||
| 22 | + $table->integer('status')->index()->default(0)->comment('工单状态,0:待处理, 1:处理中,2:已完成, 3:已关闭'); | ||
| 23 | + $table->integer('project_user_id')->index()->comment('客户ID'); | ||
| 24 | + $table->integer('project_id')->index()->comment('项目ID'); | ||
| 25 | + $table->integer('manage_id')->index()->comment('A端项目负责人ID, gl_manage 表ID'); | ||
| 26 | + $table->integer('engineer_id')->index()->comment('处理技术,工程师id, gl_manage 表ID'); | ||
| 27 | + $table->timestamp('end_at')->nullable()->comment('完成时间'); | ||
| 24 | }); | 28 | }); |
| 29 | + # 添加表注释 | ||
| 30 | + \Illuminate\Support\Facades\DB::statement("ALTER TABLE gl_work_orders comment '工单表'"); | ||
| 25 | } | 31 | } |
| 26 | 32 | ||
| 27 | /** | 33 | /** |
| @@ -31,6 +37,6 @@ class CreatePersonalAccessTokensTable extends Migration | @@ -31,6 +37,6 @@ class CreatePersonalAccessTokensTable extends Migration | ||
| 31 | */ | 37 | */ |
| 32 | public function down() | 38 | public function down() |
| 33 | { | 39 | { |
| 34 | - Schema::dropIfExists('personal_access_tokens'); | 40 | + Schema::dropIfExists('gl_work_orders'); |
| 35 | } | 41 | } |
| 36 | } | 42 | } |
| @@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration; | @@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration; | ||
| 4 | use Illuminate\Database\Schema\Blueprint; | 4 | use Illuminate\Database\Schema\Blueprint; |
| 5 | use Illuminate\Support\Facades\Schema; | 5 | use Illuminate\Support\Facades\Schema; |
| 6 | 6 | ||
| 7 | -class CreateUsersTable extends Migration | 7 | +class CreateWorkOrderLogsTable extends Migration |
| 8 | { | 8 | { |
| 9 | /** | 9 | /** |
| 10 | * Run the migrations. | 10 | * Run the migrations. |
| @@ -13,15 +13,19 @@ class CreateUsersTable extends Migration | @@ -13,15 +13,19 @@ class CreateUsersTable extends Migration | ||
| 13 | */ | 13 | */ |
| 14 | public function up() | 14 | public function up() |
| 15 | { | 15 | { |
| 16 | - Schema::create('users', function (Blueprint $table) { | 16 | + Schema::create('gl_work_order_logs', function (Blueprint $table) { |
| 17 | $table->id(); | 17 | $table->id(); |
| 18 | - $table->string('name'); | ||
| 19 | - $table->string('email')->unique(); | ||
| 20 | - $table->timestamp('email_verified_at')->nullable(); | ||
| 21 | - $table->string('password'); | ||
| 22 | - $table->rememberToken(); | ||
| 23 | $table->timestamps(); | 18 | $table->timestamps(); |
| 19 | + $table->integer('work_order_id')->index(); | ||
| 20 | + $table->integer('manage_id')->comment('gl_manage 表ID,操作人ID'); | ||
| 21 | + $table->boolean('ding')->default(false)->comment('是否钉钉通知'); | ||
| 22 | + $table->longText('content')->nullable()->comment('处理结果,图文描述'); | ||
| 23 | + $table->json('files')->nullable()->comment('附件'); | ||
| 24 | + $table->integer('status')->index()->default(0)->comment('工单状态,0:待处理, 1:处理中, 2:已完成'); | ||
| 25 | + $table->timestamp('end_at')->nullable()->comment('完成时间'); | ||
| 26 | + $table->unique(['work_order_id', 'manage_id'], 'work_order_manage_unique'); # 唯一索引,防止同一工单被同一人多次操作,同一工单,可以多人协作 | ||
| 24 | }); | 27 | }); |
| 28 | + \Illuminate\Support\Facades\DB::statement('ALTER TABLE gl_work_order_logs comment "工单操作日志表,分配工程师时创建,工程师完成时修改状态"'); | ||
| 25 | } | 29 | } |
| 26 | 30 | ||
| 27 | /** | 31 | /** |
| @@ -31,6 +35,6 @@ class CreateUsersTable extends Migration | @@ -31,6 +35,6 @@ class CreateUsersTable extends Migration | ||
| 31 | */ | 35 | */ |
| 32 | public function down() | 36 | public function down() |
| 33 | { | 37 | { |
| 34 | - Schema::dropIfExists('users'); | 38 | + Schema::dropIfExists('gl_work_order_logs'); |
| 35 | } | 39 | } |
| 36 | } | 40 | } |
docs/售后工单设计图.drawio.pdf
0 → 100644
不能预览此文件类型
| @@ -245,6 +245,13 @@ Route::middleware(['aloginauth'])->group(function () { | @@ -245,6 +245,13 @@ Route::middleware(['aloginauth'])->group(function () { | ||
| 245 | Route::post('/save_follow', [Aside\Task\TaskController::class, 'save_follow'])->name('admin.task_save_follow'); | 245 | Route::post('/save_follow', [Aside\Task\TaskController::class, 'save_follow'])->name('admin.task_save_follow'); |
| 246 | Route::any('/getUserTaskList', [Aside\Task\TaskController::class, 'getUserTaskList'])->name('admin.task_getUserTaskList'); | 246 | Route::any('/getUserTaskList', [Aside\Task\TaskController::class, 'getUserTaskList'])->name('admin.task_getUserTaskList'); |
| 247 | }); | 247 | }); |
| 248 | + // 售后工单 | ||
| 249 | + Route::prefix('workorder')->group(function () { | ||
| 250 | + Route::get('/', [Aside\WorkOrder\WorkOrderController::class, 'index'])->name('admin.workorder.index')->summary('A端工程师的工单列表'); | ||
| 251 | + Route::get('/manager', [Aside\WorkOrder\WorkOrderController::class, 'manager'])->name('admin.workorder.manager')->summary('A端管理员的工单列表'); | ||
| 252 | + Route::get('/{id}', [Aside\WorkOrder\WorkOrderController::class, 'show'])->name('admin.workorder.show')->summary('A端工单详情'); | ||
| 253 | + Route::put('/{id}', [Aside\WorkOrder\WorkOrderController::class, 'update'])->name('admin.workorder.update')->summary('A端更新工单'); | ||
| 254 | + }); | ||
| 248 | //服务器配置 | 255 | //服务器配置 |
| 249 | Route::prefix('devops')->group(function () { | 256 | Route::prefix('devops')->group(function () { |
| 250 | Route::any('/', [Aside\Devops\ServerConfigController::class, 'lists'])->name('admin.devops.lists'); | 257 | Route::any('/', [Aside\Devops\ServerConfigController::class, 'lists'])->name('admin.devops.lists'); |
| @@ -353,11 +360,6 @@ Route::middleware(['aloginauth'])->group(function () { | @@ -353,11 +360,6 @@ Route::middleware(['aloginauth'])->group(function () { | ||
| 353 | Route::any('/save', [Aside\Optimize\ProjectGscController::class, 'save'])->name('admin.gsc_save'); | 360 | Route::any('/save', [Aside\Optimize\ProjectGscController::class, 'save'])->name('admin.gsc_save'); |
| 354 | Route::any('/del', [Aside\Optimize\ProjectGscController::class, 'del'])->name('admin.gsc_del'); | 361 | Route::any('/del', [Aside\Optimize\ProjectGscController::class, 'del'])->name('admin.gsc_del'); |
| 355 | }); | 362 | }); |
| 356 | - //上线审核 | ||
| 357 | - Route::prefix('process')->group(function () { | ||
| 358 | - Route::any('/', [Aside\Optimize\ProcessController::class, 'lists'])->name('admin.process_lists'); | ||
| 359 | - Route::any('/save', [Aside\Optimize\ProcessController::class, 'save'])->name('admin.process_save'); | ||
| 360 | - }); | ||
| 361 | 363 | ||
| 362 | //询盘 | 364 | //询盘 |
| 363 | Route::prefix('inquiry')->group(function () { | 365 | Route::prefix('inquiry')->group(function () { |
| @@ -261,6 +261,15 @@ Route::middleware(['bloginauth'])->group(function () { | @@ -261,6 +261,15 @@ Route::middleware(['bloginauth'])->group(function () { | ||
| 261 | Route::any('/save',[\App\Http\Controllers\Bside\Setting\WebSettingAmpController::class, 'save'])->name('amp_save'); | 261 | Route::any('/save',[\App\Http\Controllers\Bside\Setting\WebSettingAmpController::class, 'save'])->name('amp_save'); |
| 262 | }); | 262 | }); |
| 263 | }); | 263 | }); |
| 264 | + | ||
| 265 | + // 售后工单 | ||
| 266 | + Route::prefix('workorder')->group(function () { | ||
| 267 | + Route::get('/', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'index'])->name('workorder.index')->summary('B端售后工单列表'); | ||
| 268 | + Route::post('/', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'store'])->name('workorder.store')->summary('B端创建工单'); | ||
| 269 | + Route::get('/{id}', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'show'])->name('workorder.show')->summary('B端查看工单'); | ||
| 270 | + Route::put('/{id}', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'update'])->name('workorder.update')->summary('B端完结工单'); | ||
| 271 | + }); | ||
| 272 | + | ||
| 264 | //产品 | 273 | //产品 |
| 265 | Route::prefix('product')->group(function () { | 274 | Route::prefix('product')->group(function () { |
| 266 | //产品 | 275 | //产品 |
| @@ -516,11 +525,6 @@ Route::middleware(['bloginauth'])->group(function () { | @@ -516,11 +525,6 @@ Route::middleware(['bloginauth'])->group(function () { | ||
| 516 | Route::any('/getKeyword', [\App\Http\Controllers\Bside\HomeCount\MonthCountController::class, 'getKeyword'])->name('month_getKeyword'); | 525 | Route::any('/getKeyword', [\App\Http\Controllers\Bside\HomeCount\MonthCountController::class, 'getKeyword'])->name('month_getKeyword'); |
| 517 | }); | 526 | }); |
| 518 | 527 | ||
| 519 | - //更新tdk | ||
| 520 | - Route::prefix('tdk')->group(function () { | ||
| 521 | - Route::any('/', [\App\Http\Controllers\Bside\BCom\UpdateController::class, 'updateSeoTdk'])->name('tdk_updateSeoTdk'); | ||
| 522 | - }); | ||
| 523 | - | ||
| 524 | //导入任务 | 528 | //导入任务 |
| 525 | Route::prefix('import')->group(function () { | 529 | Route::prefix('import')->group(function () { |
| 526 | Route::any('/add_task', [\App\Http\Controllers\Bside\Import\ImportController::class, 'save'])->name('import_add_task'); | 530 | Route::any('/add_task', [\App\Http\Controllers\Bside\Import\ImportController::class, 'save'])->name('import_add_task'); |
-
请 注册 或 登录 后发表评论