18 changed files with 543 additions and 19 deletions
@ -0,0 +1,177 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Admin; |
|||
|
|||
use App\Exceptions\CustomException; |
|||
use App\Models\ParkingAbnormal; |
|||
use App\Services\ApiResponseService; |
|||
use App\Services\ParkingAbnormalService; |
|||
use Exception; |
|||
use Illuminate\Http\JsonResponse; |
|||
use Illuminate\Http\Request; |
|||
use Illuminate\Validation\ValidationException; |
|||
|
|||
class ParkingAbnormalController extends BaseController |
|||
{ |
|||
protected string $menuUri = 'abnormalResourceUsage'; |
|||
|
|||
/** |
|||
* @var ParkingAbnormalService |
|||
*/ |
|||
protected ParkingAbnormalService $service; |
|||
|
|||
/** |
|||
* 构造函数 |
|||
* @param ApiResponseService $responseService |
|||
* @param ParkingAbnormalService $service |
|||
*/ |
|||
public function __construct( |
|||
ApiResponseService $responseService, |
|||
ParkingAbnormalService $service |
|||
) { |
|||
parent::__construct($responseService); |
|||
$this->service = $service; |
|||
} |
|||
|
|||
/** |
|||
* @param Request $request |
|||
* @return JsonResponse |
|||
*/ |
|||
public function index(Request $request): JsonResponse |
|||
{ |
|||
try { |
|||
$query = ParkingAbnormal::query(); |
|||
|
|||
if ($request->has('parking_id')) { |
|||
$parking_id = $request->input('parking_id'); |
|||
if ($parking_id) { |
|||
$query->where('parking_id', $parking_id); |
|||
} |
|||
} |
|||
|
|||
if ($request->has('date_type')) { |
|||
$date_type = $request->input('date_type'); |
|||
$start_date = ''; |
|||
if ($date_type == 1) { |
|||
$start_date = date('Y-m-d 00:00:00', time()); |
|||
} else { |
|||
if ($date_type == 2) { |
|||
$start_date = date( |
|||
'Y-m-d 00:00:00', |
|||
strtotime('-3 day') |
|||
); |
|||
} else { |
|||
if ($date_type == 3) { |
|||
$start_date = date( |
|||
'Y-m-d 00:00:00', |
|||
strtotime('-7 day') |
|||
); |
|||
} else { |
|||
if ($date_type == 4) { |
|||
$start_date = date( |
|||
'Y-m-d 00:00:00', |
|||
strtotime('-1 month') |
|||
); |
|||
} else { |
|||
if ($date_type == 5) { |
|||
$start_date = date( |
|||
'Y-m-d 00:00:00', |
|||
strtotime('-3 month') |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
if ($start_date) { |
|||
$end_date = date('Y-m-d 23:59:59', time()); |
|||
$query->whereBetween('enter_at', [$start_date, $end_date]); |
|||
} |
|||
} |
|||
|
|||
if ($request->has('status')) { |
|||
$status = $request->input('status'); |
|||
if ($status) { |
|||
$query->where('status', $status); |
|||
} |
|||
} |
|||
|
|||
if ($request->has('operation_type')) { |
|||
$operation_type = $request->input('operation_type'); |
|||
if ($operation_type) { |
|||
$query->where('operation_type', $operation_type); |
|||
} |
|||
} |
|||
|
|||
// 分页 |
|||
$page = $request->input('page', 1); |
|||
$perPage = $request->input('per_page', 10); |
|||
$total = $query->count(); |
|||
$items = $query->latest()->forPage($page, $perPage)->get()->each( |
|||
function ($item) { |
|||
return $this->service->getItem($item); |
|||
} |
|||
); |
|||
|
|||
return $this->responseService->success([ |
|||
'items' => $items, |
|||
'total' => $total, |
|||
'page' => $page, |
|||
'per_page' => $perPage, |
|||
'last_page' => ceil($total / $perPage), |
|||
]); |
|||
} catch (Exception $e) { |
|||
$m_prefix = __('exception.exception_handler.resource'); |
|||
return $this->responseService->systemError( |
|||
$m_prefix . ':' . $e->getMessage() |
|||
); |
|||
} |
|||
} |
|||
|
|||
public function handle(Request $request): JsonResponse |
|||
{ |
|||
try { |
|||
$data = $request->all(); |
|||
$this->validateId($data['id'] ?? 0, ParkingAbnormal::class); |
|||
$this->service->updateOperationType( |
|||
$data['id'], |
|||
$data['reason'] ?? '' |
|||
); |
|||
return $this->responseService->success( |
|||
null, |
|||
__('admin.operation_successful') |
|||
); |
|||
} catch (ValidationException|CustomException $e) { |
|||
throw $e; |
|||
} catch (Exception $e) { |
|||
return $this->responseService->systemError( |
|||
__('admin.operation_failed') . ':' |
|||
. $e->getMessage() |
|||
); |
|||
} |
|||
} |
|||
|
|||
public function ignore(Request $request): JsonResponse |
|||
{ |
|||
try { |
|||
$data = $request->all(); |
|||
$this->validateId($data['id'] ?? 0, ParkingAbnormal::class); |
|||
$this->service->updateOperationType( |
|||
$data['id'], |
|||
$data['reason'] ?? '', |
|||
2 |
|||
); |
|||
return $this->responseService->success( |
|||
null, |
|||
__('admin.operation_successful') |
|||
); |
|||
} catch (ValidationException|CustomException $e) { |
|||
throw $e; |
|||
} catch (Exception $e) { |
|||
return $this->responseService->systemError( |
|||
__('admin.operation_failed') . ':' |
|||
. $e->getMessage() |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
<?php |
|||
|
|||
namespace App\Models; |
|||
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory; |
|||
use Illuminate\Database\Eloquent\Model; |
|||
|
|||
class ParkingAbnormal extends Model |
|||
{ |
|||
use HasFactory; |
|||
|
|||
protected $table = 'parking_abnormal'; |
|||
|
|||
protected $fillable |
|||
= [ |
|||
'space_id', |
|||
'parking_id', |
|||
'license_plate_id', |
|||
'enter_at', |
|||
'type', |
|||
'status', |
|||
'operation_type', |
|||
'handle_reason', |
|||
'reason', |
|||
'operation_at', |
|||
'reservation_id' |
|||
]; |
|||
|
|||
protected $hidden |
|||
= [ |
|||
'created_at', |
|||
'update_at' |
|||
]; |
|||
|
|||
public function getEnterAtAttribute($value): string |
|||
{ |
|||
return $value ? date("Y-m-d H:i:s", strtotime($value)) : $value; |
|||
} |
|||
|
|||
|
|||
public function getOperationAtAttribute($value): string |
|||
{ |
|||
return $value ? date("Y-m-d H:i:s", strtotime($value)) : ''; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,177 @@ |
|||
<?php |
|||
|
|||
namespace App\Services; |
|||
|
|||
use App\Models\AdminFloor; |
|||
use App\Models\Parking; |
|||
use App\Models\ParkingAbnormal; |
|||
use App\Models\ParkingLicensePlate; |
|||
use App\Models\ParkingReservation; |
|||
use App\Models\ParkingSpace; |
|||
use App\Models\ParkingSpaceAttributes; |
|||
use App\Models\ParkingSpaceType; |
|||
use Exception; |
|||
use Illuminate\Support\Facades\DB; |
|||
|
|||
class ParkingAbnormalService extends BaseService |
|||
{ |
|||
public array $typeArr |
|||
= [ |
|||
1 => 'occupancy', |
|||
]; |
|||
public array $statusArr |
|||
= [ |
|||
'unprocessed', |
|||
'processed' |
|||
]; |
|||
public array $operationTypeArr |
|||
= [ |
|||
1 => 'handle', |
|||
2 => 'ignore' |
|||
]; |
|||
public array $reasonArr |
|||
= [ |
|||
1 => 'reason1', |
|||
2 => 'reason2', |
|||
3 => 'reason3', |
|||
4 => 'reason4' |
|||
]; |
|||
public array $dateArr |
|||
= [ |
|||
1 => 'today', |
|||
2 => 'days3', |
|||
3 => 'week', |
|||
4 => 'month', |
|||
5 => 'month3' |
|||
]; |
|||
protected string $menuTitle = 'abnormal_resource_usage'; |
|||
|
|||
/** |
|||
* @return array|string[] |
|||
*/ |
|||
public function getDateArr(): array |
|||
{ |
|||
$dateArr = $this->dateArr; |
|||
foreach ($dateArr as $key => $value) { |
|||
$dateArr[$key] = __service($this->menuTitle . '.' . $value); |
|||
} |
|||
return $dateArr; |
|||
} |
|||
|
|||
public function getItem($item) |
|||
{ |
|||
$item['parking'] = Parking::getName($item['parking_id']); |
|||
$ParkingSpace = ParkingSpace::query()->find($item['space_id']); |
|||
$item['floor'] = AdminFloor::getName($ParkingSpace['floor_id']); |
|||
$item['parking_space_number'] = $ParkingSpace['number']; |
|||
$item['parking_space_type'] = ParkingSpaceType::getName( |
|||
$ParkingSpace['space_type_id'] |
|||
); |
|||
$item['parking_space_attr'] = ParkingSpaceAttributes::getAttr( |
|||
$ParkingSpace['space_attr_id'] |
|||
); |
|||
$item['license_plate'] = ParkingLicensePlate::getNumber( |
|||
$item['license_plate_id'] |
|||
); |
|||
$item['duration'] = get_time_difference_str($item['enter_at']); |
|||
$typeArr = $this->getType(); |
|||
$item['type'] = $typeArr[$item['type']]; |
|||
$statusArr = $this->getStatus(); |
|||
$item['status'] = $statusArr[$item['status']]; |
|||
$operationTypeArr = $this->getOperationType(); |
|||
$item['operation_type'] = $operationTypeArr[$item['operation_type']] ?? |
|||
''; |
|||
$reasonArr = $this->getReason(); |
|||
$item['reason'] = $reasonArr[$item['reason']] ?? ''; |
|||
$item['reservation_id'] = ParkingReservation::getReserveId( |
|||
$item['reservation_id'] |
|||
); |
|||
|
|||
unset( |
|||
$item['parking_id'], |
|||
$item['space_id'], |
|||
$item['license_plate_id'] |
|||
); |
|||
return $item; |
|||
} |
|||
|
|||
/** |
|||
* @return array|string[] |
|||
*/ |
|||
public function getType(): array |
|||
{ |
|||
$typeArr = $this->typeArr; |
|||
foreach ($typeArr as $key => $value) { |
|||
$typeArr[$key] = __service($this->menuTitle . '.' . $value); |
|||
} |
|||
return $typeArr; |
|||
} |
|||
|
|||
/** |
|||
* @return array|string[] |
|||
*/ |
|||
public function getStatus(): array |
|||
{ |
|||
$typeArr = $this->statusArr; |
|||
foreach ($typeArr as $key => $value) { |
|||
$typeArr[$key] = __service($this->menuTitle . '.' . $value); |
|||
} |
|||
return $typeArr; |
|||
} |
|||
|
|||
/** |
|||
* @return array|string[] |
|||
*/ |
|||
public function getOperationType(): array |
|||
{ |
|||
$operationTypeArr = $this->operationTypeArr; |
|||
foreach ($operationTypeArr as $key => $value) { |
|||
$operationTypeArr[$key] = __service( |
|||
$this->menuTitle . '.' . $value |
|||
); |
|||
} |
|||
return $operationTypeArr; |
|||
} |
|||
|
|||
/** |
|||
* @return array|string[] |
|||
*/ |
|||
public function getReason(): array |
|||
{ |
|||
$reasonArr = $this->reasonArr; |
|||
foreach ($reasonArr as $key => $value) { |
|||
$reasonArr[$key] = __service($this->menuTitle . '.' . $value); |
|||
} |
|||
return $reasonArr; |
|||
} |
|||
|
|||
public function updateOperationType($id, $reason, $operation_type = 1) |
|||
{ |
|||
try { |
|||
DB::beginTransaction(); |
|||
|
|||
$model = ParkingAbnormal::query()->findOrFail($id); |
|||
$oldValue = $model->toArray(); |
|||
|
|||
$model->update([ |
|||
'operation_type' => $operation_type, |
|||
'handle_reason' => $reason, |
|||
'operation_at' => get_datetime(), |
|||
'updated_at' => get_datetime() |
|||
]); |
|||
|
|||
$this->logService->logUpdated( |
|||
$model, |
|||
$oldValue, |
|||
$this->menuTitle . '.operation' |
|||
); |
|||
|
|||
DB::commit(); |
|||
return $model; |
|||
} catch (Exception $e) { |
|||
DB::rollBack(); |
|||
throw $e; |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
<?php |
|||
|
|||
use Illuminate\Database\Migrations\Migration; |
|||
use Illuminate\Database\Schema\Blueprint; |
|||
use Illuminate\Support\Facades\Schema; |
|||
|
|||
return new class extends Migration |
|||
{ |
|||
/** |
|||
* Run the migrations. |
|||
*/ |
|||
public function up(): void |
|||
{ |
|||
Schema::create('parking_abnormal', function (Blueprint $table) { |
|||
$table->id(); |
|||
$table->integer('space_id')->comment('车位id'); |
|||
$table->integer('parking_id')->comment('停车场ID'); |
|||
$table->integer('license_plate_id')->comment('车牌号码'); |
|||
$table->timestamp('enter_at')->comment('入场时间'); |
|||
$table->tinyInteger('type')->default(1)->comment('异常类型'); |
|||
$table->tinyInteger('status')->default(0)->comment('异常状态'); |
|||
$table->tinyInteger('operation_type')->default(0)->comment('操作类型'); |
|||
$table->string('handle_reason', 255)->default('')->comment('处理原因'); |
|||
$table->tinyInteger('reason')->default(1)->comment('异常原因'); |
|||
$table->timestamp('operation_at')->nullable()->comment('操作时间'); |
|||
$table->integer('reservation_id')->nullable()->comment('预约id'); |
|||
$table->timestamps(); |
|||
$table->innoDb(); |
|||
$table->comment('白名单'); |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Reverse the migrations. |
|||
*/ |
|||
public function down(): void |
|||
{ |
|||
Schema::dropIfExists('parking_abnormal'); |
|||
} |
|||
}; |
|||
Loading…
Reference in new issue