master
cody 2 months ago
parent a5ab7d6076
commit 41e5f9345e

@ -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;
}
}
}
Loading…
Cancel
Save