Browse Source

新增车位导入、下载车位模板

master
wanghongjun 4 days ago
parent
commit
308eb04b0a
  1. 31
      app/Exports/ParkingSpaceTemplateExport.php
  2. 67
      app/Http/Controllers/Admin/ParkingSpaceController.php
  3. 97
      app/Imports/ParkingSpaceImport.php
  4. 4
      database/seeders/AdminMenuSeeder.php
  5. 2
      resources/lang/en/exports.php
  6. 2
      resources/lang/zh-CN/exports.php
  7. 2
      resources/lang/zh-TW/exports.php
  8. 2
      routes/admin/api.php

31
app/Exports/ParkingSpaceTemplateExport.php

@ -0,0 +1,31 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
class ParkingSpaceTemplateExport implements FromArray
{
public function array(): array
{
return [
[
__exports('global.index'),
__exports('whitelist.parking'),
__exports('parking_space.floor'),
__exports('parking_space.region'),
__exports('parking_space.space_attr'),
__exports('parking_space.number')
],
[
'1',
'MSCP',
'L1',
'A',
'YUC',
'L1-0001'
]
];
}
}

67
app/Http/Controllers/Admin/ParkingSpaceController.php

@ -4,6 +4,8 @@ namespace App\Http\Controllers\Admin;
use App\Exceptions\CustomException; use App\Exceptions\CustomException;
use App\Exports\ParkingSpaceExport; use App\Exports\ParkingSpaceExport;
use App\Exports\ParkingSpaceTemplateExport;
use App\Imports\ParkingSpaceImport;
use App\Models\AdminFloor; use App\Models\AdminFloor;
use App\Models\AdminFloorRegion; use App\Models\AdminFloorRegion;
use App\Models\Parking; use App\Models\Parking;
@ -19,6 +21,7 @@ use App\Services\ParkingSpaceService;
use Exception; use Exception;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel; use Maatwebsite\Excel\Facades\Excel;
@ -571,4 +574,68 @@ class ParkingSpaceController extends BaseController
); );
} }
} }
/**
* @return BinaryFileResponse
*/
public function importTemplate(): BinaryFileResponse
{
return Excel::download(
new ParkingSpaceTemplateExport(),
set_space_underline(__('exports.parking_space.list_export'))
. get_datetime('date_')
. '.xlsx'
);
}
/**
* 创建导入
* @param Request $request
* @return JsonResponse
* @throws ValidationException
*/
public function import(Request $request): JsonResponse
{
try {
// 1. 验证上传的文件
$data = $request->all();
$validator = Validator::make($data, [
'file' => 'required|mimes:xlsx,xls,csv,txt|max:2048'
], [
'file.required' => __('validation.admin_list_vip.file_empty'),
'file.mimes' => __('validation.admin_list_vip.file_mimes'),
'file.max' => __('validation.admin_list_vip.file_max')
]);
if ($validator->fails()) {
throw new ValidationException($validator);
}
// 2. 获取上传的文件
$file = $request->file('file');
// 3. 正确的做法:先存储文件,再获取绝对路径进行导入
$path = $file->store('imports');
// 4. 执行导入(使用存储后的绝对路径)
// storage_path('app') 获取 storage/app 的绝对路径
Excel::import(
new ParkingSpaceImport($this->adminUserId),
storage_path('app/' . $path)
);
// 5. (可选)导入完成后删除临时文件
Storage::delete($path);
return $this->responseService->success(
__('controller.import.success')
);
} catch (ValidationException $e) {
throw $e;
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.admin_vip_list.import_failed') . ':'
. $e->getMessage()
);
}
}
} }

97
app/Imports/ParkingSpaceImport.php

@ -0,0 +1,97 @@
<?php
namespace App\Imports;
use App\Models\AdminFloor;
use App\Models\AdminFloorRegion;
use App\Models\Parking;
use App\Models\ParkingSpace;
use App\Models\ParkingSpaceAttributes;
use App\Models\ParkingSpaceType;
use App\Services\OperationLogService;
use App\Services\ParkingSpaceService;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithChunkReading;
class ParkingSpaceImport implements ToModel, WithChunkReading
{
protected int $index = 1;
protected int $user_id;
public function __construct($admin_user_id)
{
$this->user_id = $admin_user_id;
}
public function model(array $row)
{
if ($this->index == 1) {
$this->index += 1;
return;
}
$parking = $row[1];
$floor = $row[2];
$region = $row[3];
$attr = $row[4];
$number = $row[5];
if (empty($parking)) {
return;
}
if (empty($floor)) {
return;
}
if (empty($region)) {
return;
}
if (empty($attr)) {
return;
}
if (empty($number)) {
return;
}
$parking_id = Parking::getValueId($parking);
if (!$parking_id) {
return;
}
$floor_id = AdminFloor::query()->where('status', 1)->where(
'building_floor',
$parking_id
)->value('id');
if (!$floor_id) {
return;
}
$region_id = AdminFloorRegion::query()->where('status', 1)->where(
'floor_id',
$floor_id
)->value('id');
$attr_id = ParkingSpaceAttributes::query()->where('attributes', $attr)
->value('id');
if (!$attr_id) {
return;
}
$create = $where = [
'number' => $number,
'floor_id' => $floor_id,
'region_id' => $region_id
];
if (ParkingSpace::query()->where($where)->exists()) {
return;
}
$create['space_type_id'] = 0;
$res = ParkingSpaceType::getDefaultData();
if ($res) {
$create['space_type_id'] = $res['id'];
}
$create['space_attr_id'] = $attr_id;
$service = new ParkingSpaceService(new OperationLogService());
$service->createData($create);
}
public function chunkSize(): int
{
return 1000; // 设置每次处理的行数,有助于避免内存问题并可能改善表头解析
}
}

