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.

213 lines
7.3 KiB

10 months ago
<?php
namespace App\Console\Commands;
3 months ago
use App\Models\Config;
8 months ago
use App\Models\Course;
10 months ago
use App\Models\User;
use Illuminate\Console\Command;
class UpdateUserNo extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'update_user_no';
/**
* The console command description.
*
* @var string
*/
4 months ago
protected $description = '批量更新学号/打元和同事标签';
10 months ago
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
4 months ago
// 1. 批量更新学号
$this->updateUserNo();
// 2. 给元和同事打标签
$this->tagYuanheColleague();
return $this->info('更新完成');
}
/**
* 批量更新学号
*/
protected function updateUserNo()
{
$this->info('开始更新学号...');
3 months ago
$today = date('Y-m-d');
// 获取所有已开始且有学号前缀的课程
$courses = Course::with([
'courseSigns' => function ($query) {
$query->where('status', 1);
}
])->whereNotNull('start_date')
->where('start_date', '<=', $today)
->whereNotNull('student_prefix')
->orderBy('start_date')
->get();
$totalUpdated = 0;
foreach ($courses as $course) {
8 months ago
$i = 1;
// 编号前缀
3 months ago
foreach ($course->courseSigns as $sign) {
$user = User::find($sign->user_id);
// 只要用户没有学号(包括 null 和空字符串),都需要更新
if ($user->no) {
continue;
8 months ago
}
3 months ago
// 生成学号,如果已存在则顺位+1继续尝试
$baseNo = $course->student_prefix . str_pad($i, 3, '0', STR_PAD_LEFT);
$no = $baseNo;
$attempt = 0;
$maxAttempts = 1000; // 防止无限循环
2 months ago
$saved = false;
// 尝试保存学号,如果遇到唯一性冲突则重新生成
while (!$saved && $attempt < $maxAttempts) {
// 检查学号是否已存在,如果存在则顺位+1继续尝试
if (User::where('no', $no)->where('id', '!=', $user->id)->exists()) {
$i++;
$no = $course->student_prefix . str_pad($i, 3, '0', STR_PAD_LEFT);
$attempt++;
continue;
}
// 尝试更新用户编号
try {
$user->no = $no;
$user->save();
$saved = true;
} catch (\Illuminate\Database\QueryException $e) {
// 捕获唯一性约束冲突异常
if ($e->getCode() == 23000 && strpos($e->getMessage(), 'Duplicate entry') !== false) {
// 学号已被其他用户占用,重新生成
$i++;
$no = $course->student_prefix . str_pad($i, 3, '0', STR_PAD_LEFT);
$attempt++;
continue;
}
// 其他异常直接抛出
throw $e;
}
3 months ago
}
2 months ago
if (!$saved) {
3 months ago
$this->warn('课程: ' . ($course->name ?? $course->id) . ', 用户: ' . ($user->name ?? $user->id) . ' 无法生成唯一学号,跳过');
continue;
}
if ($no != $baseNo) {
$this->info('课程: ' . ($course->name ?? $course->id) . ', 原学号: ' . $baseNo . ' 已存在,使用: ' . $no . ', 用户: ' . ($user->name ?? $user->id));
} else {
$this->info('课程: ' . ($course->name ?? $course->id) . ', 学号: ' . $no . ', 用户: ' . ($user->name ?? $user->id));
}
3 months ago
$i++;
$totalUpdated++;
8 months ago
}
10 months ago
}
3 months ago
$this->info('学号更新完成,共更新 ' . $totalUpdated . ' 个学号');
4 months ago
}
/**
3 months ago
* 给元和同事打标签:检查所有有公司名称的用户,若公司名匹配元和员工则追加 from 标签
4 months ago
*/
protected function tagYuanheColleague()
{
$this->info('开始给元和同事打标签...');
3 months ago
$tag = User::FROM_TAG_YUANHE_COLLEAGUE;
// 从 config 获取元和公司名称关键词(用于判断是否元和员工)
$companyNameKeyword = [];
$configValue = Config::getValueByKey('yuanhe_company');
if ($configValue) {
$configData = json_decode($configValue, true);
if (is_array($configData)) {
foreach ($configData as $item) {
if (!empty($item['company_name'])) {
$companyNameKeyword[] = $item['company_name'];
}
if (!empty($item['short_company_name'])) {
$companyNameKeyword[] = $item['short_company_name'];
}
}
$companyNameKeyword = array_values(array_unique($companyNameKeyword));
}
}
if (empty($companyNameKeyword)) {
$this->warn('config(yuanhe_company) 无数据,跳过元和同事打标签');
return;
}
4 months ago
3 months ago
// 所有有公司名称、且 from 中尚无「元禾同事」的用户(有该标签的不再追加)
$users = User::whereNotNull('company_name')
->where('company_name', '!=', '')
->where(function ($q) use ($tag) {
$q->whereNull('from')
->orWhere('from', 'not like', '%' . $tag . '%');
})
->get();
4 months ago
$count = 0;
foreach ($users as $user) {
3 months ago
$companyName = (string) ($user->company_name ?? '');
// 检查是否元和员工:公司名包含任一关键词
$isYuanhe = false;
foreach ($companyNameKeyword as $keyword) {
$keyword = (string) $keyword;
if ($keyword !== '' && mb_strpos($companyName, $keyword) !== false) {
$isYuanhe = true;
break;
}
}
if (!$isYuanhe) {
continue;
}
4 months ago
3 months ago
// 再次确认 from 未有该标签,避免重复
$from = $user->from ?? '';
4 months ago
$fromArray = array_filter(array_map('trim', explode(',', $from)));
if (in_array($tag, $fromArray)) {
continue;
}
3 months ago
// 追加标签并去重后写回
4 months ago
$fromArray[] = $tag;
3 months ago
$fromArray = array_values(array_unique($fromArray));
4 months ago
$user->from = implode(',', $fromArray);
$user->save();
3 months ago
$this->info('已为用户 ' . $user->name . '(' . $user->mobile . ') 添加标签: ' . $tag . ',公司: ' . $companyName);
4 months ago
$count++;
}
$this->info('元和同事标签更新完成,共更新 ' . $count . ' 人');
10 months ago
}
}