api 报销审核

main
panliang 2024-04-15 09:59:11 +08:00
parent 6dec9bba36
commit 075e95c764
8 changed files with 80 additions and 71 deletions

View File

@ -28,6 +28,7 @@ class WorkFlowService extends BaseService
*
* @param WorkflowCheck $check 待审核记录
* @param Employee $user 申请人
*
* @return bool true: 成功, false: 失败, $this->getError(): 错误消息
*/
public function apply(WorkflowCheck $check, Employee $user)

View File

@ -4,6 +4,8 @@ namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
use Illuminate\Http\{Request};
use Illuminate\Validation\ValidationException;
class Handler extends ExceptionHandler
{
@ -18,13 +20,26 @@ class Handler extends ExceptionHandler
'password_confirmation',
];
protected $dontReport = [
RuntimeException::class,
];
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
$this->reportable(function (Throwable $e) {
//
$this->renderable(function (RuntimeException $e, Request $request) {
return response(['code' => $e->getCode(), 'message' => $e->getMessage()], $e->getHttpStatusCode());
});
}
protected function invalidJson($request, ValidationException $exception)
{
return response()->json([
'code' => $exception->status,
'message' => $exception->getMessage(),
'errors' => $exception->errors(),
], $exception->status);
}
}

View File

@ -4,14 +4,17 @@ namespace App\Http\Controllers\Api;
use App\Admin\Services\WorkFlowService;
use App\Exceptions\RuntimeException;
use App\Http\Resources\ReimbursementResource;
use App\Http\Resources\{ReimbursementResource, WorkflowLogResource};
use App\Models\{Keyword, Reimbursement, WorkflowCheck};
use Illuminate\Http\Request;
use Illuminate\Http\{Request, Response};
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use App\Enums\CheckStatus;
use Throwable;
/**
* 报销管理
*/
class ReimbursementController extends Controller
{
public function index(Request $request)
@ -72,19 +75,8 @@ class ReimbursementController extends Controller
public function show($id, Request $request): ReimbursementResource
{
/** @var \App\Models\Employee */
$user = $request->user();
/** @var \App\Models\Reimbursement */
$reimbursement = $user->reimbursements()->find($id);
if (is_null($reimbursement)) {
throw new RuntimeException('报销记录未找到');
}
return ReimbursementResource::make(
$reimbursement->load(['type', 'workflow', 'employee', 'store']),
);
$reimbursement = Reimbursement::with(['type', 'workflow', 'employee', 'store'])->findOrFail($id);
return ReimbursementResource::make($reimbursement);
}
public function update($id, Request $request, WorkFlowService $workFlowService): ReimbursementResource
@ -157,4 +149,52 @@ class ReimbursementController extends Controller
return response()->noContent();
}
public function checkList(Request $request)
{
$user = $request->user();
$query = Reimbursement::with(['workflow', 'type', 'store'])
->whereHas('workflow', fn($q) => $q->where('check_status', CheckStatus::Processing))
->whereHas('workflow.logs', fn($q) => $q->own($user))->orderBy('created_at', 'desc');
$list = $query->paginate($request->input('per_page'));
return ReimbursementResource::collection($list);
}
public function check($id, Request $request, WorkFlowService $workFlowService)
{
$request->validate([
'status' => ['required'],
'remarks' => [Rule::requiredIf(fn() => !$request->input('status'))]
], [
'remarks.required_if' => '未通过原因必填',
]);
$info = Reimbursement::findOrFail($id);
$user = $request->user();
try {
DB::beginTransaction();
$log = $info->workflow->logs()->where('check_status', CheckStatus::Processing)->first();
if (!$log) {
throw new RuntimeException('审核已经完成');
}
if (!$workFlowService->check($user, $log, !!$request->input('status'), ['remarks' => $request->input('remarks')])) {
throw new RuntimeException($workFlowService->getError());
}
DB::commit();
return response('', Response::HTTP_OK);
} catch (\Exception $e) {
DB::rollBack();
throw new RuntimeException($e->getMessage());
}
}
public function logs($id)
{
$info = Reimbursement::findOrFail($id);
$logs = $info->workflow->logs()->sort()->get();
return WorkflowLogResource::collection($logs);
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Resources\KeywordResource;
use App\Models\{WorkflowLog, WorkflowCheck};
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Relations\Relation;
use App\Enums\{CheckStatus};
use App\Http\Resources\{WorkflowLogResource, WorkflowCheckResource};
use App\Exceptions\RuntimeException;
class WorkflowController extends Controller
{
public function index(Request $request)
{
$request->validate([
'subject_type' => 'required',
]);
$user = $this->guard()->user();
$query = WorkflowLog::with(['check.subject'])
->whereHas('check',fn($q) => $q->where('subject_type', $request->input('subject_type')))
->own($user)
->where('check_status', CheckStatus::Processing)
->orderBy('created_at', 'desc');
$list = $query->paginate($request->input('per_page'));
return WorkflowLogResource::collection($list);
}
public function show($id, Request $request)
{
$request->validate([
'subject_type' => 'required',
]);
$user = $this->guard()->user();
$info = WorkflowLog::with(['check.subject'])->own($user)->findOrFail($id);
return WorkflowLogResource::make($info);
}
}

View File

@ -3,6 +3,7 @@
namespace App\Http\Resources;
use Illuminate\Http\Request;
use App\Enums\CheckStatus;
use Illuminate\Http\Resources\Json\JsonResource;
class WorkflowLogResource extends JsonResource
@ -25,7 +26,7 @@ class WorkflowLogResource extends JsonResource
'checked_at' => $this->checked_at?->timestamp,
'remarks' => $this->remarks,
'check_status' => $this->check_status,
'check_status_text' => $this->check_status?->text(),
'check_status_text' => $this->check_status->text(),
'sort' => $this->sort,
'check' => WorkflowCheckResource::make($this->whenLoaded('check')),
];

