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.

194 lines
6.3 KiB

<?php
namespace App\Console\Commands;
use App\Models\Config;
use App\Models\Course;
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
*/
protected $description = '批量更新学号/打元和同事标签';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// 1. 批量更新学号
$this->updateUserNo();
// 2. 给元和同事打标签
$this->tagYuanheColleague();
return $this->info('更新完成');
}
/**
* 批量更新学号
*/
protected function updateUserNo()
{
$this->info('开始更新学号...');
$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) {
$i = 1;
// 编号前缀
foreach ($course->courseSigns as $sign) {
$user = User::find($sign->user_id);
// 只要用户没有学号(包括 null 和空字符串),都需要更新
if ($user->no) {
continue;
}
// 生成学号,如果已存在则顺位+1继续尝试
$baseNo = $course->student_prefix . str_pad($i, 3, '0', STR_PAD_LEFT);
$no = $baseNo;
$attempt = 0;
$maxAttempts = 1000; // 防止无限循环
// 检查学号是否已存在,如果存在则顺位+1继续尝试
while (User::where('no', $no)->where('id', '!=', $user->id)->exists() && $attempt < $maxAttempts) {
$i++;
$no = $course->student_prefix . str_pad($i, 3, '0', STR_PAD_LEFT);
$attempt++;
}
if ($attempt >= $maxAttempts) {
$this->warn('课程: ' . ($course->name ?? $course->id) . ', 用户: ' . ($user->name ?? $user->id) . ' 无法生成唯一学号,跳过');
continue;
}
// 更新用户编号
$user->no = $no;
$user->save();
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));
}
$i++;
$totalUpdated++;
}
}
$this->info('学号更新完成,共更新 ' . $totalUpdated . ' 个学号');
}
/**
* 给元和同事打标签:检查所有有公司名称的用户,若公司名匹配元和员工则追加 from 标签
*/
protected function tagYuanheColleague()
{
$this->info('开始给元和同事打标签...');
$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;
}
// 所有有公司名称、且 from 中尚无「元禾同事」的用户(有该标签的不再追加)
$users = User::whereNotNull('company_name')
->where('company_name', '!=', '')
->where(function ($q) use ($tag) {
$q->whereNull('from')
->orWhere('from', 'not like', '%' . $tag . '%');
})
->get();
$count = 0;
foreach ($users as $user) {
$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;
}
// 再次确认 from 未有该标签,避免重复
$from = $user->from ?? '';
$fromArray = array_filter(array_map('trim', explode(',', $from)));
if (in_array($tag, $fromArray)) {
continue;
}
// 追加标签并去重后写回
$fromArray[] = $tag;
$fromArray = array_values(array_unique($fromArray));
$user->from = implode(',', $fromArray);
$user->save();
$this->info('已为用户 ' . $user->name . '(' . $user->mobile . ') 添加标签: ' . $tag . ',公司: ' . $companyName);
$count++;
}
$this->info('元和同事标签更新完成,共更新 ' . $count . ' 人');
}
}