Browse Source

活动行事历2

master
wanghongjun 1 month ago
parent
commit
584366b252
  1. 30
      app/Exports/EventCalendarTemplateExport.php
  2. 417
      app/Http/Controllers/Admin/EventCalendarController.php
  3. 80
      app/Imports/EventCalendarImport.php
  4. 40
      app/Models/EventCalendar.php
  5. 261
      app/Services/EventCalendarService.php
  6. 35
      database/migrations/2026_04_23_143449_create_event_calendar_table.php

30
app/Exports/EventCalendarTemplateExport.php

@ -0,0 +1,30 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
class EventCalendarTemplateExport implements FromArray
{
public function array(): array
{
return [
[
'No.',
'Mode Name',
'Start Date',
'Start Time',
'End Date',
'End Time'
],
[
'1',
'Raceday - Major Raceday',
' 2026-10-01',
'10:30:00',
' 2026-10-01',
'18:30:00'
]
];
}
}

417
app/Http/Controllers/Admin/EventCalendarController.php

@ -0,0 +1,417 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Exceptions\CustomException;
use App\Exports\EventCalendarTemplateExport;
use App\Imports\EventCalendarImport;
use App\Models\AdminUsers;
use App\Models\EventCalendar;
use App\Models\ParkingPattern;
use App\Services\ApiResponseService;
use App\Services\EventCalendarService;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;
use Psr\SimpleCache\InvalidArgumentException;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class EventCalendarController extends BaseController
{
protected EventCalendarService $service;
/**
* 构造函数
* @param ApiResponseService $responseService
* @param EventCalendarService $service
*/
public function __construct(
ApiResponseService $responseService,
EventCalendarService $service
) {
parent::__construct($responseService);
$this->service = $service;
}
public function index(Request $request): JsonResponse
{
try {
$query = EventCalendar::query();
if ($request->has('pattern_id')) {
$pattern_id = $request->input('pattern_id');
if ($pattern_id) {
$query->where('pattern_id', $pattern_id);
}
}
if ($request->has('status')) {
$status = $request->input('status');
if ($status) {
$query->where('status', $status);
}
}
if ($request->has('start_time')) {
$start_time = $request->input('start_time');
if ($start_time && strtotime($start_time)) {
$query->where('start_time', '>=', $start_time);
}
}
if ($request->has('end_time')) {
$end_time = $request->input('end_time');
if ($end_time && strtotime($end_time)) {
$query->where('end_time', '<=', $end_time);
}
}
// 分页
$page = $request->input('page', 1);
$perPage = $request->input('per_page', 10);
$total = $query->count();
$statusArr = EventCalendarService::getStatus();
$items = $query->latest()->forPage($page, $perPage)->select()
->get()->each(function ($item) use ($statusArr) {
$item['pattern_name'] = ParkingPattern::getName(
$item['pattern_id']
);
$item['admin_username'] = AdminUsers::getUsername(
$item['admin_user_id']
);
$item['status'] = $statusArr[$item['status']] ?? '';
$item['remake'] = '';
unset($item['pattern_id'], $item['admin_user_id']);
return $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 search(): JsonResponse
{
try {
$data = [
'pattern_list' => ParkingPattern::getData(),
'status_list' => get_select_data(
EventCalendarService::getStatus()
)
];
return $this->responseService->success($data);
} catch (Exception $e) {
$m_prefix = __('exception.exception_handler.resource');
return $this->responseService->systemError(
$m_prefix . ':' . $e->getMessage()
);
}
}
public function create(): JsonResponse
{
try {
$data = [
'pattern_list' => ParkingPattern::getData()
];
return $this->responseService->success($data);
} catch (Exception $e) {
$m_prefix = __('exception.exception_handler.resource');
return $this->responseService->systemError(
$m_prefix . ':' . $e->getMessage()
);
}
}
public function changeMode(Request $request): JsonResponse
{
try {
$data = $request->all();
$this->saveValidator($data, 0, true);
$this->service->changeModel($data, $this->adminUserId);
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()
);
}
}
/**
* @param Request $request
* @return JsonResponse
* @throws CustomException
* @throws ValidationException
*/
public function store(Request $request): JsonResponse
{
try {
$this->saveValidator($request->all());
$this->service->createModel($request->all(), $this->adminUserId);
return $this->responseService->success(
null,
__('admin.save_succeeded')
);
} catch (ValidationException|CustomException $e) {
throw $e;
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.event_calendar.create_failed') . ':'
. $e->getMessage()
);
}
}
/**
* @param array $data
* @param int $id
* @return void
* @throws ValidationException
*/
protected function saveValidator(array $data, int $id = 0, $is = false): void
{
$rules = [
'pattern_id' => 'required',
'start_time' => 'required',
'end_time' => 'required'
];
$messages = [
'pattern_id.required' => __(
'validation.event_calendar.p_empty'
),
'start_time.required' => __(
'validation.event_calendar.s_empty'
),
'end_time.required' => __(
'validation.event_calendar.e_empty'
)
];
if ($id) {
$this->validateId($id, EventCalendar::class);
}
if ($is) {
unset($rules['start_time'], $messages['start_time.required']);
}
$validator = Validator::make($data, $rules, $messages);
if ($validator->fails()) {
throw new ValidationException($validator);
}
}
public function edit($id): JsonResponse
{
try {
$this->validateId($id, EventCalendar::class);
$item = EventCalendar::query()->findOrFail($id);
$data = [
'pattern_list' => ParkingPattern::getData()
];
$data['item'] = $item;
$statusArr = $item['status'] == 0 ? EventCalendarService::getStatus(
2
) : EventCalendarService::getStatus();
$data['status_list'] = get_select_data($statusArr);
unset($item['admin_user_id']);
return $this->responseService->success($data);
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.get_data_failed') . ':' . $e->getMessage()
);
}
}
/**
* @param Request $request
* @param string $id
* @return JsonResponse
* @throws CustomException
* @throws ValidationException
*/
public function update(Request $request, string $id): JsonResponse
{
try {
$data = $request->all();
$this->saveValidator($data, $id);
$data['admin_user_id'] = $this->adminUserId;
$this->service->updateModel($data, $id);
return $this->responseService->success(
null,
__('admin.update_succeeded')
);
} catch (ValidationException|CustomException $e) {
throw $e;
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.event_calendar.update_failed') . ':'
. $e->getMessage()
);
}
}
/**
* @param string $id
* @return JsonResponse
* @throws ValidationException
*/
public function destroy(string $id): JsonResponse
{
try {
$this->validateId($id, EventCalendar::class);
$this->service->deleteModel($id);
return $this->responseService->success(
null,
__('admin.delete_succeeded')
);
} catch (ValidationException $e) {
throw $e;
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.event_calendar.destroy_failed') . ':'
. $e->getMessage()
);
}
}
/**
* @param string $id
* @return JsonResponse
* @throws ValidationException
*/
public function end(string $id): JsonResponse
{
try {
$this->validateId($id, EventCalendar::class);
$this->service->endModel($id);
return $this->responseService->success(
null,
__('exception.event_calendar.end_succeeded')
);
} catch (ValidationException $e) {
throw $e;
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.event_calendar.end_failed') . ':'
. $e->getMessage()
);
}
}
/**
* @return BinaryFileResponse
*/
public function importTemplate(): BinaryFileResponse
{
return Excel::download(
new EventCalendarTemplateExport(),
__('exports.event_calendar.list') . time() . '.xlsx'
);
}
/**
* 创建导入
* @param Request $request
* @return JsonResponse
* @throws ValidationException
*/
public function import(Request $request): JsonResponse
{
try {
// 1. 验证上传的文件
$data = $request->all();
$request->validate([
'file' => 'required|mimes:xlsx,xls,csv|max:2048'
]);
$validator = Validator::make($data, [
'file' => 'required|mimes:xlsx,xls,csv|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 EventCalendarImport($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()
);
}
}
/**
* @return JsonResponse
* @throws InvalidArgumentException
*/
public function rule(): JsonResponse
{
try {
return $this->responseService->success(
$this->methodShow('eventCalendar', ['import'])
);
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.get_data_failed') . ':' . $e->getMessage()
);
}
}
public function targetMode()
{
try {
$data = [
'model' => EventCalendarService::targetModel()
];
return $this->responseService->success($data);
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.get_data_failed') . ':' . $e->getMessage()
);
}
}
}

