weizong song 2 weeks ago
parent 5460b39f6c
commit e1e75cc867

@ -22,7 +22,7 @@ ADMIN_SMS_CACHE_STORE=redis
# Empty allows all source IPs; configure office/VPN egress IPs to restrict production access. # Empty allows all source IPs; configure office/VPN egress IPs to restrict production access.
ADMIN_SMS_ALLOWED_IPS= ADMIN_SMS_ALLOWED_IPS=
FILESYSTEM_DISK=local FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync QUEUE_CONNECTION=database
SESSION_DRIVER=file SESSION_DRIVER=file
SESSION_LIFETIME=120 SESSION_LIFETIME=120

@ -11,6 +11,7 @@ use App\Models\User;
use App\Notifications\AppointmentNotify; use App\Notifications\AppointmentNotify;
use App\Repositories\DoorRepository; use App\Repositories\DoorRepository;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel; use Maatwebsite\Excel\Facades\Excel;
@ -365,6 +366,9 @@ class AppointmentController extends BaseController
public function retryAppointment() public function retryAppointment()
{ {
$all = \request()->all(); $all = \request()->all();
$traceId = substr((string) request()->header('X-Retry-Trace-Id', ''), 0, 100) ?: uniqid('retry-', true);
$startedAt = microtime(true);
Log::info('appointment.retry.received', ['trace_id' => $traceId, 'appointment_id' => $all['id'] ?? null]);
$messages = [ $messages = [
'id.required' => 'Id必填', 'id.required' => 'Id必填',
]; ];
@ -376,27 +380,44 @@ class AppointmentController extends BaseController
} }
$model = $this->model->find($all['id']); $model = $this->model->find($all['id']);
if (empty($model)) { if (empty($model)) {
Log::warning('appointment.retry.not_found', ['trace_id' => $traceId, 'appointment_id' => $all['id']]);
return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']); return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']);
} }
$model = $this->model->find($all['id']);
$appointmentConfig = $model->site_detail; $appointmentConfig = $model->site_detail;
Log::info('appointment.retry.loaded', [
'trace_id' => $traceId,
'appointment_id' => $model->id,
'status' => $model->status,
'site_ids' => $model->site,
'config_count' => $appointmentConfig->count(),
'queue_connection' => config('queue.default'),
]);
// 执行预约 // 执行预约
if ($model->status == 1 || $model->status == 4) { if ($model->status == 1 || $model->status == 4) {
$doors = $appointmentConfig->pluck('door')->filter(); $doors = $appointmentConfig->pluck('door')->filter();
if ($doors->isNotEmpty()) { if ($doors->isNotEmpty()) {
Log::info('appointment.retry.door_check.begin', ['trace_id' => $traceId, 'appointment_id' => $model->id]);
$result = (new DoorRepository)->checkRepeatDoor($model->mobile, $appointmentConfig, $model->end_time, $out); $result = (new DoorRepository)->checkRepeatDoor($model->mobile, $appointmentConfig, $model->end_time, $out);
if (!$result) { if (!$result) {
Log::warning('appointment.retry.door_check.rejected', ['trace_id' => $traceId, 'appointment_id' => $model->id, 'reason' => $out]);
return $this->fail([ResponseCode::ERROR_BUSINESS, $out]); return $this->fail([ResponseCode::ERROR_BUSINESS, $out]);
} }
Log::info('appointment.retry.door_check.completed', ['trace_id' => $traceId, 'appointment_id' => $model->id]);
} }
// 发送预约 // 发送预约
dispatch((new SendAppoint($model, $appointmentConfig))); Log::info('appointment.retry.dispatch.begin', ['trace_id' => $traceId, 'appointment_id' => $model->id]);
dispatch((new SendAppoint($model, $appointmentConfig, $traceId)));
Log::info('appointment.retry.dispatch.completed', [
'trace_id' => $traceId,
'appointment_id' => $model->id,
'elapsed_ms' => (int) ((microtime(true) - $startedAt) * 1000),
]);
} }
// 取消预约 // 取消预约
if (($model->status == 3)) { if (($model->status == 3)) {
Appointment::sendCancelAppoin($model); Appointment::sendCancelAppoin($model);
} }
return $this->success('成功'); return $this->success(['message' => '已提交重新预约', 'trace_id' => $traceId]);
} }
} }

