元禾参与/干部培训 导入

master
lion 2 days ago
commit 5c13b44ad8

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

@ -41,8 +41,6 @@ class Kernel extends ConsoleKernel
// $schedule->command('update_company')->everyFiveMinutes();
// 全量同步公司信息(每天凌晨执行,不同步经纬度和地址)
// $schedule->command('sync:company')->dailyAt('02:00');
// 同步老师课程方向
$schedule->command('sync:teacher_direction')->hourly();
}
/**

@ -11,6 +11,7 @@ use App\Models\User;
use App\Notifications\AppointmentNotify;
use App\Repositories\DoorRepository;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
@ -365,6 +366,9 @@ class AppointmentController extends BaseController
public function retryAppointment()
{
$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 = [
'id.required' => 'Id必填',
];
@ -376,27 +380,44 @@ class AppointmentController extends BaseController
}
$model = $this->model->find($all['id']);
if (empty($model)) {
Log::warning('appointment.retry.not_found', ['trace_id' => $traceId, 'appointment_id' => $all['id']]);
return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']);
}
$model = $this->model->find($all['id']);
$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) {
$doors = $appointmentConfig->pluck('door')->filter();
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);
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]);
}
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)) {
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\SerializesModels;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Log;
class SendAppoint implements ShouldQueue
{
@ -26,16 +27,18 @@ class SendAppoint implements ShouldQueue
public $appointmentModel;
public $appointmentConfig;
public $traceId;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($appointmentModel, $AppointmentConfig)
public function __construct($appointmentModel, $AppointmentConfig, $traceId = null)
{
$this->appointmentModel = $appointmentModel;
$this->appointmentConfig = $AppointmentConfig;
$this->traceId = $traceId ?: uniqid('appointment-job-', true);
}
/**
@ -45,20 +48,35 @@ class SendAppoint implements ShouldQueue
*/
public function handle()
{
// 预约车牌(有成功的就不会再次预约)
$carResult = Appointment::sendAppoinCar($this->appointmentModel);
// 预约会议室(有成功的就不会再次预约)
$meetResult = (new Appointment())->appointMeet($this->appointmentModel, $this->appointmentConfig);
// 预约门禁(每个学员一定会预约门禁)
$doorResult = (new Appointment())->appointDoor($this->appointmentModel, $this->appointmentConfig);
if ($doorResult) {
// 门禁预约成功
$this->appointmentModel->status = 1;
} else {
// 预约失败
$this->appointmentModel->status = 4;
$startedAt = microtime(true);
$context = ['trace_id' => $this->traceId, 'appointment_id' => $this->appointmentModel->id];
Log::info('appointment.retry.job.started', $context);
try {
Log::info('appointment.retry.car.begin', $context);
$carResult = Appointment::sendAppoinCar($this->appointmentModel);
Log::info('appointment.retry.car.completed', $context + ['result' => $carResult]);
Log::info('appointment.retry.meet.begin', $context);
$meetResult = (new Appointment())->appointMeet($this->appointmentModel, $this->appointmentConfig);
Log::info('appointment.retry.meet.completed', $context + ['result' => $meetResult]);
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);

@ -427,7 +427,16 @@ class DoorRepository
public function checkRepeatDoor($mobile, $appointmentConfig, $end_time, &$out)
{
foreach ($appointmentConfig as $value) {
// 车牌等场地不需要门禁,未配置门禁时无需做重复授权校验。
if (empty($value->door)) {
continue;
}
$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%')
->whereHas('appointment', function ($query) {
$query->where('status', 1);

@ -0,0 +1,37 @@
<?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()
{
if (Schema::hasTable('jobs')) {
return;
}
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()
{
// The production database may already have this table from an older,
// untracked migration. Do not remove an existing queue table on rollback.
}
};

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

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