80
app/Imports/EventCalendarImport.php

@ -0,0 +1,80 @@
<?php
namespace App\Imports;
use App\Models\EventCalendar;
use App\Models\ParkingPattern;
use App\Services\OperationLogService;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class EventCalendarImport implements ToModel, WithHeadingRow
{
protected string $user_id;
protected OperationLogService $logService;
public function __construct(string $user_id)
{
$this->user_id = $user_id;
$this->logService = new OperationLogService();
$this->logService->menuTitle = 'event_calendar';
}
/**
* @param array $row
* @return false|void
*/
public function model(array $row)
{
$pattern_name = $row['mode_name'];
$start_date = $row['start_date'];
$start_time = $row['start_time'];
$end_date = $row['end_date'];
$end_time = $row['end_time'];
if (empty($pattern_name)) {
return false;
}
$pattern_id = ParkingPattern::getId($pattern_name);
if (EventCalendar::query()->whereIn('status', [0, 1])->where(
'pattern_id',
$pattern_id
)
->exists()
) {
return false;
}
$start_date_times = strtotime($start_date);
$start_times = strtotime($start_time);
$end_date_times = strtotime($end_date);
$end_times = strtotime($end_time);
if (!$start_date_times) {
return false;
}
if (!$start_times) {
return false;
}
if (!$end_date_times) {
return false;
}
if (!$end_times) {
return false;
}
$start_date = date("Y-m-d", $start_date_times);
$start_time = date("H:i:s", $start_times);
$end_date_time = date("Y-m-d", $end_date_times);
$end_time = date("H:i:s", $end_times);
$create = [
'pattern_id' => $pattern_id,
'admin_user_id' => $this->user_id,
'start_time' => $start_date . ' ' . $start_time,
'end_time' => $end_date_time . ' ' . $end_time,
'status' => 0,
'created_at' => get_datetime()
];
$model = EventCalendar::query()->create($create);
$this->logService->logCreated($model, 'event_calendar.import');
}
}

