c86f08c325
Co-Authored-By: Claude Code <noreply@anthropic.com>
83 lines
3.1 KiB
PHP
83 lines
3.1 KiB
PHP
<?php
|
|
/**
|
|
* 人员 CSV 导入接口 POST /api/person/import.php (multipart/form-data, 字段名 file)
|
|
* CSV 表头:union_id,full_name,gender,nationality,id_type,id_number,education,
|
|
* graduated_from,hometown,work_location,phone,email,source_channel,source_detail
|
|
* 仅 full_name 必填;union_id 留空自动生成;phone/email 写入 social_accounts(默认常用)。
|
|
*/
|
|
require_once __DIR__ . '/../common/Api.php';
|
|
$pdo = Api::boot(['module' => 'person']);
|
|
|
|
|
|
if (empty($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
|
|
Response::error('请选择要上传的CSV文件', 400);
|
|
}
|
|
|
|
$handle = fopen($_FILES['file']['tmp_name'], 'r');
|
|
if (!$handle) {
|
|
Response::error('无法读取文件', 400);
|
|
}
|
|
$first = preg_replace('/^\xEF\xBB\xBF/', '', fgets($handle));
|
|
$header = str_getcsv(trim($first));
|
|
|
|
$pdo = DB::getInstance()->getPdo();
|
|
$insPerson = $pdo->prepare(
|
|
"INSERT INTO persons (union_id, full_name, gender, nationality, id_type, id_number, education, graduated_from, hometown, work_location, source_channel, source_detail)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"
|
|
);
|
|
$insAccount = $pdo->prepare(
|
|
"INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, is_defult)
|
|
VALUES ('person', ?, ?, ?, 1)"
|
|
);
|
|
|
|
$inserted = 0;
|
|
$failed = 0;
|
|
|
|
while (($row = fgetcsv($handle)) !== false) {
|
|
$row = array_map('trim', $row);
|
|
$rec = [];
|
|
foreach ($header as $idx => $col) {
|
|
$col = trim($col);
|
|
if (isset($row[$idx])) {
|
|
$rec[$col] = $row[$idx];
|
|
}
|
|
}
|
|
if (empty($rec['full_name'])) {
|
|
$failed++;
|
|
continue;
|
|
}
|
|
try {
|
|
$unionId = !empty($rec['union_id']) ? $rec['union_id'] : ('P' . date('YmdHis') . substr(uniqid(), -6));
|
|
// 跳过重复 union_id
|
|
$chk = $pdo->prepare("SELECT COUNT(*) FROM persons WHERE union_id = ?");
|
|
$chk->execute([$unionId]);
|
|
if ((int)$chk->fetchColumn() > 0) {
|
|
$failed++;
|
|
continue;
|
|
}
|
|
$insPerson->execute([
|
|
$unionId, $rec['full_name'], $rec['gender'] ?? '未知', $rec['nationality'] ?? null,
|
|
$rec['id_type'] ?? null, $rec['id_number'] ?? null, $rec['education'] ?? null,
|
|
$rec['graduated_from'] ?? null, $rec['hometown'] ?? null, $rec['work_location'] ?? null,
|
|
$rec['source_channel'] ?? null, $rec['source_detail'] ?? null,
|
|
]);
|
|
$newId = (int)$pdo->lastInsertId();
|
|
if (!empty($rec['phone'])) {
|
|
$insAccount->execute([$newId, 'phone', $rec['phone']]);
|
|
}
|
|
if (!empty($rec['email'])) {
|
|
$insAccount->execute([$newId, 'email', $rec['email']]);
|
|
}
|
|
// 完整度检查(导入每行入库后)
|
|
updateIncomplete($pdo, 'persons', $newId);
|
|
updateAccountsIncomplete($pdo, 'person', $newId);
|
|
$inserted++;
|
|
} catch (Exception $e) {
|
|
$failed++;
|
|
}
|
|
}
|
|
fclose($handle);
|
|
|
|
logCurrent('import', 'person', 'persons', null, ['inserted' => $inserted, 'failed' => $failed]);
|
|
Response::success(['inserted' => $inserted, 'failed' => $failed], "导入完成:成功 $inserted 条,失败 $failed 条");
|