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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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;
}
}