4
database/seeders/AdminMenuSeeder.php

@ -512,7 +512,9 @@ class AdminMenuSeeder extends Seeder
'edit' => 'parkingSpaceManagement.update', 'edit' => 'parkingSpaceManagement.update',
'delete' => 'parkingSpaceManagement.destroy', 'delete' => 'parkingSpaceManagement.destroy',
'batch_update_attr' => 'parkingSpaceManagement.batchUpdateAttr', 'batch_update_attr' => 'parkingSpaceManagement.batchUpdateAttr',
'batch_delete' => 'parkingSpaceManagement.batchDelete' 'batch_delete' => 'parkingSpaceManagement.batchDelete',
'batch_import' => 'parkingSpaceManagement.batchImport',
'download_template' => 'parkingSpaceManagement.downloadTemplate'
] ]
], ],
], ],

2
resources/lang/en/exports.php

@ -25,6 +25,8 @@ return [
'space_type' => 'Parking space type', 'space_type' => 'Parking space type',
'operation_type' => 'Operation Type', 'operation_type' => 'Operation Type',
'updated_at' => 'Last update time', 'updated_at' => 'Last update time',
'region' => 'region',
'list_export' => 'Import parking spaces',
], ],
'parking_camera' => [ 'parking_camera' => [
'list' => 'Parking camera', 'list' => 'Parking camera',

2
resources/lang/zh-CN/exports.php

@ -25,6 +25,8 @@ return [
'space_type' => '车位类型', 'space_type' => '车位类型',
'operation_type' => '操作类型', 'operation_type' => '操作类型',
'updated_at' => '最后更新时间', 'updated_at' => '最后更新时间',
'region' => '区域',
'list_export' => '导入车位',
], ],
'parking_camera' => [ 'parking_camera' => [
'list' => '车位相机', 'list' => '车位相机',

2
resources/lang/zh-TW/exports.php

@ -25,6 +25,8 @@ return [
'space_type' => '車位類型', 'space_type' => '車位類型',
'operation_type' => '操作類型', 'operation_type' => '操作類型',
'updated_at' => '最後更新時間', 'updated_at' => '最後更新時間',
'region' => '區域',
'list_export' => '導入車位',
], ],
'parking_camera' => [ 'parking_camera' => [
'list' => '車位相機', 'list' => '車位相機',

2
routes/admin/api.php

@ -128,6 +128,7 @@ Route::group(['prefix' => 'admin'], function () {
Route::delete('/parkingSpaceManagement/{id}', [ParkingSpaceController::class, 'destroy']); Route::delete('/parkingSpaceManagement/{id}', [ParkingSpaceController::class, 'destroy']);
Route::post('/parkingSpaceManagement/batchDelete', [ParkingSpaceController::class, 'batchDelete']); Route::post('/parkingSpaceManagement/batchDelete', [ParkingSpaceController::class, 'batchDelete']);
Route::post('/parkingSpaceManagement/batchUpdateAttr', [ParkingSpaceController::class, 'updateAttr']); Route::post('/parkingSpaceManagement/batchUpdateAttr', [ParkingSpaceController::class, 'updateAttr']);
Route::post('/parkingSpaceManagement/batchImport', [ParkingSpaceController::class, 'import']);
//车位类型管理 //车位类型管理
Route::get('/spaceType', [ParkingSpaceTypeController::class, 'index']); Route::get('/spaceType', [ParkingSpaceTypeController::class, 'index']);
Route::get('/spaceType/create', [ParkingSpaceTypeController::class, 'create']); Route::get('/spaceType/create', [ParkingSpaceTypeController::class, 'create']);
@ -375,4 +376,5 @@ Route::group(['prefix' => 'admin'], function () {
Route::get('/whitelist/downloadTemplate', [ParkingWhitelistController::class, 'downloadTemplate']); Route::get('/whitelist/downloadTemplate', [ParkingWhitelistController::class, 'downloadTemplate']);
Route::get('/whitelist/export', [ParkingWhitelistController::class, 'export']); Route::get('/whitelist/export', [ParkingWhitelistController::class, 'export']);
Route::get('/parkingRepair/downloadTemplate', [ParkingSpaceRepairController::class, 'downloadTemplate']); Route::get('/parkingRepair/downloadTemplate', [ParkingSpaceRepairController::class, 'downloadTemplate']);
Route::get('/parkingSpaceManagement/downloadTemplate', [ParkingSpaceController::class, 'importTemplate']);
}); });

Loading…
Cancel
Save