元禾参与/干部培训 导入

master
lion 2 days ago
parent 5460b39f6c
commit 0f1a721b0e

@ -246,64 +246,145 @@ class EmployeeParticipationController extends BaseController
$tempFile = $file->getRealPath();
$dataArray = (new FastExcel)->import($tempFile)->toArray();
// 类型映射:中文 => 数字
// 类型映射:兼容页面文案、库字段备注、数字
$typeMapping = [
'元禾员工参与' => 1,
'元和员工参与' => 1,
'员工参与数' => 1,
'员工参与' => 1,
'1' => 1,
'干部培训' => 2,
'干部培训数' => 2,
'2' => 2,
];
// 类型名称映射:数字 => 中文
$typeNameMapping = [
1 => '元禾员工参与',
2 => '干部培训',
];
$list = [];
foreach ($dataArray as $key => $value) {
$list[$key] = [];
// 只读取 Excel 中的字段:类型、课程名称、公司名称、姓名、部门
$courseName = $value['课程名称'] ?? null;
$typeText = $value['类型'] ?? null;
foreach ($dataArray as $value) {
if ($value instanceof \Illuminate\Support\Collection) {
$value = $value->toArray();
}
if (!is_array($value)) {
continue;
}
$row = $this->normalizeExcelRow($value);
$courseName = $this->getExcelCell($row, ['课程名称']);
$typeText = $this->getExcelCell($row, ['类型']);
$companyName = $this->getExcelCell($row, ['公司名称', '公司名字']);
$name = $this->getExcelCell($row, ['姓名']);
$department = $this->getExcelCell($row, ['部门']);
$total = $this->getExcelCell($row, ['数量']);
// 转换类型:中文 -> 数字
$type = null;
if ($typeText) {
$type = $typeMapping[$typeText] ?? null;
// 跳过模板说明行、空行
if ($this->isExcelInstructionRow($typeText, $courseName, $companyName, $name, $department)) {
continue;
}
// 根据课程名称查找课程信息
$type = $this->parseParticipationType($typeText, $typeMapping);
$course = null;
if ($courseName) {
$course = Course::where('name', $courseName)->first();
}
// 填充基础字段
$list[$key]['type'] = $type;
$list[$key]['type_name'] = $type ? ($typeNameMapping[$type] ?? '') : '';
$list[$key]['course_name'] = $courseName;
$list[$key]['company_name'] = $value['公司名称'] ?? null;
$list[$key]['name'] = $value['姓名'] ?? null;
$list[$key]['department'] = $value['部门'] ?? null;
$list[$key]['total'] = $value['数量'] ?? 1;
$item = [
'type' => $type,
'type_name' => $type ? ($typeNameMapping[$type] ?? '') : '',
'course_name' => $courseName,
'company_name' => $companyName,
'name' => $name,
'department' => $department,
'total' => $total !== null && $total !== '' ? $total : 1,
];
// 根据课程信息填充其他字段
if ($course) {
$list[$key]['start_date'] = $course->start_date;
$list[$key]['end_date'] = $course->end_date;
$list[$key]['course_type_id'] = $course->type;
$list[$key]['course_id'] = $course->id;
$item['start_date'] = $course->start_date;
$item['end_date'] = $course->end_date;
$item['course_type_id'] = $course->type;
$item['course_id'] = $course->id;
} else {
// 如果找不到课程,字段设为 null
$list[$key]['start_date'] = null;
$list[$key]['end_date'] = null;
$list[$key]['course_type_id'] = null;
$list[$key]['course_id'] = null;
$item['start_date'] = null;
$item['end_date'] = null;
$item['course_type_id'] = null;
$item['course_id'] = null;
}
$list[] = $item;
}
return $this->success($list);
}
/**
* 去掉表头空格,避免 FastExcel 读到「类型 」导致取不到值
*/
private function normalizeExcelRow(array $row): array
{
$normalized = [];
foreach ($row as $key => $cell) {
$header = trim((string)$key);
if ($header === '') {
continue;
}
if (is_string($cell)) {
$cell = trim($cell);
}
$normalized[$header] = $cell;
}
return $normalized;
}
/**
* 按候选表头取值兼容「类型1员工参与数2干部培训数」这类备注表头
*/
private function getExcelCell(array $row, array $candidates)
{
foreach ($candidates as $name) {
if (array_key_exists($name, $row) && $row[$name] !== null && $row[$name] !== '') {
return $row[$name];
}
}
foreach ($row as $header => $cell) {
foreach ($candidates as $name) {
if (mb_strpos((string)$header, $name) !== false && $cell !== null && $cell !== '') {
return $cell;
}
}
}
return null;
}
private function isExcelInstructionRow($typeText, $courseName, $companyName, $name, $department): bool
{
$hasData = !empty($courseName) || !empty($companyName) || !empty($name) || !empty($department);
$typeString = is_scalar($typeText) ? trim((string)$typeText) : '';
$isTip = $typeString !== '' && (mb_strpos($typeString, '请填入') !== false || mb_strpos($typeString, '请确保') !== false);
// 纯说明行才跳过;同一行如果已经填了业务数据则保留,类型按空处理
if ($isTip && !$hasData) {
return true;
}
return $typeString === '' && !$hasData;
}
private function parseParticipationType($typeText, array $typeMapping): ?int
{
if ($typeText === null || $typeText === '' || !is_scalar($typeText)) {
return null;
}
if (is_numeric($typeText) && (int)$typeText > 0) {
$numeric = (int)$typeText;
return in_array($numeric, [1, 2], true) ? $numeric : null;
}
$typeString = trim((string)$typeText);
if (mb_strpos($typeString, '请填入') !== false || mb_strpos($typeString, '请确保') !== false) {
return null;
}
return $typeMapping[$typeString] ?? null;
}
/**
* @OA\Post(
* path="/api/admin/employee-participations/import",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save