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 WorkflowCheck $check 待审核记录
* @param Employee $user 申请人 * @param Employee $user 申请人
*
* @return bool true: 成功, false: 失败, $this->getError(): 错误消息 * @return bool true: 成功, false: 失败, $this->getError(): 错误消息
*/ */
public function apply(WorkflowCheck $check, Employee $user) public function apply(WorkflowCheck $check, Employee $user)

View File

@ -4,6 +4,8 @@ namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable; use Throwable;
use Illuminate\Http\{Request};
use Illuminate\Validation\ValidationException;
class Handler extends ExceptionHandler class Handler extends ExceptionHandler
{ {
@ -18,13 +20,26 @@ class Handler extends ExceptionHandler
'password_confirmation', 'password_confirmation',
]; ];
protected $dontReport = [
RuntimeException::class,
];
/** /**
* Register the exception handling callbacks for the application. * Register the exception handling callbacks for the application.
*/ */
public function register(): void 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\Admin\Services\WorkFlowService;
use App\Exceptions\RuntimeException; use App\Exceptions\RuntimeException;
use App\Http\Resources\ReimbursementResource; use App\Http\Resources\{ReimbursementResource, WorkflowLogResource};
use App\Models\{Keyword, Reimbursement, WorkflowCheck}; use App\Models\{Keyword, Reimbursement, WorkflowCheck};
use Illuminate\Http\Request; use Illuminate\Http\{Request, Response};
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use App\Enums\CheckStatus; use App\Enums\CheckStatus;
use Throwable; use Throwable;
/**
* 报销管理
*/
class ReimbursementController extends Controller class ReimbursementController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
@ -72,19 +75,8 @@ class ReimbursementController extends Controller
public function show($id, Request $request): ReimbursementResource public function show($id, Request $request): ReimbursementResource
{ {
/** @var \App\Models\Employee */ $reimbursement = Reimbursement::with(['type', 'workflow', 'employee', 'store'])->findOrFail($id);
$user = $request->user(); return ReimbursementResource::make($reimbursement);
/** @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']),
);
} }
public function update($id, Request $request, WorkFlowService $workFlowService): ReimbursementResource public function update($id, Request $request, WorkFlowService $workFlowService): ReimbursementResource
@ -157,4 +149,52 @@ class ReimbursementController extends Controller
return response()->noContent(); 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; namespace App\Http\Resources;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Enums\CheckStatus;
use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\Json\JsonResource;
class WorkflowLogResource extends JsonResource class WorkflowLogResource extends JsonResource
@ -25,7 +26,7 @@ class WorkflowLogResource extends JsonResource
'checked_at' => $this->checked_at?->timestamp, 'checked_at' => $this->checked_at?->timestamp,
'remarks' => $this->remarks, 'remarks' => $this->remarks,
'check_status' => $this->check_status, 'check_status' => $this->check_status,
'check_status_text' => $this->check_status?->text(), 'check_status_text' => $this->check_status->text(),
'sort' => $this->sort, 'sort' => $this->sort,
'check' => WorkflowCheckResource::make($this->whenLoaded('check')), 'check' => WorkflowCheckResource::make($this->whenLoaded('check')),
]; ];

View File

@ -16,6 +16,7 @@ class WorkflowLog extends Model
protected $casts = [ protected $casts = [
'check_type' => CheckType::class, 'check_type' => CheckType::class,
'check_status' => CheckStatus::class, 'check_status' => CheckStatus::class,
'checked_at' => 'datetime',
]; ];
public function check() public function check()
@ -30,7 +31,7 @@ class WorkflowLog extends Model
public function scopeSort($q) 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) 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->unsignedInteger('check_status')->default(CheckStatus::None->value)->comment('审核状态');
$table->timestamp('checked_at')->nullable()->comment('审核通过时间'); $table->timestamp('checked_at')->nullable()->comment('审核通过时间');
$table->string('check_remarks')->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->timestamps();
$table->comment('审核申请'); $table->comment('审核申请');
}); });

View File

@ -55,12 +55,8 @@ Route::group([
}); });
// 报销管理 // 报销管理
// Route::group(['middleware' => ['user_role:store_user']], function () { 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/checks', [\App\Http\Controllers\Api\ReimbursementController::class, 'checkList']); Route::get('reimbursements/{id}/logs', [\App\Http\Controllers\Api\ReimbursementController::class, 'logs']);
Route::apiResource('reimbursements', \App\Http\Controllers\Api\ReimbursementController::class); 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']);
}); });