generated from liutk/owl-admin-base
api 请假申请
parent
1939d281fa
commit
f084d81dba
|
|
@ -55,6 +55,7 @@ class HolidayController extends AdminController
|
||||||
]),
|
]),
|
||||||
]))
|
]))
|
||||||
->columns([
|
->columns([
|
||||||
|
amisMake()->TableColumn()->name('id')->label(__('holiday_apply.id')),
|
||||||
amisMake()->TableColumn()->name('store.title')->label(__('employee_sign.store_id')),
|
amisMake()->TableColumn()->name('store.title')->label(__('employee_sign.store_id')),
|
||||||
amisMake()->TableColumn()->name('employee.name')->label(__('holiday_apply.employee_id')),
|
amisMake()->TableColumn()->name('employee.name')->label(__('holiday_apply.employee_id')),
|
||||||
amisMake()->TableColumn()->name('type.name')->label(__('holiday_apply.type_id')),
|
amisMake()->TableColumn()->name('type.name')->label(__('holiday_apply.type_id')),
|
||||||
|
|
@ -115,7 +116,7 @@ class HolidayController extends AdminController
|
||||||
['label' => __('holiday_apply.store_id'), 'content' => '${store.title}'],
|
['label' => __('holiday_apply.store_id'), 'content' => '${store.title}'],
|
||||||
['label' => __('holiday_apply.employee_id'), 'content' => '${employee.name}'],
|
['label' => __('holiday_apply.employee_id'), 'content' => '${employee.name}'],
|
||||||
['label' => __('holiday_apply.type_id'), 'content' => '${type.name}'],
|
['label' => __('holiday_apply.type_id'), 'content' => '${type.name}'],
|
||||||
['label' => __('holiday_apply.date'), 'content' => '${start_at} ${end_at}'],
|
['label' => __('holiday_apply.date'), 'content' => [amisMake()->Tag()->label('${start_at}'), amisMake()->Tag()->label('${end_at}')]],
|
||||||
['label' => __('holiday_apply.reason'), 'content' => '${reason}'],
|
['label' => __('holiday_apply.reason'), 'content' => '${reason}'],
|
||||||
['label' => __('holiday_apply.created_at'), 'content' => '${created_at}'],
|
['label' => __('holiday_apply.created_at'), 'content' => '${created_at}'],
|
||||||
['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
|
['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ class SignRepairController extends AdminController
|
||||||
['label' => __('employee_sign_repair.created_at'), 'content' => '${created_at}'],
|
['label' => __('employee_sign_repair.created_at'), 'content' => '${created_at}'],
|
||||||
['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
|
['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
|
||||||
['label' => __('workflow_log.checked_at'), 'content' => '${workflow.checked_at}'],
|
['label' => __('workflow_log.checked_at'), 'content' => '${workflow.checked_at}'],
|
||||||
['label' => __('workflow_log.check_remarks'), 'content' => '${workflow.check_remarks}'],
|
['label' => __('workflow_log.remarks'), 'content' => '${workflow.check_remarks}'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->baseDetail()->id($detailId)->title('')->onEvent([
|
return $this->baseDetail()->id($detailId)->title('')->onEvent([
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ class HolidayApplyService extends BaseService
|
||||||
|
|
||||||
public function validate($data, $model = null)
|
public function validate($data, $model = null)
|
||||||
{
|
{
|
||||||
// 验证申请时间是否重叠
|
// todo 验证申请时间是否重复
|
||||||
// todo
|
|
||||||
$createRules = [
|
$createRules = [
|
||||||
'employee_id' => ['required'],
|
'employee_id' => ['required'],
|
||||||
'type_id' => ['required'],
|
'type_id' => ['required'],
|
||||||
|
|
@ -51,4 +50,32 @@ class HolidayApplyService extends BaseService
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function update($primaryKey, $data): bool
|
||||||
|
{
|
||||||
|
$model = $this->query()->whereKey($primaryKey)->firstOrFail();
|
||||||
|
if (!$model->canUpdate()) {
|
||||||
|
return $this->setError('审核中, 无法修改');
|
||||||
|
}
|
||||||
|
$data = $this->resloveData($data, $model);
|
||||||
|
$validate = $this->validate($data, $model);
|
||||||
|
if ($validate !== true) {
|
||||||
|
$this->setError($validate);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model->update($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(string $ids): mixed
|
||||||
|
{
|
||||||
|
$list = HolidayApply::with(['workflow'])->whereIn('id', explode(',', $ids))->get();
|
||||||
|
foreach ($list as $item) {
|
||||||
|
if (!$item->canUpdate()) {
|
||||||
|
return $this->setError('审核中, 无法删除');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\Hr;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Api\Controller;
|
||||||
|
use Illuminate\Http\{Request, Response};
|
||||||
|
use App\Models\HolidayApply;
|
||||||
|
use App\Http\Resources\HolidayApplyResource;
|
||||||
|
use App\Admin\Services\{HolidayApplyService, WorkFlowService};
|
||||||
|
use App\Exceptions\RuntimeException;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请假管理
|
||||||
|
*/
|
||||||
|
class HolidayController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$user = $this->guard()->user();
|
||||||
|
$list = HolidayApply::with(['type', 'workflow'])
|
||||||
|
->where('employee_id', $user->id)
|
||||||
|
->filter($request->all())
|
||||||
|
->orderBy('id', 'desc')
|
||||||
|
->paginate($request->input('per_page'));
|
||||||
|
|
||||||
|
return HolidayApplyResource::collection($list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
$info = HolidayApply::with(['type', 'employee', 'store', 'workflow'])->findOrFail($id);
|
||||||
|
|
||||||
|
return HolidayApplyResource::make($info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request, HolidayApplyService $service)
|
||||||
|
{
|
||||||
|
$user = $this->guard()->user();
|
||||||
|
$data = $request->all();
|
||||||
|
$data['employee_id'] = $user->id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
$data = $service->resloveData($data);
|
||||||
|
$result = $service->validate($data);
|
||||||
|
if ($result !== true) {
|
||||||
|
throw new RuntimeException($result);
|
||||||
|
}
|
||||||
|
$model = HolidayApply::create($data);
|
||||||
|
$workflow = WorkFlowService::make();
|
||||||
|
if (!$workflow->apply($model->workflow, $user)) {
|
||||||
|
throw new RuntimeException($workflow->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
return response()->noContent();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
throw new RuntimeException($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request, HolidayApplyService $service)
|
||||||
|
{
|
||||||
|
$user = $this->guard()->user();
|
||||||
|
$model = HolidayApply::where('employee_id', $user->id)->findOrFail($id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
if (!$service->update($id, $request->all())) {
|
||||||
|
throw new RuntimeException($service->getError());
|
||||||
|
}
|
||||||
|
$workflow = WorkFlowService::make();
|
||||||
|
if (!$workflow->apply($model->workflow, $user)) {
|
||||||
|
throw new RuntimeException($workflow->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
return response()->noContent();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
throw new RuntimeException($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id, HolidayApplyService $service)
|
||||||
|
{
|
||||||
|
$user = $this->guard()->user();
|
||||||
|
$model = HolidayApply::with(['workflow'])->where('employee_id', $user->id)->findOrFail($id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
if (!$service->delete($id)) {
|
||||||
|
throw new RuntimeException($service->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
return response()->noContent();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
throw new RuntimeException($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -71,7 +71,7 @@ class SignRepairController extends Controller
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
$data = $service->resloveData($data, $model);
|
$data = $service->resloveData($request->all(), $model);
|
||||||
$result = $service->validate($data, $model);
|
$result = $service->validate($data, $model);
|
||||||
if ($result !== true) {
|
if ($result !== true) {
|
||||||
throw new RuntimeException($result);
|
throw new RuntimeException($result);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use Illuminate\Http\{Request, Response};
|
use Illuminate\Http\{Request, Response};
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||||
use App\Http\Resources\{ReimbursementResource, WorkflowLogResource, EmployeeSignRepairResource};
|
use App\Http\Resources\{ReimbursementResource, WorkflowLogResource, EmployeeSignRepairResource, HolidayApplyResource};
|
||||||
use App\Enums\CheckStatus;
|
use App\Enums\CheckStatus;
|
||||||
use App\Models\{WorkflowLog, WorkflowCheck};
|
use App\Models\{WorkflowLog, WorkflowCheck};
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
@ -24,7 +24,14 @@ class WorkflowController extends Controller
|
||||||
$resource = $this->mapResource($subjectType);
|
$resource = $this->mapResource($subjectType);
|
||||||
|
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
$query = $model::query()->with(['workflow'])
|
|
||||||
|
$include = ['workflow'];
|
||||||
|
if ($request->input('include')) {
|
||||||
|
$explodes = explode(',', $request->input('include'));
|
||||||
|
$include = array_merge($include, $explodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $model::query()->with($include)
|
||||||
->whereHas('workflow', fn($q) => $q->where('check_status', CheckStatus::Processing))
|
->whereHas('workflow', fn($q) => $q->where('check_status', CheckStatus::Processing))
|
||||||
->whereHas('workflow.logs', fn($q) => $q->own($user))
|
->whereHas('workflow.logs', fn($q) => $q->own($user))
|
||||||
->orderBy('created_at', 'desc');
|
->orderBy('created_at', 'desc');
|
||||||
|
|
@ -64,6 +71,26 @@ class WorkflowController extends Controller
|
||||||
return WorkflowLogResource::collection($logs);
|
return WorkflowLogResource::collection($logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function cancel($id, Request $request, WorkFlowService $workFlowService)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'subject_type' => 'required',
|
||||||
|
]);
|
||||||
|
$check = WorkflowCheck::where('subject_type', $request->input('subject_type'))->where('subject_id', $id)->firstOrFail();
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
if (!$workFlowService->cancel($check)) {
|
||||||
|
throw new RuntimeException($workFlowService->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
return response('', Response::HTTP_OK);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
throw new RuntimeException($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function check($id, Request $request, WorkFlowService $workFlowService)
|
public function check($id, Request $request, WorkFlowService $workFlowService)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
|
|
@ -98,6 +125,7 @@ class WorkflowController extends Controller
|
||||||
$map = [
|
$map = [
|
||||||
'reimbursements' => ReimbursementResource::class,
|
'reimbursements' => ReimbursementResource::class,
|
||||||
'employee_sign_repairs' => EmployeeSignRepairResource::class,
|
'employee_sign_repairs' => EmployeeSignRepairResource::class,
|
||||||
|
'holiday_applies' => HolidayApplyResource::class,
|
||||||
];
|
];
|
||||||
return data_get($map, $key);
|
return data_get($map, $key);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class HolidayApplyResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
|
||||||
|
'employee_id' => $this->employee_id,
|
||||||
|
'employee' => EmployeeResource::make($this->whenLoaded('employee')),
|
||||||
|
'store_id' => $this->store_id,
|
||||||
|
'store' => StoreResource::make($this->whenLoaded('store')),
|
||||||
|
|
||||||
|
'type_id' => $this->type_id,
|
||||||
|
'type' => KeywordResource::make($this->whenLoaded('type')),
|
||||||
|
|
||||||
|
'workflow_check' => WorkflowCheckResource::make($this->whenLoaded('workflow')),
|
||||||
|
|
||||||
|
'start_at' => $this->start_at->timestamp,
|
||||||
|
'end_at' => $this->end_at->timestamp,
|
||||||
|
|
||||||
|
'reason' => $this->reason,
|
||||||
|
'created_at' => $this->created_at->timestamp,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,16 +15,21 @@ class HolidayApply extends Model
|
||||||
{
|
{
|
||||||
use Filterable, HasCheckable, HasDateTimeFormatter;
|
use Filterable, HasCheckable, HasDateTimeFormatter;
|
||||||
|
|
||||||
protected $fillable = ['store_id', 'employee_id', 'start_at', 'end_at', 'type_id', 'reason'];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'start_at' => 'date:Y-m-d',
|
'start_at' => 'datetime:Y-m-d H:i',
|
||||||
'end_at' => 'date:Y-m-d',
|
'end_at' => 'datetime:Y-m-d H:i',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function modelFilter()
|
public function modelFilter()
|
||||||
{
|
{
|
||||||
return App\Admin\Filters\HolidayApplyFilter::class;
|
return \App\Admin\Filters\HolidayApplyFilter::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canUpdate(): bool
|
||||||
|
{
|
||||||
|
return in_array($this->workflow?->check_status, [CheckStatus::None, CheckStatus::Fail, CheckStatus::Cancel]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store()
|
public function store()
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ namespace App\Models;
|
||||||
use App\Enums\CheckStatus;
|
use App\Enums\CheckStatus;
|
||||||
use App\Enums\CheckType;
|
use App\Enums\CheckType;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use App\Traits\HasDateTimeFormatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审核流水
|
* 审核流水
|
||||||
|
|
@ -16,7 +17,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',
|
'checked_at' => 'datetime:Y-m-d H:i:s',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function check()
|
public function check()
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ Route::delete('/auth/logout', [AccessTokenController::class, 'destroy']);
|
||||||
// 数据字典
|
// 数据字典
|
||||||
Route::get('keyword', [\App\Http\Controllers\Api\KeywordController::class, 'index']);
|
Route::get('keyword', [\App\Http\Controllers\Api\KeywordController::class, 'index']);
|
||||||
|
|
||||||
|
// 字典表
|
||||||
|
Route::get('keywords', [KeywordController::class, 'index']);
|
||||||
Route::group([
|
Route::group([
|
||||||
'middleware' => ['auth:api'],
|
'middleware' => ['auth:api'],
|
||||||
], function () {
|
], function () {
|
||||||
// 字典表
|
|
||||||
Route::get('keywords', [KeywordController::class, 'index']);
|
|
||||||
// 文件上传
|
// 文件上传
|
||||||
Route::post('fileupload', FileUploadController::class);
|
Route::post('fileupload', FileUploadController::class);
|
||||||
|
|
||||||
|
|
@ -59,6 +59,9 @@ Route::group([
|
||||||
// 补卡申请
|
// 补卡申请
|
||||||
Route::apiResource('hr/sign-repairs', \App\Http\Controllers\Api\Hr\SignRepairController::class);
|
Route::apiResource('hr/sign-repairs', \App\Http\Controllers\Api\Hr\SignRepairController::class);
|
||||||
|
|
||||||
|
// 请假管理
|
||||||
|
Route::apiResource('hr/holidays', \App\Http\Controllers\Api\Hr\HolidayController::class);
|
||||||
|
|
||||||
// 报销管理
|
// 报销管理
|
||||||
Route::apiResource('reimbursements', \App\Http\Controllers\Api\ReimbursementController::class);
|
Route::apiResource('reimbursements', \App\Http\Controllers\Api\ReimbursementController::class);
|
||||||
|
|
||||||
|
|
@ -67,4 +70,5 @@ Route::group([
|
||||||
Route::get('workflow/{id}', [\App\Http\Controllers\Api\WorkflowController::class, 'show']);
|
Route::get('workflow/{id}', [\App\Http\Controllers\Api\WorkflowController::class, 'show']);
|
||||||
Route::get('workflow/{id}/logs', [\App\Http\Controllers\Api\WorkflowController::class, 'logs']);
|
Route::get('workflow/{id}/logs', [\App\Http\Controllers\Api\WorkflowController::class, 'logs']);
|
||||||
Route::post('workflow/{id}/check', [\App\Http\Controllers\Api\WorkflowController::class, 'check']);
|
Route::post('workflow/{id}/check', [\App\Http\Controllers\Api\WorkflowController::class, 'check']);
|
||||||
|
Route::post('workflow/{id}/cancel', [\App\Http\Controllers\Api\WorkflowController::class, 'cancel']);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue