|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
|
|
|
|
|
|
|
|
use App\Models\Company;
|
|
|
|
|
|
use App\Models\Course;
|
|
|
|
|
|
use App\Models\CourseForm;
|
|
|
|
|
|
use App\Models\CourseSign;
|
|
|
|
|
|
use App\Models\CourseType;
|
|
|
|
|
|
use App\Models\User;
|
|
|
|
|
|
use Illuminate\Console\Command;
|
|
|
|
|
|
use Illuminate\Support\Facades\Artisan;
|
|
|
|
|
|
|
|
|
|
|
|
class UpdateUserFromCourseSign extends Command
|
|
|
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 课程体系优先级(高研班 > 攀峰班 > 初创班)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @var array
|
|
|
|
|
|
*/
|
|
|
|
|
|
protected $courseTypePriority = ['高研班', '攀峰班', '初创班'];
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 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()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 获取高研班、攀峰班、初创班三个课程体系下的课程 ID
|
|
|
|
|
|
$courseTypeIds = CourseType::whereIn('name', $this->courseTypePriority)->pluck('id')->toArray();
|
|
|
|
|
|
if (empty($courseTypeIds)) {
|
|
|
|
|
|
return $this->error('未找到高研班/攀峰班/初创班课程类型');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$courseIds = Course::whereIn('type', $courseTypeIds)->pluck('id')->toArray();
|
|
|
|
|
|
if (empty($courseIds)) {
|
|
|
|
|
|
return $this->error('三个课程体系下没有课程');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取这三个体系下所有有报名数据(data 不为空)的报名记录,再取去重用户
|
|
|
|
|
|
$userIds = CourseSign::whereIn('course_id', $courseIds)
|
|
|
|
|
|
->whereNotNull('user_id')
|
|
|
|
|
|
->whereNotNull('data')
|
|
|
|
|
|
->pluck('user_id')
|
|
|
|
|
|
->unique()
|
|
|
|
|
|
->values()
|
|
|
|
|
|
->toArray();
|
|
|
|
|
|
|
|
|
|
|
|
if (empty($userIds)) {
|
|
|
|
|
|
return $this->error('没有找到符合条件的报名用户');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$users = User::whereIn('id', $userIds)->get();
|
|
|
|
|
|
$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, $courseIds);
|
|
|
|
|
|
$successCount++;
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
|
$this->error("处理用户 {$user->name} 时出错:" . $e->getMessage());
|
|
|
|
|
|
$failCount++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$this->newLine();
|
|
|
|
|
|
return $this->info("全部处理完成!成功:{$successCount},失败:{$failCount}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理单个用户
|
|
|
|
|
|
* 按优先级(高研班 > 攀峰班 > 初创班)选定课程体系,取该体系下最新一条报名数据覆盖用户
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param \App\Models\User $user
|
|
|
|
|
|
* @param array $courseIds 高研班/攀峰班/初创班下的课程 ID 列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function processUser($user, array $courseIds)
|
|
|
|
|
|
{
|
|
|
|
|
|
$user_id = $user->id;
|
|
|
|
|
|
|
|
|
|
|
|
// 仅获取该用户在三个体系下的报名记录(携带课程及课程类型),按 created_at 倒序
|
|
|
|
|
|
$courseSigns = CourseSign::with('course.typeDetail')
|
|
|
|
|
|
->where('user_id', $user_id)
|
|
|
|
|
|
->whereIn('course_id', $courseIds)
|
|
|
|
|
|
->whereNotNull('data')
|
|
|
|
|
|
->orderByDesc('created_at')
|
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
|
|
if ($courseSigns->isEmpty()) {
|
|
|
|
|
|
$this->info('该用户在此三个体系下没有报名记录或报名记录中没有数据');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 按优先级确定使用的课程体系:有高研班用高研班,否则攀峰班,否则初创班
|
|
|
|
|
|
$selectedTypeName = null;
|
|
|
|
|
|
foreach ($this->courseTypePriority as $typeName) {
|
|
|
|
|
|
$hasSign = $courseSigns->contains(function ($sign) use ($typeName) {
|
|
|
|
|
|
$name = $sign->course->typeDetail->name ?? '';
|
|
|
|
|
|
return $name === $typeName;
|
|
|
|
|
|
});
|
|
|
|
|
|
if ($hasSign) {
|
|
|
|
|
|
$selectedTypeName = $typeName;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($selectedTypeName === null) {
|
|
|
|
|
|
$this->info('未匹配到高研班/攀峰班/初创班课程类型,跳过');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 只保留该体系下的报名,且已按 created_at 倒序,取最新一条
|
|
|
|
|
|
$targetSigns = $courseSigns->filter(function ($sign) use ($selectedTypeName) {
|
|
|
|
|
|
$name = $sign->course->typeDetail->name ?? '';
|
|
|
|
|
|
return $name === $selectedTypeName;
|
|
|
|
|
|
});
|
|
|
|
|
|
$latestSign = $targetSigns->first();
|
|
|
|
|
|
$this->info("使用课程体系【{$selectedTypeName}】下最新报名(course_sign_id: {$latestSign->id})覆盖用户数据");
|
|
|
|
|
|
|
|
|
|
|
|
// 从单条最新报名中提取用户字段
|
|
|
|
|
|
$userData = [];
|
|
|
|
|
|
$hasCompanyName = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (empty($latestSign->data) || !is_array($latestSign->data)) {
|
|
|
|
|
|
$this->info('该条报名 data 为空,无法更新用户');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$courseForms = CourseForm::where('course_id', $latestSign->course_id)
|
|
|
|
|
|
->where('belong_user', 1)
|
|
|
|
|
|
->whereNotNull('belong_user_table')
|
|
|
|
|
|
->where('belong_user_table', '!=', '')
|
|
|
|
|
|
->get(['field', 'belong_user_table']);
|
|
|
|
|
|
|
|
|
|
|
|
if ($courseForms->isEmpty()) {
|
|
|
|
|
|
$this->info('该课程无 belong_user 表单配置,跳过');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$fieldMapping = [];
|
|
|
|
|
|
foreach ($courseForms as $form) {
|
|
|
|
|
|
$fieldMapping[$form->field] = $form->belong_user_table;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$dataArray = [];
|
|
|
|
|
|
foreach ($latestSign->data as $item) {
|
|
|
|
|
|
if (isset($item['field'], $item['value'])) {
|
|
|
|
|
|
$dataArray[$item['field']] = $item['value'];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($fieldMapping as $field => $userTableField) {
|
|
|
|
|
|
if (isset($dataArray[$field]) && $dataArray[$field] !== null && $dataArray[$field] !== '') {
|
|
|
|
|
|
$userData[$userTableField] = $dataArray[$field];
|
|
|
|
|
|
if ($userTableField === 'company_name') {
|
|
|
|
|
|
$hasCompanyName = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (empty($userData)) {
|
|
|
|
|
|
$this->info('未解析出可更新的用户字段');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果用户已有 company_id 且存在对应的 company 数据,则不更新公司名字
|
|
|
|
|
|
if ($user->company_id) {
|
|
|
|
|
|
$hasCompany = Company::where('id', $user->company_id)->exists();
|
|
|
|
|
|
if ($hasCompany) {
|
|
|
|
|
|
// 有关联的 company 数据,移除 company_name 字段,不更新
|
|
|
|
|
|
if (isset($userData['company_name'])) {
|
|
|
|
|
|
unset($userData['company_name']);
|
|
|
|
|
|
$hasCompanyName = false;
|
|
|
|
|
|
$this->info('用户已有关联的 company 数据(company_id: ' . $user->company_id . '),跳过公司名字更新');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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('用户信息更新成功');
|
|
|
|
|
|
|
|
|
|
|
|
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}),跳过公司信息更新");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$this->info('用户更新完成');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|