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.

248 lines
8.3 KiB

4 days ago
<?php
namespace App\Console\Commands;
use App\Models\CourseForm;
use App\Models\CourseSign;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
class UpdateUserFromCourseSign extends Command
{
/**
* 限定的手机号列表
*
* @var array
*/
4 days ago
protected $allowedMobiles = [
4 days ago
'18068449126',
'13775025589',
'13372137856',
'15862529818',
'15850007903',
'18662477010',
4 days ago
'13776041671',
'13811803477',
4 days ago
'13816102853',
'18761927103',
'13771899330',
'15850174698',
'13901337246',
'15190599917',
'13601736904',
'18013537727',
'13771990129',
'13862584161',
'18067734553',
'13913088481',
'13382182663',
'15962537089',
'13472506601',
'15366527762',
'17306151525',
'18862122672',
'18768114864',
'13646251927',
'18068036921',
'13962165222',
'13812764284',
4 days ago
'17746389584',
'13813662822',
];
4 days ago
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'update_user_from_course_sign';
/**
* The console command description.
*
* @var string
*/
protected $description = '从报名表获取用户填写的信息填充到user数据表按手机号匹配';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// 根据限定手机号列表查找所有用户
$users = User::whereIn('mobile', $this->allowedMobiles)->get();
if ($users->isEmpty()) {
return $this->error('没有找到符合条件的用户');
}
$this->info("找到 {$users->count()} 个用户需要处理");
$successCount = 0;
$failCount = 0;
foreach ($users as $user) {
$this->newLine();
$this->info("========== 处理用户:{$user->name} (手机号: {$user->mobile}, ID: {$user->id}) ==========");
try {
$this->processUser($user);
$successCount++;
} catch (\Exception $e) {
$this->error("处理用户 {$user->name} 时出错:" . $e->getMessage());
$failCount++;
}
}
$this->newLine();
return $this->info("全部处理完成!成功:{$successCount},失败:{$failCount}");
}
/**
* 处理单个用户
*/
private function processUser($user)
{
$user_id = $user->id;
4 days ago
// 获取该用户的所有报名记录(携带课程及课程类型)
$courseSigns = CourseSign::with('course.typeDetail')
->where('user_id', $user_id)
4 days ago
->whereNotNull('data')
->get();
if ($courseSigns->isEmpty()) {
$this->info('该用户没有报名记录或报名记录中没有数据');
return;
}
$this->info("找到 {$courseSigns->count()} 条报名记录");
4 days ago
// 如果用户报名了多个课程,并且其中包含课程类型是「高研班」或者「攀峰班」的课程
// 则优先使用这些课程的报名信息更新用户
$targetCourseSigns = $courseSigns;
if ($courseSigns->count() > 1) {
$specialCourseSigns = $courseSigns->filter(function ($sign) {
$typeName = $sign->course->typeDetail->name ?? '';
return in_array($typeName, ['高研班', '攀峰班']);
});
if ($specialCourseSigns->isNotEmpty()) {
$this->info('检测到高研班/攀峰班课程报名记录,将优先使用这些课程的报名信息更新用户');
$targetCourseSigns = $specialCourseSigns;
}
}
4 days ago
// 收集所有需要更新的用户字段
$userData = [];
$hasCompanyName = false;
4 days ago
foreach ($targetCourseSigns as $courseSign) {
4 days ago
if (empty($courseSign->data) || !is_array($courseSign->data)) {
continue;
}
4 days ago
// 获取该课程的表单字段配置,建立 field -> belong_user_table 的映射关系
4 days ago
$courseForms = CourseForm::where('course_id', $courseSign->course_id)
->where('belong_user', 1) // 只获取属于用户信息的字段
4 days ago
->whereNotNull('belong_user_table') // 必须有对应的用户表字段
->where('belong_user_table', '!=', '') // 用户表字段不能为空
->get(['field', 'belong_user_table']);
4 days ago
4 days ago
if ($courseForms->isEmpty()) {
4 days ago
continue;
}
4 days ago
// 建立 field -> belong_user_table 的映射关系
$fieldMapping = [];
foreach ($courseForms as $form) {
$fieldMapping[$form->field] = $form->belong_user_table;
}
4 days ago
// 将 data 数组转换为以 field 为 key 的关联数组
$dataArray = [];
foreach ($courseSign->data as $item) {
if (isset($item['field']) && isset($item['value'])) {
$dataArray[$item['field']] = $item['value'];
}
}
4 days ago
// 提取属于用户信息的字段,使用 belong_user_table 作为用户表的字段名
foreach ($fieldMapping as $field => $userTableField) {
4 days ago
if (isset($dataArray[$field]) && $dataArray[$field] !== null && $dataArray[$field] !== '') {
// 如果字段已经在 $userData 中,且新值不为空,则更新(优先使用非空值)
4 days ago
if (!isset($userData[$userTableField]) || empty($userData[$userTableField])) {
$userData[$userTableField] = $dataArray[$field];
4 days ago
}
// 检查是否是公司名字
4 days ago
if ($userTableField === 'company_name') {
4 days ago
$hasCompanyName = true;
}
}
}
}
if (empty($userData)) {
$this->info('没有找到需要更新的用户信息');
return;
}
$this->info('准备更新以下字段:' . implode(', ', array_keys($userData)));
// 更新用户信息
// 根据 User::$coverFields 判断是否需要覆盖更新
foreach ($userData as $key => $value) {
if (!in_array($key, User::$coverFields)) {
// 追加更新(对于非覆盖字段)
$currentValue = $user->$key ?? '';
if (!empty($currentValue)) {
$tempArray = explode(',', $currentValue . ',' . $value);
$tempArray = array_unique(array_filter($tempArray));
$userData[$key] = implode(',', $tempArray);
}
}
}
// 检查公司名字是否发生变化
$oldCompanyName = $user->company_name;
$newCompanyName = $userData['company_name'] ?? null;
// 如果公司名字从无到有,或者发生变化,都需要更新
$companyNameChanged = $hasCompanyName && isset($newCompanyName) &&
(empty($oldCompanyName) || $oldCompanyName != $newCompanyName);
$user->fill($userData);
$user->save();
$this->info('用户信息更新成功');
// 如果公司名字发生变化或新增,调用 UpdateCompany 脚本
4 days ago
if ($companyNameChanged) {
if (empty($oldCompanyName)) {
$this->info("检测到新增公司名字({$newCompanyName}),开始调用 UpdateCompany 脚本更新公司信息...");
} else {
$this->info("检测到公司名字发生变化({$oldCompanyName} -> {$newCompanyName}),开始调用 UpdateCompany 脚本更新公司信息...");
}
Artisan::call("update_company --user_id={$user_id}");
$this->info('公司信息更新完成');
} elseif ($hasCompanyName && isset($newCompanyName)) {
$this->info("公司名字未发生变化({$newCompanyName}),跳过公司信息更新");
}
4 days ago
$this->info('用户更新完成');
}
}