You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
6.5 KiB

11 months ago
<?php
namespace App\Models;
class Blacklist extends SoftDeletesModel
{
protected $table = 'blacklists';
protected $casts = [
'file' => 'array',
'start_date' => 'date',
'end_date' => 'date',
'status' => 'boolean',
'credent' => 'integer',
];
// 证件类型常量
const CREDENT_ID_CARD = 1; // 身份证
const CREDENT_PASSPORT = 2; // 护照
// 状态常量
const STATUS_DISABLED = 0; // 禁用
const STATUS_ENABLED = 1; // 启用
/**
* 获取证件类型文本
*/
public function getCredentTextAttribute()
{
$credents = [
self::CREDENT_ID_CARD => '身份证',
self::CREDENT_PASSPORT => '护照',
];
return $credents[$this->credent] ?? '未知';
}
/**
* 获取状态文本
*/
public function getStatusTextAttribute()
{
return $this->status ? '启用' : '禁用';
}
/**
* 获取文件列表
*/
public function getFilesAttribute()
{
if (!$this->file) {
return [];
}
return Upload::whereIn('id', $this->file)->get();
}
/**
* 检查是否在有效期内
*/
public function isActive()
{
if (!$this->status) {
return false;
}
$now = now();
// 检查开始时间
if ($this->start_date && $now->lt($this->start_date)) {
return false;
}
// 检查结束时间
if ($this->end_date && $now->gt($this->end_date)) {
return false;
}
return true;
}
/**
* 检查访客是否在黑名单中
*/
public static function checkVisitor($mobile, $idcard = null)
{
$query = self::where('status', self::STATUS_ENABLED)
->where(function ($q) use ($mobile, $idcard) {
$q->where('mobile', $mobile);
if ($idcard) {
$q->orWhere('idcard', $idcard);
}
});
$blacklist = $query->first();
if (!$blacklist) {
return null;
}
return $blacklist->isActive() ? $blacklist : null;
}
/**
* 添加黑名单记录
*/
public static function addToBlacklist($data)
{
// 检查是否已存在
$existing = self::where('mobile', $data['mobile'])
->orWhere('idcard', $data['idcard'] ?? '')
->first();
if ($existing) {
// 更新现有记录
$existing->update($data);
return $existing;
}
// 创建新记录
return self::create($data);
}
/**
* 从黑名单中移除
*/
public function removeFromBlacklist()
{
$this->status = self::STATUS_DISABLED;
$this->save();
}
/**
* 获取有效期文本
*/
public function getValidityPeriodText()
{
if (!$this->start_date && !$this->end_date) {
return '永久有效';
}
$start = $this->start_date ? $this->start_date->format('Y-m-d') : '开始';
$end = $this->end_date ? $this->end_date->format('Y-m-d') : '结束';
return $start . ' 至 ' . $end;
}
/**
* 获取剩余天数
*/
public function getRemainingDays()
{
if (!$this->end_date) {
return null; // 永久有效
}
$now = now();
if ($now->gt($this->end_date)) {
return 0; // 已过期
}
return $now->diffInDays($this->end_date);
}
/**
* 检查是否即将过期7天内
*/
public function isExpiringSoon()
{
$remainingDays = $this->getRemainingDays();
return $remainingDays !== null && $remainingDays <= 7;
}
/**
* 获取黑名单统计信息
*/
public static function getStatistics()
{
$total = self::count();
$active = self::where('status', self::STATUS_ENABLED)->count();
$expired = self::where('status', self::STATUS_ENABLED)
->where('end_date', '<', now())
->count();
$expiringSoon = self::where('status', self::STATUS_ENABLED)
->whereBetween('end_date', [now(), now()->addDays(7)])
->count();
return [
'total' => $total,
'active' => $active,
'expired' => $expired,
'expiring_soon' => $expiringSoon,
'disabled' => $total - $active,
];
}
/**
* 批量导入黑名单
*/
public static function batchImport($data)
{
$successCount = 0;
$errorCount = 0;
$errors = [];
foreach ($data as $index => $item) {
try {
// 验证必填字段
if (empty($item['mobile']) && empty($item['idcard'])) {
$errors[] = "第" . ($index + 1) . "行:手机号和证件号不能同时为空";
$errorCount++;
continue;
}
// 检查是否已存在
$existing = self::where('mobile', $item['mobile'] ?? '')
->orWhere('idcard', $item['idcard'] ?? '')
->first();
if ($existing) {
$existing->update($item);
} else {
self::create($item);
}
$successCount++;
} catch (\Exception $e) {
$errors[] = "第" . ($index + 1) . "行:" . $e->getMessage();
$errorCount++;
}
}
return [
'success_count' => $successCount,
'error_count' => $errorCount,
'errors' => $errors,
];
}
/**
* 验证黑名单数据
*/
public function validate()
{
$errors = [];
if (empty($this->mobile) && empty($this->idcard)) {
$errors[] = '手机号和证件号不能同时为空';
}
if (!empty($this->mobile) && !preg_match('/^1[3-9]\d{9}$/', $this->mobile)) {
$errors[] = '手机号格式不正确';
}
if (!empty($this->idcard) && !preg_match('/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/', $this->idcard)) {
$errors[] = '身份证号格式不正确';
}
if ($this->start_date && $this->end_date && $this->start_date > $this->end_date) {
$errors[] = '开始时间不能晚于结束时间';
}
return $errors;
}
}