diff --git a/app/Models/User.php b/app/Models/User.php index c58001a..b00543f 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -125,6 +125,72 @@ class User extends Authenticatable implements Auditable 'is_schoolmate' => ['否', '是'], ]; + public static function normalizeBirthday($birthday): ?string + { + if ($birthday instanceof DateTimeInterface) { + return Carbon::instance(\DateTime::createFromInterface($birthday))->format('Y-m-d'); + } + + if ($birthday === null) { + return null; + } + + $birthday = trim((string) $birthday); + if ($birthday === '') { + return null; + } + + $normalized = str_replace( + ['年', '月', '日', '/', '.', '_'], + ['-', '-', '', '-', '-', '-'], + $birthday + ); + $normalized = preg_replace('/\s+/', '', $normalized); + $normalized = preg_replace('/-+/', '-', $normalized); + $normalized = trim($normalized, '-'); + + if (preg_match('/^(\d{4})(\d{2})$/', $normalized, $matches)) { + $normalized = $matches[1] . '-' . $matches[2]; + } elseif (preg_match('/^(\d{4})(\d{2})(\d{2})$/', $normalized, $matches)) { + $normalized = $matches[1] . '-' . $matches[2] . '-' . $matches[3]; + } + + if (preg_match('/^(\d{4})-(\d{1,2})$/', $normalized, $matches)) { + $year = (int) $matches[1]; + $month = (int) $matches[2]; + + if ($month >= 1 && $month <= 12) { + return sprintf('%04d-%02d', $year, $month); + } + } + + if (preg_match('/^(\d{4})-(\d{1,2})-(\d{1,2})$/', $normalized, $matches)) { + $year = (int) $matches[1]; + $month = (int) $matches[2]; + $day = (int) $matches[3]; + + if (checkdate($month, $day, $year)) { + return sprintf('%04d-%02d-%02d', $year, $month, $day); + } + } + + return null; + } + + public static function hasBirthdayFormat(?string $birthday): bool + { + if (empty($birthday)) { + return false; + } + + if (preg_match('/^\d{4}-\d{2}$/', $birthday)) { + [, $month] = array_map('intval', explode('-', $birthday)); + return $month >= 1 && $month <= 12; + } + + return self::hasCompleteBirthday($birthday); + } + public static function hasCompleteBirthday(?string $birthday): bool { if (empty($birthday) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $birthday)) { @@ -145,6 +211,11 @@ class User extends Authenticatable implements Auditable return substr($birthday, 5, 5) === date('m-d'); } + public function setBirthdayAttribute($value): void + { + $this->attributes['birthday'] = self::normalizeBirthday($value); + } + public function getMobileAttribute($value) { // 如果url中包含admin字符串,则所有的手机号显示中间4位星号代替