- 定期契約データを psectionusertypemonths で統合 - 新規/更新 減免/通常 を1レコードに集約 - Operator Queue に park_id と operator_id を正確に設定 - SQL に contract_money の SUM を追加
252 lines
6.6 KiB
PHP
252 lines
6.6 KiB
PHP
<?php
|
||
|
||
namespace App\Models;
|
||
|
||
use Illuminate\Database\Eloquent\Model;
|
||
use Carbon\Carbon;
|
||
|
||
/**
|
||
* プリンタジョブログモデル - print_job_logテーブル
|
||
*
|
||
* プリンタ制御プログラムの実行ログを管理
|
||
*/
|
||
class PrintJobLog extends Model
|
||
{
|
||
/**
|
||
* テーブル名
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $table = 'print_job_log';
|
||
|
||
/**
|
||
* プライマリキー
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $primaryKey = 'job_log_id';
|
||
|
||
/**
|
||
* 一括代入可能な属性
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $fillable = [
|
||
'park_id', // 駐輪場ID
|
||
'user_id', // ユーザーID
|
||
'contract_id', // 契約ID
|
||
'process_name', // プロセス名
|
||
'job_name', // ジョブ名
|
||
'status', // ステータス
|
||
'error_code', // エラーコード
|
||
'status_comment', // ステータスコメント
|
||
'created_at' // 作成日時
|
||
];
|
||
|
||
/**
|
||
* キャストする属性
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $casts = [
|
||
'job_log_id' => 'integer',
|
||
'park_id' => 'integer',
|
||
'user_id' => 'integer',
|
||
'contract_id' => 'integer',
|
||
'error_code' => 'integer',
|
||
'created_at' => 'datetime'
|
||
];
|
||
|
||
/**
|
||
* エラーコードの定数
|
||
*/
|
||
const ERROR_CODE_THRESHOLD = 100; // エラー判定閾値(>=100がエラー)
|
||
|
||
/**
|
||
* updateされない設定(created_atのみ)
|
||
*
|
||
* @var bool
|
||
*/
|
||
public $timestamps = false;
|
||
|
||
/**
|
||
* 駐輪場との関連
|
||
*
|
||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||
*/
|
||
public function park()
|
||
{
|
||
return $this->belongsTo(Park::class, 'park_id', 'park_id');
|
||
}
|
||
|
||
/**
|
||
* ユーザーとの関連
|
||
*
|
||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||
*/
|
||
public function user()
|
||
{
|
||
return $this->belongsTo(User::class, 'user_id', 'user_id');
|
||
}
|
||
|
||
/**
|
||
* 契約との関連
|
||
*
|
||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||
*/
|
||
public function contract()
|
||
{
|
||
return $this->belongsTo(RegularContract::class, 'contract_id', 'contract_id');
|
||
}
|
||
|
||
/**
|
||
* 過去15分間のエラーログを取得
|
||
*
|
||
* @return \Illuminate\Database\Eloquent\Collection
|
||
*/
|
||
public static function getRecentErrorLogs()
|
||
{
|
||
$fifteenMinutesAgo = Carbon::now()->subMinutes(15);
|
||
|
||
return self::where('created_at', '>=', $fifteenMinutesAgo)
|
||
->where('error_code', '>=', self::ERROR_CODE_THRESHOLD)
|
||
->orderBy('created_at', 'desc')
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* 指定期間内のエラーログを取得
|
||
*
|
||
* @param string $startTime 開始時刻
|
||
* @param string $endTime 終了時刻
|
||
* @return \Illuminate\Database\Eloquent\Collection
|
||
*/
|
||
public static function getErrorLogsByPeriod(string $startTime, string $endTime)
|
||
{
|
||
return self::whereBetween('created_at', [$startTime, $endTime])
|
||
->where('error_code', '>=', self::ERROR_CODE_THRESHOLD)
|
||
->orderBy('created_at', 'desc')
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* 指定期間内の全ログを取得
|
||
*
|
||
* @param string $startTime 開始時刻
|
||
* @param string $endTime 終了時刻
|
||
* @return \Illuminate\Database\Eloquent\Collection
|
||
*/
|
||
public static function getLogsByPeriod(string $startTime, string $endTime)
|
||
{
|
||
return self::whereBetween('created_at', [$startTime, $endTime])
|
||
->orderBy('created_at', 'desc')
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* プリンタジョブログを作成
|
||
*
|
||
* @param array $data ログデータ
|
||
* @return PrintJobLog 作成されたログ
|
||
*/
|
||
public static function createLog(array $data): PrintJobLog
|
||
{
|
||
$defaultData = [
|
||
'park_id' => null,
|
||
'user_id' => null,
|
||
'contract_id' => null,
|
||
'process_name' => '',
|
||
'job_name' => '',
|
||
'status' => '',
|
||
'error_code' => 0,
|
||
'status_comment' => '',
|
||
'created_at' => now()
|
||
];
|
||
|
||
$mergedData = array_merge($defaultData, $data);
|
||
|
||
return self::create($mergedData);
|
||
}
|
||
|
||
/**
|
||
* エラーログかどうかを判定
|
||
*
|
||
* @return bool エラーログかどうか
|
||
*/
|
||
public function isError(): bool
|
||
{
|
||
return $this->error_code >= self::ERROR_CODE_THRESHOLD;
|
||
}
|
||
|
||
/**
|
||
* 正常ログかどうかを判定
|
||
*
|
||
* @return bool 正常ログかどうか
|
||
*/
|
||
public function isNormal(): bool
|
||
{
|
||
return $this->error_code < self::ERROR_CODE_THRESHOLD;
|
||
}
|
||
|
||
/**
|
||
* エラーレベルを取得
|
||
*
|
||
* @return string エラーレベル
|
||
*/
|
||
public function getErrorLevel(): string
|
||
{
|
||
if ($this->error_code >= 200) {
|
||
return '重大エラー';
|
||
} elseif ($this->error_code >= self::ERROR_CODE_THRESHOLD) {
|
||
return 'エラー';
|
||
} else {
|
||
return '正常';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* エラーログの統計情報を取得
|
||
*
|
||
* @param string $startTime 開始時刻
|
||
* @param string $endTime 終了時刻
|
||
* @return array 統計情報
|
||
*/
|
||
public static function getErrorStatistics(string $startTime, string $endTime): array
|
||
{
|
||
$errorLogs = self::getErrorLogsByPeriod($startTime, $endTime);
|
||
$totalLogs = self::getLogsByPeriod($startTime, $endTime);
|
||
|
||
$errorByCode = $errorLogs->groupBy('error_code')->map->count();
|
||
$errorByProcess = $errorLogs->groupBy('process_name')->map->count();
|
||
|
||
return [
|
||
'total_logs' => $totalLogs->count(),
|
||
'error_logs' => $errorLogs->count(),
|
||
'error_rate' => $totalLogs->count() > 0 ?
|
||
round(($errorLogs->count() / $totalLogs->count()) * 100, 2) : 0,
|
||
'error_by_code' => $errorByCode->toArray(),
|
||
'error_by_process' => $errorByProcess->toArray(),
|
||
'period' => [
|
||
'start' => $startTime,
|
||
'end' => $endTime
|
||
]
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 文字列表現
|
||
*
|
||
* @return string
|
||
*/
|
||
public function __toString(): string
|
||
{
|
||
return sprintf(
|
||
'PrintJobLog[ID:%d, Process:%s, ErrorCode:%d, Time:%s]',
|
||
$this->job_log_id,
|
||
$this->process_name,
|
||
$this->error_code,
|
||
$this->created_at ? $this->created_at->format('Y-m-d H:i:s') : 'N/A'
|
||
);
|
||
}
|
||
}
|