40
app/Models/EventCalendar.php

@ -0,0 +1,40 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class EventCalendar extends Model
{
use HasFactory, SoftDeletes;
protected $table = 'event_calendar';
protected $fillable
= [
'pattern_id',
'start_time',
'end_time',
'admin_user_id',
'status'
];
protected $hidden
= [
'created_at',
'updated_at',
'deleted_at'
];
public function getStartTimeAttribute($value): string
{
return get_datetime('date_time', strtotime($value));
}
public function getEndTimeAttribute($value): string
{
return get_datetime('date_time', strtotime($value));
}
}

261
app/Services/EventCalendarService.php

@ -0,0 +1,261 @@
<?php
namespace App\Services;
use App\Exceptions\CustomException;
use App\Models\EventCalendar;
use App\Models\ParkingPattern;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class EventCalendarService extends BaseService
{
private static array $statusArr
= [
'planned',
'running',
'ended',
'disabled'
];
public function __construct(OperationLogService $logService)
{
parent::__construct($logService);
$this->logService->menuTitle = 'event_calendar';
}
/**
* @return array|string[]
*/
public static function getStatus($type = 1): array
{
$statusArr = self::$statusArr;
foreach ($statusArr as $key => $value) {
$statusArr[$key] = __('service.event_calendar.' . $value);
}
if ($type == 2) {
unset($statusArr[1], $statusArr[2]);
}
return $statusArr;
}
/**
* @param array $data
* @param $user_id
* @return Builder|Model
* @throws Exception
*/
public function createModel(array $data, $user_id): Builder|Model
{
try {
DB::beginTransaction();
if (EventCalendar::query()->whereIn('status', [0, 1])->where(
'pattern_id',
$data['pattern_id']
)
->exists()
) {
throw new Exception(
__('service.event_calendar.pattern_exists')
);
}
$start_time = get_datetime(
'datetime',
strtotime($data['start_time'])
);
$end_time = get_datetime('datetime', strtotime($data['end_time']));
$model = EventCalendar::query()->create([
'pattern_id' => $data['pattern_id'],
'start_time' => $start_time,
'end_time' => $end_time,
'admin_user_id' => $user_id,
'status' => 0,
'created_at' => get_datetime()
]);
$this->logService->logCreated($model, 'event_calendar.create');
DB::commit();
return $model;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
/**
* @param array $data
* @param string $id
* @throws Exception
*/
public function updateModel(array $data, string $id)
{
try {
DB::beginTransaction();
$existsWhere = [
['pattern_id', '=', $data['pattern_id']],
['status', 'in', [0, 1]],
['id', '<>', $id]
];
if (EventCalendar::query()->where($existsWhere)->exists()) {
throw new Exception(
__('service.event_calendar.pattern_exists')
);
}
$model = EventCalendar::query()->findOrFail($id);
$oldValues = $model->toArray();
$end_time = get_datetime('datetime', strtotime($data['end_time']));
$update = [
'pattern_id' => $data['pattern_id'],
'end_time' => $end_time,
'admin_user_id' => $data['admin_user_id'],
'updated_at' => get_datetime()
];
if ($oldValues['status'] == 0) {
if (isset($data['start_time'])
&& strtotime(
$data['start_time']
)
) {
$update['start_time'] = get_datetime(
'datetime',
strtotime($data['start_time'])
);
}
if (isset($data['status'])
&& in_array($data['status'], [0, 3])
) {
$update['status'] = $data['status'];
}
}
$model->update($update);
$this->logService->logUpdated(
$model,
$oldValues,
'event_calendar.update'
);
DB::commit();
return $model;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
public function deleteModel(int $id): bool
{
try {
DB::beginTransaction();
$model = EventCalendar::query()->findOrFail($id);
if ($model['status'] > 0) {
throw new Exception(__('service.event_calendar.error_status'));
}
$this->logService->logDeleted($model, 'event_calendar.delete');
$model->delete();
DB::commit();
return true;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
public function endModel(int $id): bool
{
try {
DB::beginTransaction();
$model = EventCalendar::query()->findOrFail($id);
$oldValues = $model->toArray();
if ($model['status'] != 1) {
throw new Exception(__('service.event_calendar.error_end'));
}
$update = [
'status' => 2,
'updated_at' => get_datetime()
];
$model->update($update);
$this->logService->logUpdated(
$model,
$oldValues,
'event_calendar.update'
);
DB::commit();
return true;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
public function changeModel($data, $user_id)
{
try {
DB::beginTransaction();
$pattern_id = $data['pattern_id'];
$end_time = $data['end_time'];
$where = [
'pattern_id' => $pattern_id,
'status' => 1
];
$query = EventCalendar::query()->where($where)->first();
$save = [
'pattern_id' => $pattern_id,
'start_time' => get_datetime(),
'end_time' => get_datetime('datetime', strtotime($end_time)),
'status' => 1,
'admin_user_id' => $user_id
];
if ($query) {
$save['updated_at'] = get_datetime();
$model = EventCalendar::query()->findOrFail($query['id']);
$oldValues = $model->toArray();
$model->update($save);
$this->logService->logUpdated(
$model,
$oldValues,
'event_calendar.update'
);
} else {
$save['created_at'] = get_datetime();
$model = EventCalendar::query()->create($save);
$this->logService->logCreated($model, 'event_calendar.create');
}
DB::commit();
return $model;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
public static function targetModel()
{
$pattern_id = EventCalendar::query()->where('status', 1)->first(['pattern_id']);
$columns = ['id as pattern_id', 'name as model_name'];
if ($pattern_id) {
$data = ParkingPattern::query()->findOrFail($pattern_id, $columns)->toArray();
} else {
$data = ParkingPattern::query()->where('is_default', 1)->first($columns);
}
return $data;
}
}

35
database/migrations/2026_04_23_143449_create_event_calendar_table.php

@ -0,0 +1,35 @@
<?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('event_calendar', function (Blueprint $table) {
$table->id();
$table->integer('pattern_id')->comment('模式id');
$table->timestamp('start_time')->comment('开始时间');
$table->timestamp('end_time')->comment('结束时间');
$table->integer('admin_user_id')->comment('操作员');
$table->tinyInteger('status')->default(0)->comment('状态 0计划中 1运行中 2已结束 3已停用');
$table->timestamps();
$table->softDeletes();
$table->innoDb();
$table->comment('模式管理车位');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('event_calendar');
}
};
Loading…
Cancel
Save