改进 工单系统

This commit is contained in:
iVampireSP.com 2022-08-15 22:29:57 +08:00
parent 90b357591e
commit 17c816ac50
No known key found for this signature in database
GPG Key ID: 2F7B001CA27A8132
16 changed files with 351 additions and 51 deletions

View File

@ -1,6 +1,6 @@
<?php
namespace App\Http\Controllers\Remote\User;
namespace App\Http\Controllers\Remote\Host;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
@ -16,10 +16,10 @@ public function __construct(Request $request)
{
$request->validate([
'host_id' => 'sometimes|integer|exists:hosts,id',
'user_id' => 'integer|exists:users,id',
// 'user_id' => 'integer|exists:users,id',
]);
$this->user_id = $request->user_id;
// $this->user_id = $request->user_id;
$this->host_id = $request->host_id;
}
@ -100,7 +100,7 @@ public function pushTask($task, $id = null)
{
$cache_key = 'user_tasks_' . $this->user_id;
$data = [
'user_id' => $this->user_id,
// 'user_id' => $this->user_id,
'done_at' => null,
'host_id' => $this->host_id
];

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Remote\WorkOrder;
use Illuminate\Http\Request;
use App\Models\WorkOrder\Reply;
use App\Http\Controllers\Controller;
class ReplyController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
//
$replies = Reply::workOrderId($request->route('work_order'))->simplePaginate(10);
return $this->success($replies);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
$request->validate([
'content' => 'string|required|min:1|max:1000',
]);
$reply = Reply::create([
'content' => $request->content,
'work_order_id' => $request->route('work_order'),
]);
return $this->success($reply);
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\Remote\WorkOrder;
use Illuminate\Http\Request;
use App\Models\WorkOrder\WorkOrder;
use App\Http\Controllers\Controller;
use App\Http\Requests\Remote\WorkOrderRequest;
class WorkOrderController extends Controller
{
//
public function index(Request $request, WorkOrder $workOrder) {
// $work_orders = new WorkOrder();
// // if route has user
// if ($request->route('user')) {
// $work_orders = $work_orders->where('user_id', $request->route('user'));
// }
// $work_orders = $work_orders->simplePaginate(10);
$workOrder = $workOrder->thisModule()->simplePaginate(10);
return $this->success($workOrder);
}
// public function store(Request $request) {
// }
public function show(WorkOrderRequest $request, WorkOrder $workOrder) {
return $this->success($workOrder);
}
public function update(WorkOrderRequest $request, WorkOrder $workOrder)
{
$request->validate([
'status' => 'nullable|sometimes|string|in:open,closed,on_hold,in_progress',
]);
$workOrder->update($request->only('status'));
return $this->success($workOrder);
}
// public function destroy() {}
}

View File

@ -1,11 +0,0 @@
<?php
namespace App\Http\Controllers\Remote;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class WorkOrderController extends Controller
{
//
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\User\WorkOrder;
use App\Http\Controllers\Controller;
use App\Http\Requests\User\WorkOrder\WorkOrderRequest;
use App\Models\WorkOrder\Reply;
use Illuminate\Http\Request;
class ReplyController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(WorkOrderRequest $request)
{
//
$replies = Reply::workOrderId($request->route('work_order'))->simplePaginate(10);
return $this->success($replies);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(WorkOrderRequest $request)
{
// add reply
$request->validate([
'content' => 'string|required|min:1|max:1000',
]);
$reply = Reply::create([
'content' => $request->content,
'work_order_id' => $request->route('work_order'),
]);
return $this->success($reply);
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace App\Http\Controllers\User\WorkOrder;
use Illuminate\Http\Request;
use App\Models\WorkOrder\WorkOrder;
use App\Http\Controllers\Controller;
use App\Http\Requests\User\WorkOrder\WorkOrderRequest;
class WorkOrderController extends Controller
{
//
public function index(Request $request, WorkOrder $workOrder) {
$workOrder = $workOrder->user()->simplePaginate(10);
return $this->success($workOrder);
}
public function store(Request $request) {
$request->validate([
'title' => 'required|max:255',
'content' => 'required',
'module_id' => 'nullable|sometimes|string|exists:modules,id',
'host_id' => 'nullable|sometimes|string|exists:hosts,id',
]);
// module_id 和 host_id 必须有个要填写
if (!$request->module_id && !$request->host_id) {
return $this->error('module_id 和 host_id 至少要填写一个');
}
$workOrder = WorkOrder::create([
'title' => $request->title,
'content' => $request->content,
'module_id' => $request->module_id,
'host_id' => $request->host_id,
'status' => 'pending',
]);
return $this->success($workOrder);
}
public function show(WorkOrderRequest $request, WorkOrder $workOrder) {
return $this->success($workOrder);
}
public function update(WorkOrderRequest $request, WorkOrder $workOrder) {
$request->validate([
'status' => 'nullable|sometimes|string|in:closed',
]);
$workOrder->update($request->only('status'));
return $this->success($workOrder);
}
}

View File

@ -1,11 +0,0 @@
<?php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class WorkOrderController extends Controller
{
//
}

View File

@ -2,6 +2,7 @@
namespace App\Http\Requests\Remote;
use App\Models\WorkOrder\WorkOrder;
use Illuminate\Foundation\Http\FormRequest;
class WorkOrderRequest extends FormRequest
@ -13,7 +14,7 @@ class WorkOrderRequest extends FormRequest
*/
public function authorize()
{
return false;
return WorkOrder::where('id', $this->route('work_order')->id)->where('module_id', auth('remote')->id())->exists();
}
/**

View File

@ -1,7 +1,8 @@
<?php
namespace App\Http\Requests\User;
namespace App\Http\Requests\User\WorkOrder;
use App\Models\WorkOrder\WorkOrder;
use Illuminate\Foundation\Http\FormRequest;
class WorkOrderRequest extends FormRequest
@ -13,6 +14,19 @@ class WorkOrderRequest extends FormRequest
*/
public function authorize()
{
$work_order = $this->route('work_order');
// if work_order is model
if ($work_order instanceof WorkOrder) {
$work_order_id = $work_order->id;
} else {
$work_order_id = $work_order;
}
return WorkOrder::where('user_id', auth('sanctum')->id())->where('id', $work_order_id)->exists();
return false;
}

View File

@ -9,13 +9,49 @@ class Reply extends Model
{
use HasFactory;
protected $table = 'workorder_replies';
protected $table = 'work_order_replies';
protected $fillable = [
'content',
'work_order_id',
'user_id',
// 'user_id',
'is_pending',
];
public function workOrder()
{
return $this->belongsTo(WorkOrder::class);
}
public function scopeWorkOrderId($query, $work_order_id)
{
return $query->where('work_order_id', $work_order_id);
}
// before create
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
// load work order
$model->load(['workOrder']);
// change work order status
if (auth('sanctum')->check()) {
$model->user_id = auth()->id();
$model->workOrder->status = 'user_replied';
}
if (auth('remote')->check()) {
$model->user_id = null;
$model->workOrder->status = 'replied';
}
$model->workOrder->save();
});
}
}

View File

@ -3,23 +3,24 @@
namespace App\Models\WorkOrder;
use App\Models\User\Host;
use Illuminate\Support\Arr;
use App\Models\Module\Module;
use App\Exceptions\CommonException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Arr;
class WorkOrder extends Model
{
use HasFactory;
protected $table = 'workorders';
protected $table = 'work_orders';
protected $fillable = [
'title',
'content',
'host_id',
'user_id',
'provider_module_id',
'module_id',
'status',
];
@ -30,12 +31,28 @@ public function replies()
return $this->hasMany(Reply::class);
}
// provider module
// host
public function host()
{
return $this->belongsTo(Host::class);
}
public function module()
{
return $this->belongsTo(Module::class);
}
// scope
public function scopeThisModule($query)
{
return $query->where('module_id', auth('remote')->id());
}
public function scopeUser($query)
{
return $query->where('user_id', auth()->id());
}
// on create
protected static function boot()
@ -43,22 +60,37 @@ protected static function boot()
parent::boot();
static::creating(function ($model) {
$model->load('host');
if ($model->host_id) {
$model->load(['host']);
$model->module_id = $model->host->module_id;
}
// if logged
if (auth('sanctum')->check()) {
$model->user_id = auth('sanctum')->id();
if ($model->host_id) {
if (!$model->user_id === $model->host->user_id) {
throw new CommonException('user_id not match host user_id');
}
$model->host->load('provider_module');
$provider_module = $model->host->provider_module;
}
} else {
throw new CommonException('user_id is required');
}
if ($provider_module === null) {
if ($model->host_id) {
$model->host->load('module');
$module = $model->host->module;
if ($module === null) {
$model->status = 'open';
} else {
$model->status = 'pending';
}
}
});
// 更新时获取差异部分

View File

@ -17,7 +17,7 @@
*/
public function up()
{
Schema::create('workorders', function (Blueprint $table) {
Schema::create('work_orders', function (Blueprint $table) {
$table->id();
// title
@ -30,8 +30,12 @@ public function up()
$table->unsignedBigInteger('user_id')->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
// module id
$table->string('module_id')->index();
$table->foreign('module_id')->references('id')->on('modules')->onDelete('cascade');
// host id
$table->unsignedBigInteger('host_id')->index();
$table->unsignedBigInteger('host_id')->index()->nullable();
$table->foreign('host_id')->references('id')->on('hosts')->onDelete('cascade');
// status

View File

@ -15,15 +15,15 @@
*/
public function up()
{
Schema::create('workorder_replies', function (Blueprint $table) {
Schema::create('work_order_replies', function (Blueprint $table) {
$table->id();
// content
$table->text('content');
// workorder id (on delete cascade)
$table->unsignedBigInteger('workorder_id')->index();
$table->foreign('workorder_id')->references('id')->on('workorders')->onDelete('cascade');
$table->unsignedBigInteger('work_order_id')->index();
$table->foreign('work_order_id')->references('id')->on('work_orders')->onDelete('cascade');
// user id
$table->unsignedBigInteger('user_id')->index();

View File

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

View File

@ -2,12 +2,15 @@
use App\Http\Controllers;
use App\Http\Controllers\Admin\User\DropController;
use App\Models\Admin\Admin;
use App\Http\Controllers\User;
use Illuminate\Support\Facades\Route;
Route::name('client.')->middleware(['api'])->group(function () {
Route::name('client.')->middleware(['api', 'auth:sanctum'])->group(function () {
// Route::apiResource('users', Controllers\User\UserController::class);
Route::apiResource('drops', DropController::class);
Route::apiResource('work-orders', User\WorkOrder\WorkOrderController::class);
Route::apiResource('work-orders.replies', User\WorkOrder\ReplyController::class);
});

View File

@ -7,6 +7,10 @@
Route::apiResource('modules', Remote\ModuleController::class)->only(['index']);
Route::apiResource('servers', Remote\ServerController::class);
Route::patch('hosts/{host}/drops', [Remote\Host\DropController::class, 'update']);
Route::apiResource('users.tasks', Remote\User\TaskController::class);
Route::apiResource('hosts.tasks', Remote\Host\TaskController::class);
Route::apiResource('work-orders', Remote\WorkOrder\WorkOrderController::class);
Route::apiResource('work-orders.replies', Remote\WorkOrder\ReplyController::class);
// Route::apiResource('users', Controllers\User\UserController::class);
});