|
|
|
|
@ -0,0 +1,175 @@
|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
|
|
|
|
|
|
use App\Models\Course;
|
|
|
|
|
use App\Models\CourseSign;
|
|
|
|
|
use App\Models\User;
|
|
|
|
|
use Illuminate\Console\Command;
|
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
|
use Rap2hpoutre\FastExcel\FastExcel;
|
|
|
|
|
|
|
|
|
|
class UpdateUserTalentTags extends Command
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* The name and signature of the console command.
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
protected $signature = 'update:user-talent-tags';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The console command description.
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
protected $description = '从Excel文件读取人才标签并更新到用户表';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Execute the console command.
|
|
|
|
|
*
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function handle()
|
|
|
|
|
{
|
|
|
|
|
$this->info('开始读取Excel文件并更新用户人才标签...');
|
|
|
|
|
|
|
|
|
|
// Excel文件路径
|
|
|
|
|
$excelPath = base_path('科技商学院学员信息-匹配人才标签_匹配是否.xlsx');
|
|
|
|
|
|
|
|
|
|
// 检查文件是否存在
|
|
|
|
|
if (!file_exists($excelPath)) {
|
|
|
|
|
$this->error('Excel文件不存在: ' . $excelPath);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 读取Excel文件
|
|
|
|
|
$dataArray = (new FastExcel)->import($excelPath)->toArray();
|
|
|
|
|
|
|
|
|
|
if (empty($dataArray)) {
|
|
|
|
|
$this->warn('Excel文件为空或无法读取');
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->info('成功读取Excel文件,共 ' . count($dataArray) . ' 行数据');
|
|
|
|
|
|
|
|
|
|
$successCount = 0;
|
|
|
|
|
$notFoundCount = 0;
|
|
|
|
|
$errorCount = 0;
|
|
|
|
|
$skippedCount = 0;
|
|
|
|
|
|
|
|
|
|
DB::beginTransaction();
|
|
|
|
|
|
|
|
|
|
foreach ($dataArray as $index => $row) {
|
|
|
|
|
$rowNum = $index + 2; // Excel行号(从第2行开始,第1行是表头)
|
|
|
|
|
|
|
|
|
|
// 获取必要字段
|
|
|
|
|
$courseName = trim($row['课程名称'] ?? '');
|
|
|
|
|
$userName = trim($row['姓名'] ?? '');
|
|
|
|
|
$talentTag = trim($row['人才标签'] ?? '');
|
|
|
|
|
|
|
|
|
|
// 跳过空行
|
|
|
|
|
if (empty($courseName) && empty($userName)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证必要字段
|
|
|
|
|
if (empty($courseName)) {
|
|
|
|
|
$this->warn("第 {$rowNum} 行: 课程名称为空,跳过");
|
|
|
|
|
$skippedCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($userName)) {
|
|
|
|
|
$this->warn("第 {$rowNum} 行: 姓名为空,跳过");
|
|
|
|
|
$skippedCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($talentTag)) {
|
|
|
|
|
$this->warn("第 {$rowNum} 行: 人才标签为空,跳过");
|
|
|
|
|
$skippedCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 通过课程名称查找课程
|
|
|
|
|
$course = Course::where('name', $courseName)->first();
|
|
|
|
|
|
|
|
|
|
if (!$course) {
|
|
|
|
|
$this->warn("第 {$rowNum} 行: 未找到课程 '{$courseName}',跳过");
|
|
|
|
|
$notFoundCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 通过课程ID和姓名查找用户(通过CourseSign关联)
|
|
|
|
|
$courseSign = CourseSign::where('course_id', $course->id)
|
|
|
|
|
->whereHas('user', function ($query) use ($userName) {
|
|
|
|
|
$query->where('name', $userName);
|
|
|
|
|
})
|
|
|
|
|
->with('user')
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
if (!$courseSign || !$courseSign->user) {
|
|
|
|
|
$this->warn("第 {$rowNum} 行: 未找到用户 '{$userName}' 在课程 '{$courseName}' 中的报名记录,跳过");
|
|
|
|
|
$notFoundCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$user = $courseSign->user;
|
|
|
|
|
|
|
|
|
|
// 处理人才标签,避免重复
|
|
|
|
|
$existingTags = $user->talent_tags;
|
|
|
|
|
$existingTagsArray = [];
|
|
|
|
|
|
|
|
|
|
if (!empty($existingTags)) {
|
|
|
|
|
// 将现有标签转换为数组
|
|
|
|
|
$existingTagsArray = array_filter(array_map('trim', explode(',', $existingTags)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查新标签是否已存在
|
|
|
|
|
if (in_array($talentTag, $existingTagsArray)) {
|
|
|
|
|
$this->info("第 {$rowNum} 行: 用户 '{$userName}' 已存在标签 '{$talentTag}',跳过");
|
|
|
|
|
$skippedCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加新标签
|
|
|
|
|
$existingTagsArray[] = $talentTag;
|
|
|
|
|
$existingTagsArray = array_values(array_unique($existingTagsArray)); // 去重并重新索引
|
|
|
|
|
$newTalentTags = implode(',', $existingTagsArray);
|
|
|
|
|
|
|
|
|
|
// 更新用户
|
|
|
|
|
try {
|
|
|
|
|
$user->talent_tags = $newTalentTags;
|
|
|
|
|
$user->save();
|
|
|
|
|
|
|
|
|
|
$this->info("第 {$rowNum} 行: 成功更新用户 '{$userName}' (ID: {$user->id}) 的人才标签: {$newTalentTags}");
|
|
|
|
|
$successCount++;
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$this->error("第 {$rowNum} 行: 更新用户 '{$userName}' 失败: " . $e->getMessage());
|
|
|
|
|
$errorCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DB::commit();
|
|
|
|
|
|
|
|
|
|
// 输出统计信息
|
|
|
|
|
$this->info('');
|
|
|
|
|
$this->info('========================================');
|
|
|
|
|
$this->info('更新完成!统计信息:');
|
|
|
|
|
$this->info("成功更新: {$successCount} 条");
|
|
|
|
|
$this->info("未找到记录: {$notFoundCount} 条");
|
|
|
|
|
$this->info("跳过(已存在/空数据): {$skippedCount} 条");
|
|
|
|
|
$this->info("更新失败: {$errorCount} 条");
|
|
|
|
|
$this->info('========================================');
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
DB::rollBack();
|
|
|
|
|
$this->error('处理Excel文件时发生错误: ' . $e->getMessage());
|
|
|
|
|
$this->error('错误堆栈: ' . $e->getTraceAsString());
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|