@ -16,6 +16,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Log;
class SendAppoint implements ShouldQueue class SendAppoint implements ShouldQueue
{ {
@ -26,16 +27,18 @@ class SendAppoint implements ShouldQueue
public $appointmentModel; public $appointmentModel;
public $appointmentConfig; public $appointmentConfig;
public $traceId;
/** /**
* Create a new job instance. * Create a new job instance.
* *
* @return void * @return void
*/ */
public function __construct($appointmentModel, $AppointmentConfig) public function __construct($appointmentModel, $AppointmentConfig, $traceId = null)
{ {
$this->appointmentModel = $appointmentModel; $this->appointmentModel = $appointmentModel;
$this->appointmentConfig = $AppointmentConfig; $this->appointmentConfig = $AppointmentConfig;
$this->traceId = $traceId ?: uniqid('appointment-job-', true);
} }
/** /**
@ -45,20 +48,35 @@ class SendAppoint implements ShouldQueue
*/ */
public function handle() public function handle()
{ {
// 预约车牌(有成功的就不会再次预约) $startedAt = microtime(true);
$carResult = Appointment::sendAppoinCar($this->appointmentModel); $context = ['trace_id' => $this->traceId, 'appointment_id' => $this->appointmentModel->id];
// 预约会议室(有成功的就不会再次预约) Log::info('appointment.retry.job.started', $context);
$meetResult = (new Appointment())->appointMeet($this->appointmentModel, $this->appointmentConfig); try {
// 预约门禁(每个学员一定会预约门禁) Log::info('appointment.retry.car.begin', $context);
$doorResult = (new Appointment())->appointDoor($this->appointmentModel, $this->appointmentConfig); $carResult = Appointment::sendAppoinCar($this->appointmentModel);
if ($doorResult) { Log::info('appointment.retry.car.completed', $context + ['result' => $carResult]);
// 门禁预约成功
$this->appointmentModel->status = 1; Log::info('appointment.retry.meet.begin', $context);
} else { $meetResult = (new Appointment())->appointMeet($this->appointmentModel, $this->appointmentConfig);
// 预约失败 Log::info('appointment.retry.meet.completed', $context + ['result' => $meetResult]);
$this->appointmentModel->status = 4;
Log::info('appointment.retry.door.begin', $context);
$doorResult = (new Appointment())->appointDoor($this->appointmentModel, $this->appointmentConfig);
Log::info('appointment.retry.door.completed', $context + ['result' => $doorResult]);
$this->appointmentModel->status = $doorResult ? 1 : 4;
$this->appointmentModel->save();
Log::info('appointment.retry.job.completed', $context + [
'status' => $this->appointmentModel->status,
'elapsed_ms' => (int) ((microtime(true) - $startedAt) * 1000),
]);
} catch (\Throwable $exception) {
Log::error('appointment.retry.job.failed', $context + [
'elapsed_ms' => (int) ((microtime(true) - $startedAt) * 1000),
'exception' => $exception,
]);
throw $exception;
} }
$this->appointmentModel->save();
// 预约门禁 // 预约门禁
// $result = (new Appointment())->appointDoor($this->appointmentModel, $this->appointmentConfig); // $result = (new Appointment())->appointDoor($this->appointmentModel, $this->appointmentConfig);

@ -428,6 +428,10 @@ class DoorRepository
{ {
foreach ($appointmentConfig as $value) { foreach ($appointmentConfig as $value) {
$door = is_array($value->door) ? $value->door : json_decode($value->door, true); $door = is_array($value->door) ? $value->door : json_decode($value->door, true);
if (!is_array($door) || empty($door['doorName'])) {
$out = "场地【{$value->name}】的门禁配置无效";
return false;
}
$lastThirdAppointmentLogs = ThirdAppointmentLog::where('url', 'like', '%GenerateEmpAuthorSet1%') $lastThirdAppointmentLogs = ThirdAppointmentLog::where('url', 'like', '%GenerateEmpAuthorSet1%')
->whereHas('appointment', function ($query) { ->whereHas('appointment', function ($query) {
$query->where('status', 1); $query->where('status', 1);

@ -0,0 +1,32 @@
<?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()
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue')->index();
$table->longText('payload');
$table->unsignedTinyInteger('attempts');
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::dropIfExists('jobs');
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save