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