diff --git a/app/Http/Controllers/Admin/ParkingPatternSpaceController.php b/app/Http/Controllers/Admin/ParkingPatternSpaceController.php index f54b8c7..8257736 100644 --- a/app/Http/Controllers/Admin/ParkingPatternSpaceController.php +++ b/app/Http/Controllers/Admin/ParkingPatternSpaceController.php @@ -6,6 +6,7 @@ use App\Exceptions\CustomException; use App\Models\ParkingPattern; use App\Models\ParkingPatternSpace; use App\Models\ParkingSpace; +use App\Models\ParkingSpaceAttributes; use App\Models\ParkingSpaceType; use App\Services\ApiResponseService; use App\Services\ParkingPatternSpaceService; @@ -14,7 +15,6 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\ValidationException; -use Psr\SimpleCache\InvalidArgumentException; class ParkingPatternSpaceController extends BaseController { @@ -80,12 +80,13 @@ class ParkingPatternSpaceController extends BaseController $items = $query->latest()->forPage($page, $perPage)->select( $columns )->get()->each(function ($item) { - $item['parking_space_number'] = ParkingSpace::getNumber( - $item['space_id'] - ); + $ParkingSpace = ParkingSpace::query()->find($item['space_id']); + $item['parking_space_number'] = $ParkingSpace['number']; $item['parking_space_type'] = ParkingSpaceType::getName( $item['space_type_id'] ); + $item['parking_space_attr'] = ParkingSpaceAttributes::getAttr($ParkingSpace['space_attr_id']); + $item['auxiliary_space_type'] = ''; unset($item['space_id'], $item['space_type_id']); return $item; }); @@ -287,4 +288,46 @@ class ParkingPatternSpaceController extends BaseController ); } } + + // 批量更新车位类型 + public function updateType(Request $request): JsonResponse + { + try { + $rules = [ + 'space_type_id' => 'required|numeric', + 'ids' => 'required|array' + ]; + $messages = [ + 'space_type_id.required' => __( + 'validation.parking_space.type_id_empty' + ), + 'space_type_id.numeric' => __( + 'validation.parking_space.type_id_numeric' + ), + 'ids.required' => __('validation.id_empty'), + 'ids.array' => __('validation.id_empty') + ]; + + $validator = Validator::make($request->all(), $rules, $messages); + + if ($validator->fails()) { + throw new ValidationException($validator); + } + $data = $request->all(); + $ids = $data['ids'] ?? []; + $space_type_id = $data['space_type_id']; + foreach ($ids as $id) { + $this->service->updateData($id, $space_type_id); + } + return $this->responseService->success( + null, + __('admin.update_succeeded') + ); + } catch (Exception $e) { + return $this->responseService->systemError( + __('admin.operation_failed') . ':' + . $e->getMessage() + ); + } + } } diff --git a/app/Http/Controllers/Admin/ParkingSpaceCatMapController.php b/app/Http/Controllers/Admin/ParkingSpaceCatMapController.php index 66ff144..b61ec3e 100644 --- a/app/Http/Controllers/Admin/ParkingSpaceCatMapController.php +++ b/app/Http/Controllers/Admin/ParkingSpaceCatMapController.php @@ -4,8 +4,16 @@ namespace App\Http\Controllers\Admin; use App\Models\AdminFloor; use App\Models\ParkingElectronicMap; +use App\Models\ParkingLicensePlate; +use App\Models\ParkingPatternSpace; use App\Models\ParkingSpace; +use App\Models\ParkingSpaceAttributes; use App\Models\ParkingSpaceType; +use App\Models\ParkingSpaceTypeAttr; +use App\Services\EventCalendarService; +use App\Services\ParkingPatternSpaceService; +use App\Services\ParkingSpaceTypeAttrService; +use App\Services\ParkingSpaceTypeService; use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -17,8 +25,58 @@ class ParkingSpaceCatMapController extends BaseController public function search(): JsonResponse { try { + $modeTypeList = ParkingPatternSpaceService::getPatternSpaceTypeData(); $data = [ - 'parking_space_type_list' => ParkingSpaceType::getData() + 'parking_space_type_list' => ParkingSpaceType::getData(), + 'model_parking_space_type_list' => $modeTypeList, + 'parking_space_attr_list' => ParkingSpaceAttributes::getTypeList() + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + /** + * 返回占用、控制车位颜色 + * @return JsonResponse + */ + public function parkingTypeColor() + { + try { + $modeTypeList = ParkingPatternSpaceService::getPatternSpaceTypeData(); + $colorOccupyList = []; + $colorVacantList = []; + $colorArr = ParkingSpaceTypeService::$colorArr; + foreach ($modeTypeList as $modeTypeItem) { + $type_id = $modeTypeItem['space_type_id']; + $space_type = $modeTypeItem['space_type']; + $colorVacantData = $colorOccupyData = [ + 'space_type_id' => $type_id, + 'space_type' => $space_type, + 'space_attr_list' => [] + ]; + $typeAttrData = ParkingSpaceTypeAttrService::getTypeAttrData($type_id); + foreach ($typeAttrData as $typeAttrItem) { + $space_attr = ParkingSpaceAttributes::getAttr($typeAttrItem['attributes_id']); + $colorVacantData['space_attr_list'][] = [ + 'space_attr' => $space_attr, + 'color' => $colorArr[$typeAttrItem['attr_color_vacant']] + ] ; + $colorOccupyData['space_attr_list'][] = [ + 'space_attr' => $space_attr, + 'color' => $colorArr[$typeAttrItem['attr_color_occupy']] + ]; + } + $colorOccupyList[] = $colorOccupyData; + $colorVacantList[] = $colorVacantData; + } + $data = [ + 'color_occupy_list' => $colorOccupyList, + 'color_vacant_list' => $colorVacantList ]; return $this->responseService->success($data); } catch (Exception $e) { @@ -33,22 +91,43 @@ class ParkingSpaceCatMapController extends BaseController { try { $floor_id = $request->input('floor_id'); - $where = ['floor_id' => $floor_id]; - $sum = ParkingSpace::query()->where($where)->count(); - $surplus = ParkingSpace::query()->where($where)->where('status', 0) - ->count(); - $under_repair = ParkingSpace::query()->where($where)->where( - 'status', + $pattern_id = EventCalendarService::getTargetModeId(); + $spaceIds = ParkingPatternSpace::getParkingSpaceIds($pattern_id); + $sum = ParkingSpace::getModeFloorCount($floor_id, $spaceIds); + $surplus = ParkingSpace::getModeFloorCount($floor_id, $spaceIds, 0); + $under_repair = ParkingSpace::getModeFloorCount( + $floor_id, + $spaceIds, 2 - )->count(); + ); $occupancy_rate = get_ratio($sum, $surplus); $data = [ 'sum' => $sum, 'surplus' => $surplus, 'occupancy_rate' => $occupancy_rate, 'under_repair' => $under_repair, - 'parking_space_details' => 45 + 'parking_space_details' => [] ]; + $modeTypeList = ParkingPatternSpaceService::getPatternSpaceTypeData( + ); + foreach ($modeTypeList as $item) { + $data['parking_space_details'][] = [ + 'space_type_id' => $item['space_type_id'], + 'space_type' => $item['space_type'], + 'sum' => ParkingSpace::getModeFloorCount( + $floor_id, + $spaceIds, + '11', + $item['space_type_id'] + ), + 'surplus' => ParkingSpace::getModeFloorCount( + $floor_id, + $spaceIds, + 0, + $item['space_type_id'] + ) + ]; + } return $this->responseService->success($data); } catch (Exception $e) { $m_prefix = __('exception.exception_handler.resource'); @@ -62,7 +141,7 @@ class ParkingSpaceCatMapController extends BaseController { try { $floor_id = $request->input('floor_id'); - $parking_space_type = $request->input('parking_space_type'); + $floorData = AdminFloor::query()->where('id', $floor_id)->whereNull( 'deleted_at' )->first(); @@ -70,27 +149,56 @@ class ParkingSpaceCatMapController extends BaseController $floorData['pic_url'] = get_image_url($floorData['image_url']); unset($floorData['image_url']); } + + $colorArr = ParkingSpaceTypeService::$colorArr; + // 获取当前模式车位 + $pattern_id = EventCalendarService::getTargetModeId(); + $spaceIds = ParkingPatternSpace::getParkingSpaceIds($pattern_id); + // 查询车位所在图上位置 $model = ParkingElectronicMap::query()->where( 'floor_id', $floor_id - ); - if (isset($parking_space_type) && $parking_space_type) { - $type_arr = explode(',', $parking_space_type); - $space_ids = ParkingSpace::query()->whereIn( - 'space_type_id', - $type_arr - )->pluck('id'); - if ($space_ids) { - $model->whereIn('space_id', $space_ids); - } - } + )->whereIn('space_id', $spaceIds); $electronicMapData = $model->select()->get()->toArray(); foreach ($electronicMapData as &$item) { - $item['parking_space_number'] = ParkingSpace::getNumber( - $item['space_id'] - ); + $ParkingSpace = ParkingSpace::query()->find($item['space_id']); + $space_attr_id = $ParkingSpace['space_attr_id']; + $space_type_id = $ParkingSpace['space_type_id']; + $item['parking_space_number'] = $ParkingSpace['number']; $item['parking_space_id'] = $item['space_id']; - unset($item['space_id']); + + $ParkingAttr = ParkingSpaceAttributes::query()->find( + $space_attr_id + ); + $item['has_ar'] = !empty($ParkingSpace['license_plate_id']); + $item['attr_icon'] = get_image_url( + $ParkingAttr['import_diagram'] + ); + $item['attr_name'] = $ParkingAttr['attributes']; + + $ParkingType = ParkingSpaceType::query()->find($space_type_id); + $item['space_type'] = $ParkingType['name']; + + $ParkingColor = ParkingSpaceTypeAttr::getSpaceTypeAttrInfo( + $space_type_id, + $space_attr_id + ); + $item['attr_color'] = $ParkingColor + ? $ParkingColor['color_vacant'] + : $ParkingType['default_color_vacant']; + $item['attr_color_value'] = $colorArr[$item['attr_color']]; + $item['car_color'] = ''; + $item['car_no'] = ''; + if ($item['has_ar']) { + $item['car_color'] = $ParkingColor + ? $ParkingColor['color_occupy'] + : $ParkingType['default_color_occupy']; + $item['car_color_value'] = $colorArr[$item['car_color']]; + $item['car_no'] = ParkingLicensePlate::getNumber( + $ParkingSpace['license_plate_id'] + ); + } + unset($item['space_id'], $item['floor_id']); } $data = [ 'floor_data' => $floorData, diff --git a/app/Http/Controllers/Admin/ParkingSpaceController.php b/app/Http/Controllers/Admin/ParkingSpaceController.php index f5ef68d..8667c9c 100644 --- a/app/Http/Controllers/Admin/ParkingSpaceController.php +++ b/app/Http/Controllers/Admin/ParkingSpaceController.php @@ -6,10 +6,12 @@ use App\Exports\ParkingSpaceExport; use App\Http\Controllers\Controller; use App\Models\AdminFloor; use App\Models\ParkingLicensePlate; +use App\Models\ParkingPatternSpace; use App\Models\ParkingSpace; use App\Models\ParkingSpaceAttributes; use App\Models\ParkingSpaceType; use App\Services\ApiResponseService; +use App\Services\EventCalendarService; use App\Services\ParkingSpaceService; use Exception; use Illuminate\Http\JsonResponse; @@ -48,7 +50,9 @@ class ParkingSpaceController extends BaseController { try { $query = ParkingSpace::query(); - + $pattern_id = EventCalendarService::getTargetModeId(); + $spaceIds = ParkingPatternSpace::getParkingSpaceIds($pattern_id); + $query->whereIn('id', $spaceIds); if ($request->has('license_plate')) { $license_plate = $request->input('license_plate'); if (!empty($license_plate)) { @@ -232,6 +236,45 @@ class ParkingSpaceController extends BaseController } } + public function updateAuxiliaryType(Request $request): JsonResponse + { + try { + $rules = [ + 'auxiliary_space_type' => 'required|numeric', + 'space_ids' => 'required|array' + ]; + $messages = [ + 'auxiliary_space_type.required' => __( + 'validation.parking_space.attr_id_empty' + ), + 'auxiliary_space_type.numeric' => __( + 'validation.parking_space.attr_id_numeric' + ), + 'space_ids.required' => __( + 'validation.parking_space.ids_empty' + ), + 'space_ids.array' => __( + 'validation.parking_space.ids_array' + ) + ]; + $validator = Validator::make($request->all(), $rules, $messages); + + if ($validator->fails()) { + throw new ValidationException($validator); + } + $this->service->updateData($request->all(), 'auxiliary_space_type'); + return $this->responseService->success( + null, + __('admin.update_succeeded') + ); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.parking_space.update_attr_failed') . ':' + . $e->getMessage() + ); + } + } + /** * @return BinaryFileResponse */ diff --git a/app/Http/Middleware/CheckPermission.php b/app/Http/Middleware/CheckPermission.php index 698120f..e9ab566 100644 --- a/app/Http/Middleware/CheckPermission.php +++ b/app/Http/Middleware/CheckPermission.php @@ -74,7 +74,7 @@ class CheckPermission // 特殊2 $special2 = [ 'rule', 'search', 'targetMode', 'buildingFloorList', - 'floorList', 'parkingSpaceList', 'statistics' + 'floorList', 'parkingSpaceList', 'statistics', 'parkingTypeColor' ]; if (in_array($method, $special2)) { return false; diff --git a/app/Models/ParkingPatternSpace.php b/app/Models/ParkingPatternSpace.php index 9ee56ba..4db6796 100644 --- a/app/Models/ParkingPatternSpace.php +++ b/app/Models/ParkingPatternSpace.php @@ -16,7 +16,9 @@ class ParkingPatternSpace extends Model = [ 'pattern_id', 'space_id', - 'space_type_id' + 'space_type_id', + 'space_attr_id', + 'auxiliary_space_type' ]; protected $hidden @@ -41,4 +43,9 @@ class ParkingPatternSpace extends Model { return self::query()->where('pattern_id', $pattern_id)->pluck('space_id'); } + + public static function getParkingSpaceTypeIds($pattern_id) + { + return self::query()->where('pattern_id', $pattern_id)->pluck('space_type_id'); + } } diff --git a/app/Models/ParkingSpace.php b/app/Models/ParkingSpace.php index 5fa6f58..1d1d614 100644 --- a/app/Models/ParkingSpace.php +++ b/app/Models/ParkingSpace.php @@ -79,4 +79,20 @@ class ParkingSpace extends Model ['id', 'number'] )->get()->toArray(); } + + public static function getModeFloorCount($floor_id, $spaceIds, $status = '11', $type = '') + { + $model = self::query(); + $model->where('floor_id', $floor_id); + $model->whereIn('id', $spaceIds); + if ($status == '11') { + $model->whereIn('status', [0, 1]); + } else { + $model->where('status', $status); + } + if ($type) { + $model->where('space_type_id', $type); + } + return $model->count(); + } } diff --git a/app/Models/ParkingSpaceTypeAttr.php b/app/Models/ParkingSpaceTypeAttr.php index 914e982..e07a401 100644 --- a/app/Models/ParkingSpaceTypeAttr.php +++ b/app/Models/ParkingSpaceTypeAttr.php @@ -27,4 +27,13 @@ class ParkingSpaceTypeAttr extends Model 'created_at', 'updated_at' ]; + + public static function getSpaceTypeAttrInfo($type_id, $attr_id) + { + $where = [ + 'space_type_id' => $type_id, + 'space_attr_id' => $attr_id + ]; + return self::query()->where($where)->first(); + } } diff --git a/app/Services/EventCalendarService.php b/app/Services/EventCalendarService.php index 69ca5ad..85966b1 100644 --- a/app/Services/EventCalendarService.php +++ b/app/Services/EventCalendarService.php @@ -313,7 +313,7 @@ class EventCalendarService extends BaseService $space_type_id = $item['space_type_id']; (new ParkingSpaceService( $this->logService - ))->syncUpdateSpaceType( + ))->syncUpdateSpaceData( $space_id, $space_type_id, $pattern_id, diff --git a/app/Services/ParkingPatternSpaceService.php b/app/Services/ParkingPatternSpaceService.php index 4dcd7bb..dd1f258 100644 --- a/app/Services/ParkingPatternSpaceService.php +++ b/app/Services/ParkingPatternSpaceService.php @@ -68,7 +68,7 @@ class ParkingPatternSpaceService extends BaseService 'parking_pattern_space.create' ); // 同步更新车位类型 - (new ParkingSpaceService($this->logService))->syncUpdateSpaceType( + (new ParkingSpaceService($this->logService))->syncUpdateSpaceData( $save['space_id'], $save['space_type_id'], $data['pattern_id'] @@ -111,7 +111,7 @@ class ParkingPatternSpaceService extends BaseService 'parking_pattern_space.update' ); // 同步更新车位类型 - (new ParkingSpaceService($this->logService))->syncUpdateSpaceType( + (new ParkingSpaceService($this->logService))->syncUpdateSpaceData( $oldValues['space_id'], $update['space_type_id'], $oldValues['pattern_id'] @@ -138,6 +138,7 @@ class ParkingPatternSpaceService extends BaseService } } + // 切换模式后 将模式的车位 类型,属性, public static function getPatternSpaceTypeData() { $pattern_id = EventCalendarService::getTargetModeId(); diff --git a/app/Services/ParkingSpaceService.php b/app/Services/ParkingSpaceService.php index aea190d..3dd6f69 100644 --- a/app/Services/ParkingSpaceService.php +++ b/app/Services/ParkingSpaceService.php @@ -137,7 +137,13 @@ class ParkingSpaceService extends BaseService ]; $model->update($updateData); - $str = $key == 'space_type_id' ? 'space_type.update' : 'space_attributes.update'; + // 同步更新模式 类型、属性、附属类型 + if ($key == 'space_type_id') { + foreach ($ids as $space_id) { + $tar_mode_id = EventCalendarService::getTargetModeId(); + $this->syncUpdateSpaceData($space_id, $data_id, $tar_mode_id, false); + } + } $newValue = $oldValues; $newValue[$key] = $data_id; @@ -146,7 +152,7 @@ class ParkingSpaceService extends BaseService $this->logService->logUpdatedData( new ParkingSpace(), $oldValues, - $str, + $this->getLogDescription($key), $newValue ); DB::commit(); @@ -157,6 +163,19 @@ class ParkingSpaceService extends BaseService } } + private function getLogDescription($key): string + { + $str = ''; + if ($key == 'space_type_id') { + $str = 'space_type.update'; + } elseif ($key == 'space_attr_id') { + $str = 'space_attributes.update'; + } elseif ($key == 'auxiliary_space_type') { + $str = 'parking_space.auxiliary_space_type'; + } + return $str; + } + /** * @param $data * @return Builder|Model @@ -277,7 +296,7 @@ class ParkingSpaceService extends BaseService * @param bool $is_target_mode // 是否判断是不是当前模式 * @return void */ - public function syncUpdateSpaceType( + public function syncUpdateSpaceData( $id, $type_id, $pattern_id, @@ -302,6 +321,11 @@ class ParkingSpaceService extends BaseService 'updated_at' => get_datetime() ]; $model->update($updateData); - $this->logService->logUpdated($model, $oldValues, 'space_type.update'); + // 记录日志 + $this->logService->logUpdated( + $model, + $oldValues, + $this->getLogDescription('space_type_id') + ); } } diff --git a/database/migrations/2026_03_23_143449_create_parking_space_table.php b/database/migrations/2026_03_23_143449_create_parking_space_table.php index 9f0ba46..9f4bdab 100644 --- a/database/migrations/2026_03_23_143449_create_parking_space_table.php +++ b/database/migrations/2026_03_23_143449_create_parking_space_table.php @@ -23,6 +23,7 @@ return new class extends Migration $table->integer('space_type_id')->comment('车位类型id'); $table->tinyInteger('operation_type')->default(0)->comment('操作类型'); $table->string('pic_url', 255)->nullable()->default('')->comment('车位图片'); + //$table->integer('auxiliary_space_type')->nullable()->comment('附属车位类型'); $table->timestamps(); }); } diff --git a/routes/admin/api.php b/routes/admin/api.php index 434ad05..586b16c 100644 --- a/routes/admin/api.php +++ b/routes/admin/api.php @@ -80,12 +80,15 @@ Route::group(['prefix' => 'admin'], function () { Route::put('/patternSpace/{id}', [ParkingPatternSpaceController::class, 'update']); Route::delete('/patternSpace/{id}', [ParkingPatternSpaceController::class, 'destroy']); Route::get('/patternSpace/rule', [ParkingPatternSpaceController::class, 'rule']); + Route::post('/patternSpace/update', [ParkingPatternSpaceController::class, 'updateType']); // 车位地图 Route::get('/parkingSpaceMap/search', [ParkingSpaceCatMapController::class, 'search']); Route::get('/parkingSpaceMap/floorOverview', [ParkingSpaceCatMapController::class, 'floorOverview']); Route::get('/parkingSpaceMap/map', [ParkingSpaceCatMapController::class, 'map']); Route::get('/parkingSpaceMap/rule', [ParkingSpaceCatMapController::class, 'rule']); + Route::get('/parkingSpaceMap/parkingTypeColor', [ParkingSpaceCatMapController::class, 'parkingTypeColor']); + // 车位预定列表 Route::get('/parkingReservation', [ParkingReservationController::class, 'index']); Route::get('/parkingReservation/search', [ParkingReservationController::class, 'search']);