master
cody 3 days ago
parent 2fac210016
commit 9764f7ca85

@ -44,14 +44,13 @@ class CheckBirthday extends Command
*/ */
public function handle() public function handle()
{ {
// 匹配今天生日格式YYYY-MM-DD 或 MM-DD // 仅完整生日YYYY-MM-DD参与提醒避免 YYYY-MM 被自动补成 01 误判
$today = date('m-d');
$users = User::where('is_schoolmate', 1) $users = User::where('is_schoolmate', 1)
->where(function ($query) use ($today) { ->whereNotNull('birthday')
$query->where('birthday', 'like', '%-' . $today)
->orWhere('birthday', 'like', $today . '%');
})
->get(); ->get();
$users = $users->filter(function ($user) {
return User::isBirthdayToday($user->birthday);
})->values();
$birthdayCount = $users->count(); $birthdayCount = $users->count();

@ -0,0 +1,78 @@
<?php
namespace App\Console\Commands;
use App\Models\User;
use Illuminate\Console\Command;
class NormalizeUserBirthdayMonth extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'users:normalize-birthday-month {--dry-run : 仅预览将被修复的数据,不实际写库}';
/**
* The console command description.
*
* @var string
*/
protected $description = '将用户表中形如 YYYY-MM-01 的生日还原为 YYYY-MM';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$dryRun = (bool) $this->option('dry-run');
$query = User::query()
->whereNotNull('birthday')
->where('birthday', 'like', '____-__-01');
$total = (clone $query)->count();
if ($total === 0) {
$this->info('未找到需要修复的生日数据');
return self::SUCCESS;
}
$this->info(($dryRun ? '预览' : '开始修复') . " {$total} 条生日数据");
$updated = 0;
$previewed = 0;
$query->orderBy('id')->chunkById(200, function ($users) use ($dryRun, &$updated, &$previewed) {
foreach ($users as $user) {
$normalizedBirthday = substr($user->birthday, 0, 7);
if ($dryRun) {
if ($previewed < 20) {
$this->line("user_id={$user->id} {$user->birthday} => {$normalizedBirthday}");
}
$previewed++;
continue;
}
$user->birthday = $normalizedBirthday;
$user->save();
$updated++;
}
});
if ($dryRun) {
if ($previewed > 20) {
$this->line('仅展示前 20 条预览结果');
}
$this->info("预览完成,共 {$total} 条待修复");
return self::SUCCESS;
}
$this->info("修复完成,共更新 {$updated} 条生日数据");
return self::SUCCESS;
}
}

@ -279,7 +279,7 @@ class UserController extends CommonController
})->where('id', $this->getUserId())->count(); })->where('id', $this->getUserId())->count();
// 是否生日 // 是否生日
$is_birthday = 0; $is_birthday = 0;
if (isset($user->birthday) && date('m-d', strtotime($user->birthday)) == date('m-d')) { if (User::isBirthdayToday($user->birthday ?? null)) {
$is_birthday = 1; $is_birthday = 1;
} }
return $this->success(compact('user', 'door_appointments', 'course_signs', 'enter_schoolmate', 'is_birthday')); return $this->success(compact('user', 'door_appointments', 'course_signs', 'enter_schoolmate', 'is_birthday'));

@ -125,6 +125,26 @@ class User extends Authenticatable implements Auditable
'is_schoolmate' => ['否', '是'], 'is_schoolmate' => ['否', '是'],
]; ];
public static function hasCompleteBirthday(?string $birthday): bool
{
if (empty($birthday) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $birthday)) {
return false;
}
[$year, $month, $day] = array_map('intval', explode('-', $birthday));
return checkdate($month, $day, $year);
}
public static function isBirthdayToday(?string $birthday): bool
{
if (!self::hasCompleteBirthday($birthday)) {
return false;
}
return substr($birthday, 5, 5) === date('m-d');
}
public function getMobileAttribute($value) public function getMobileAttribute($value)
{ {
// 如果url中包含admin字符串则所有的手机号显示中间4位星号代替 // 如果url中包含admin字符串则所有的手机号显示中间4位星号代替

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('birthday')->nullable()->comment('生日')->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->date('birthday')->nullable()->comment('生日')->change();
});
}
};
Loading…
Cancel
Save