generated from liutk/owl-admin-base
api 报销审核
parent
6dec9bba36
commit
075e95c764
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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')),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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('审核申请');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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']);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue