|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
|
|
|
|
class VisitLog extends CommonModel
|
|
|
|
|
{
|
|
|
|
|
protected $table = 'visit_logs';
|
|
|
|
|
|
|
|
|
|
protected $casts = [
|
|
|
|
|
'created_at' => 'datetime',
|
|
|
|
|
'updated_at' => 'datetime',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 日志类型常量
|
|
|
|
|
const TYPE_CREATE = 'create'; // 创建申请
|
|
|
|
|
const TYPE_UPDATE = 'update'; // 更新申请
|
|
|
|
|
const TYPE_AUDIT = 'audit'; // 审核
|
|
|
|
|
const TYPE_APPROVE = 'approve'; // 通过
|
|
|
|
|
const TYPE_REJECT = 'reject'; // 驳回
|
|
|
|
|
const TYPE_ENTER = 'enter'; // 进厂
|
|
|
|
|
const TYPE_LEAVE = 'leave'; // 离厂
|
|
|
|
|
const TYPE_CANCEL = 'cancel'; // 取消
|
|
|
|
|
const TYPE_STUDY = 'study'; // 学习
|
|
|
|
|
const TYPE_EXAM = 'exam'; // 考试
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关联访问申请
|
|
|
|
|
*/
|
|
|
|
|
public function visit()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsTo(Visit::class, 'visit_id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关联管理员
|
|
|
|
|
*/
|
|
|
|
|
public function admin()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsTo(Admin::class, 'admin_id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关联用户
|
|
|
|
|
*/
|
|
|
|
|
public function user()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsTo(User::class, 'user_id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关联部门
|
|
|
|
|
*/
|
|
|
|
|
public function department()
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsTo(Department::class, 'department_id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录访问日志
|
|
|
|
|
*/
|
|
|
|
|
public static function log($visitId, $type, $remark = null, $adminId = null, $userId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::create([
|
|
|
|
|
'visit_id' => $visitId,
|
|
|
|
|
'type' => $type,
|
|
|
|
|
'admin_id' => $adminId,
|
|
|
|
|
'user_id' => $userId,
|
|
|
|
|
'remark' => $remark,
|
|
|
|
|
'created_at' => now(),
|
|
|
|
|
'updated_at' => now(),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录创建申请日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logCreate($visitId, $remark = null, $userId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_CREATE, $remark, null, $userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录审核日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logAudit($visitId, $remark = null, $adminId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_AUDIT, $remark, $adminId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录通过日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logApprove($visitId, $remark = null, $adminId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_APPROVE, $remark, $adminId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录驳回日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logReject($visitId, $remark = null, $adminId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_REJECT, $remark, $adminId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录进厂日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logEnter($visitId, $remark = null, $adminId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_ENTER, $remark, $adminId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录离厂日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logLeave($visitId, $remark = null, $adminId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_LEAVE, $remark, $adminId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录学习日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logStudy($visitId, $remark = null, $userId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_STUDY, $remark, null, $userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录考试日志
|
|
|
|
|
*/
|
|
|
|
|
public static function logExam($visitId, $remark = null, $userId = null)
|
|
|
|
|
{
|
|
|
|
|
return self::log($visitId, self::TYPE_EXAM, $remark, null, $userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取日志类型文本
|
|
|
|
|
*/
|
|
|
|
|
public function getTypeTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$types = [
|
|
|
|
|
self::TYPE_CREATE => '创建申请',
|
|
|
|
|
self::TYPE_UPDATE => '更新申请',
|
|
|
|
|
self::TYPE_AUDIT => '审核',
|
|
|
|
|
self::TYPE_APPROVE => '通过',
|
|
|
|
|
self::TYPE_REJECT => '驳回',
|
|
|
|
|
self::TYPE_ENTER => '进厂',
|
|
|
|
|
self::TYPE_LEAVE => '离厂',
|
|
|
|
|
self::TYPE_CANCEL => '取消',
|
|
|
|
|
self::TYPE_STUDY => '学习',
|
|
|
|
|
self::TYPE_EXAM => '考试',
|
|
|
|
|
];
|
|
|
|
|
return $types[$this->type] ?? '未知';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取操作人信息
|
|
|
|
|
*/
|
|
|
|
|
public function getOperatorAttribute()
|
|
|
|
|
{
|
|
|
|
|
if ($this->admin) {
|
|
|
|
|
return $this->admin->name ?? '管理员';
|
|
|
|
|
}
|
|
|
|
|
if ($this->user) {
|
|
|
|
|
return $this->user->name ?? '用户';
|
|
|
|
|
}
|
|
|
|
|
return '系统';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取访问日志统计
|
|
|
|
|
*/
|
|
|
|
|
public static function getStatistics($startDate = null, $endDate = null)
|
|
|
|
|
{
|
|
|
|
|
$query = self::query();
|
|
|
|
|
|
|
|
|
|
if ($startDate) {
|
|
|
|
|
$query->where('created_at', '>=', $startDate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($endDate) {
|
|
|
|
|
$query->where('created_at', '<=', $endDate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$total = $query->count();
|
|
|
|
|
$today = self::whereDate('created_at', today())->count();
|
|
|
|
|
$thisWeek = self::whereBetween('created_at', [
|
|
|
|
|
now()->startOfWeek(),
|
|
|
|
|
now()->endOfWeek()
|
|
|
|
|
])->count();
|
|
|
|
|
$thisMonth = self::whereMonth('created_at', now()->month)->count();
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'total' => $total,
|
|
|
|
|
'today' => $today,
|
|
|
|
|
'this_week' => $thisWeek,
|
|
|
|
|
'this_month' => $thisMonth,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取访问申请的操作历史
|
|
|
|
|
*/
|
|
|
|
|
public static function getVisitHistory($visitId)
|
|
|
|
|
{
|
|
|
|
|
return self::where('visit_id', $visitId)
|
|
|
|
|
->with(['admin', 'user'])
|
|
|
|
|
->orderBy('created_at', 'desc')
|
|
|
|
|
->get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取操作日志(按类型分组)
|
|
|
|
|
*/
|
|
|
|
|
public static function getLogsByType($type, $limit = 100)
|
|
|
|
|
{
|
|
|
|
|
return self::where('type', $type)
|
|
|
|
|
->with(['visit', 'admin', 'user'])
|
|
|
|
|
->orderBy('created_at', 'desc')
|
|
|
|
|
->limit($limit)
|
|
|
|
|
->get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 清理过期日志
|
|
|
|
|
*/
|
|
|
|
|
public static function cleanExpiredLogs($days = 365)
|
|
|
|
|
{
|
|
|
|
|
$expiredDate = now()->subDays($days);
|
|
|
|
|
return self::where('created_at', '<', $expiredDate)->delete();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取日志详情
|
|
|
|
|
*/
|
|
|
|
|
public function getDetails()
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'id' => $this->id,
|
|
|
|
|
'visit_id' => $this->visit_id,
|
|
|
|
|
'type' => $this->getTypeTextAttribute(),
|
|
|
|
|
'operator' => $this->getOperatorAttribute(),
|
|
|
|
|
'remark' => $this->remark,
|
|
|
|
|
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
|
|
|
|
|
'visit_info' => $this->visit ? [
|
|
|
|
|
'code' => $this->visit->code,
|
|
|
|
|
'name' => $this->visit->name,
|
|
|
|
|
'mobile' => $this->visit->mobile,
|
|
|
|
|
'company_name' => $this->visit->company_name,
|
|
|
|
|
] : null,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|