store-manage/app/Http/Controllers/Api/Hr/SignController.php

89 lines
3.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Hr;
use App\Http\Controllers\Api\Controller;
use App\Models\{EmployeeSign, EmployeeSignLog};
use Illuminate\Http\{Request, Response};
use App\Exceptions\RuntimeException;
use Illuminate\Support\Facades\DB;
use App\Admin\Services\EmployeeSignService;
use App\Enums\{SignTime, SignType, SignStatus};
use Carbon\Carbon;
use Slowlyo\OwlAdmin\Services\AdminSettingService;
/**
* 考勤打卡
*/
class SignController extends Controller
{
public function index(Request $request)
{
$user = $this->guard()->user();
$time = $request->filled('time') ? Carbon::createFromFormat('Y-m', $request->input('time')) : now();
$list = EmployeeSign::where('employee_id', $user->id)->filter(['month' => $time->format('Y-m')])->get();
$data = [];
$start = $time->copy()->startOfMonth();
$end = $time->copy()->endOfMonth();
do {
$info = $list->where(fn($item) => $item->date->format('Y-m-d') == $start->format('Y-m-d'))->first();
array_push($data, [
'date' => $start->format('Y-m-d'),
'sign_status' => $info ? $info->sign_status : null,
'first_time' => $info && $info->first_time ? $info->first_time->format('H:i') : '',
'last_time' => $info && $info->last_time ? $info->last_time->format('H:i') : '',
]);
$start->addDay();
} while(!$end->isSameDay($start));
return $data;
}
public function info(Request $request, EmployeeSignService $service)
{
$user = $this->guard()->user();
$store = $user->store;
$date = now();
// 是否允许打卡
$enable = true;
// 上班/下班 打卡, 当天是否打卡
$time = EmployeeSignLog::filter(['date' => $date->format('Y-m-d')])->exists() ? SignTime::Afternoon : SignTime::Morning;
// 根据定位的距离判断, 是否外勤
$maxDistance = AdminSettingService::make()->arrayGet('sign', 'distance');
$type = SignType::Outside;
$distance = '';
$description = '当前位置不在考勤范围内,请选择外勤打卡';
if ($request->filled(['lon', 'lat']) && $store && $maxDistance) {
$distance = $service->haversineDistance($request->input('lat'), $request->input('lon'), $store->lat, $store->lon);
if ($distance <= $maxDistance) {
$description = '已进入考勤范围' . $store->title;
$type = SignType::Normal;
}
}
return compact('enable', 'time', 'type', 'description', 'distance');
}
public function store(Request $request, EmployeeSignService $service)
{
$request->validate([
'type' => ['required'],
'time' => ['required'],
]);
$user = $this->guard()->user();
$time = SignTime::from($request->input('time'));
try {
DB::beginTransaction();
if (!$service->signDay($user, $time, now(), $request->only(['remarks', 'position', 'type']))) {
throw new RuntimeException($service->getError());
}
DB::commit();
return response('', Response::HTTP_OK);
} catch (\Exception $e) {
DB::rollBack();
throw new RuntimeException($e->getMessage());
}
}
}