View File

@ -16,6 +16,7 @@ class WorkflowLog extends Model
protected $casts = [
'check_type' => CheckType::class,
'check_status' => CheckStatus::class,
'checked_at' => 'datetime',
];
public function check()
@ -30,7 +31,7 @@ class WorkflowLog extends Model
public function scopeSort($q)
{
return $q->orderBy('batch_id')->orderBy('sort');
return $q->orderBy('batch_id', 'desc')->orderBy('sort', 'desc');
}
public function scopeOwn($builder, $user)

View File

@ -31,11 +31,6 @@ return new class extends Migration
$table->unsignedInteger('check_status')->default(CheckStatus::None->value)->comment('审核状态');
$table->timestamp('checked_at')->nullable()->comment('审核通过时间');
$table->string('check_remarks')->nullable()->comment('审核未通过原因');
$table->string('check_type')->comment('审核类型{job, user}');
$table->string('check_value')->comment('审核类型值');
$table->string('check_name')->comment('审核名称(展示用)');
$table->timestamps();
$table->comment('审核申请');
});

View File

@ -55,12 +55,8 @@ Route::group([
});
// 报销管理
// Route::group(['middleware' => ['user_role:store_user']], function () {
// });
Route::get('reimbursements/checks', [\App\Http\Controllers\Api\ReimbursementController::class, 'checkList']);
Route::get('reimbursements/check', [\App\Http\Controllers\Api\ReimbursementController::class, 'checkList']);
Route::post('reimbursements/{id}/check', [\App\Http\Controllers\Api\ReimbursementController::class, 'check']);
Route::get('reimbursements/{id}/logs', [\App\Http\Controllers\Api\ReimbursementController::class, 'logs']);
Route::apiResource('reimbursements', \App\Http\Controllers\Api\ReimbursementController::class);
// 审核
Route::get('workflow', [\App\Http\Controllers\Api\WorkflowController::class, 'index']);
Route::get('workflow/{id}', [\App\Http\Controllers\Api\WorkflowController::class, 'show']);
});