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.

178 lines
6.7 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\Console\Commands;
use App\Models\User;
use Illuminate\Console\Command;
class CheckSchoolmateData extends Command
{
/**
* 允许直接认定为校友的课程体系名称
*
* @var string[]
*/
protected array $allowedCourseTypeNames = ['高研班', '攀峰班'];
/**
* 允许直接认定为校友的课程名称
*
* @var string[]
*/
protected array $allowedCourseNames = ['首期技术经理人领航班'];
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'check_schoolmate_data';
/**
* The console command description.
*
* @var string
*/
protected $description = '按当前校友认定口径校验所有校友数据,并自动修正不合格校友';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$today = date('Y-m-d');
$allowedCourseTypeNames = $this->allowedCourseTypeNames;
$allowedCourseNames = $this->allowedCourseNames;
$fixedUsers = User::query()
->where('is_schoolmate', 1)
->where(function ($query) {
$query->whereNull('mobile')
->orWhere('mobile', '');
})
->orderBy('id')
->get();
$fixedCount = 0;
foreach ($fixedUsers as $user) {
$user->is_schoolmate = 0;
$user->schoolmate_time = null;
if ($user->isDirty()) {
$user->save();
$fixedCount++;
}
}
$invalidUsers = User::query()
->where('is_schoolmate', 1)
->whereDoesntHave('courseSigns', function ($query) use ($today, $allowedCourseTypeNames, $allowedCourseNames) {
$query->where('status', 1)
->whereHas('course', function ($courseQuery) use ($today, $allowedCourseTypeNames, $allowedCourseNames) {
$courseQuery->where(function ($eligibleQuery) use ($today, $allowedCourseTypeNames, $allowedCourseNames) {
$eligibleQuery->where(function ($autoSchoolmateQuery) use ($today) {
$autoSchoolmateQuery->where('auto_schoolmate', 1)
->whereNotNull('start_date')
->where('start_date', '<=', $today);
})->orWhereHas('typeDetail', function ($typeQuery) use ($allowedCourseTypeNames) {
$typeQuery->whereIn('name', $allowedCourseTypeNames);
})->orWhereIn('name', $allowedCourseNames);
});
});
})
->with([
'courseSigns' => function ($query) {
$query->where('status', 1)->with('course.typeDetail');
}
])
->orderBy('id')
->get();
$schoolmateTotal = User::where('is_schoolmate', 1)->count();
$invalidCount = $invalidUsers->count();
$this->info("当前校友总数:{$schoolmateTotal}");
$this->info("已自动修正无手机号但仍是校友的用户数:{$fixedCount}");
$this->info('检测口径:用户当前是校友,但不存在以下任一合格来源,则判定为不符合要求:');
$this->line('1. 已审核通过,且课程开启自动入校友,且课程已开课');
$this->line('2. 已审核通过,且课程属于高研班体系');
$this->line('3. 已审核通过,且课程属于攀峰班体系');
$this->line('4. 已审核通过,且课程为“首期技术经理人领航班”');
if ($invalidUsers->isEmpty()) {
$this->info('检测完成:当前所有校友数据都符合校友认定规则。');
return self::SUCCESS;
}
$this->warn('检测完成:发现 ' . $invalidCount . ' 位校友不符合校友认定规则,以下用户将被自动取消校友身份。');
$this->newLine();
$rows = [];
foreach ($invalidUsers as $user) {
$passedCourses = $user->courseSigns
->map(function ($courseSign) use ($allowedCourseTypeNames, $allowedCourseNames, $today) {
if (empty($courseSign->course)) {
return '课程已删除';
}
$course = $courseSign->course;
$courseTypeName = $course->typeDetail->name ?? '空';
$reasons = [];
if ($course->auto_schoolmate == 1 && !empty($course->start_date) && $course->start_date <= $today) {
$reasons[] = '自动入校友';
}
if (in_array($courseTypeName, $allowedCourseTypeNames, true)) {
$reasons[] = '体系白名单';
}
if (in_array($course->name, $allowedCourseNames, true)) {
$reasons[] = '课程白名单';
}
return sprintf(
'%s[课程体系=%s,auto_schoolmate=%s,start_date=%s,命中规则=%s]',
$course->name,
$courseTypeName,
(string) $course->auto_schoolmate,
$course->start_date ?: '空',
empty($reasons) ? '无' : implode('+', $reasons)
);
})
->filter()
->unique()
->values()
->implode('');
$rows[] = [
'用户ID' => $user->id,
'姓名' => $user->name,
'手机号' => $user->mobile,
'成为校友时间' => $user->schoolmate_time ?: '空',
'已通过课程' => $passedCourses ?: '无',
'不符合原因' => '没有符合自动入校友规则的已通过课程',
];
}
$this->table(
['用户ID', '姓名', '手机号', '成为校友时间', '已通过课程', '不符合原因'],
$rows
);
$updatedCount = 0;
foreach ($invalidUsers as $user) {
$user->is_schoolmate = 0;
$user->schoolmate_time = null;
if ($user->isDirty()) {
$user->save();
$updatedCount++;
}
}
$this->newLine();
$this->info("已自动取消 {$updatedCount} 位异常校友的校友身份。");
$this->info('本次仅在命令行输出处理结果,不再生成 txt 文件。');
return self::SUCCESS;
}
}