Files
superlink/api/fragment/hard_convert.php
T

230 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 硬碎片转换为主表接口 POST /api/fragment/hard_convert.php
* 入参:id(硬碎片ID,必填)/ target_type(company|person|product|need,必填)/
* 补全字段:company_name, person_name, contact_phone, contact_email, target_product_category,
* description, industry, need_category, application_scenario, contact_person
* 逻辑:按目标类型写入主表(product/need 缺公司时自动建公司)→ 标记碎片已转换(converted_type/id, processed_at)
*/
require_once __DIR__ . '/../common/db.php';
require_once __DIR__ . '/../common/response.php';
require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
require_once __DIR__ . '/../common/validate.php';
checkAjax();
checkPermission('preliminary');
$id = (int)($_POST['id'] ?? 0);
$targetType = trim($_POST['target_type'] ?? '');
if ($id <= 0 || !in_array($targetType, ['company', 'person', 'product', 'need'], true)) {
Response::error('参数错误', 400);
}
$pdo = DB::getInstance()->getPdo();
$stmt = $pdo->prepare("SELECT * FROM preliminary_data WHERE id = ? AND is_active = 1");
$stmt->execute([$id]);
$frag = $stmt->fetch();
if (!$frag) {
Response::error('碎片不存在');
}
if (in_array($frag['status'], ['已转换', '已废弃'], true)) {
Response::error('该碎片已处理(' . $frag['status'] . ')');
}
$companyName = trim($_POST['company_name'] ?? ($frag['company_name'] ?? ''));
$personName = trim($_POST['person_name'] ?? ($frag['person_name'] ?? ''));
$phone = trim($_POST['contact_phone'] ?? ($frag['contact_phone'] ?? ''));
$email = trim($_POST['contact_email'] ?? ($frag['contact_email'] ?? ''));
$industry = trim($_POST['industry'] ?? ($frag['industry'] ?? '')); // 核心-企业(转软碎片必填)
$registrationNum = trim($_POST['registration_number'] ?? ($frag['registration_number'] ?? '')); // 核心-企业(转软碎片必填)
$businessRole = trim($_POST['business_role'] ?? ($frag['business_role'] ?? ''));
$country = trim($_POST['country'] ?? ($frag['country'] ?? ''));
$address = trim($_POST['address'] ?? ($frag['address'] ?? ''));
$workLocation = trim($_POST['work_location'] ?? ($frag['work_location'] ?? ''));
$idNumber = trim($_POST['id_number'] ?? ($frag['id_number'] ?? ''));
$platform = trim($_POST['platform'] ?? ($frag['platform'] ?? ''));
$accountId = trim($_POST['account_id'] ?? ($frag['account_id'] ?? ''));
$profileUrl = trim($_POST['profile_url'] ?? ($frag['profile_url'] ?? ''));
$sourceChannel = $frag['source_channel'] ?? null;
$convertedId = 0;
// 格式校验:手机 / 邮箱 / 身份证 / 主页链接
checkFieldFormat('phone', $phone);
checkFieldFormat('email', $email);
checkFieldFormat('id_number', $idNumber);
if ($profileUrl !== '' && !preg_match('/^https?:\/\//i', $profileUrl)) {
Response::error('主页链接格式不正确(应以 http:// 或 https:// 开头)', 400);
}
// 各类型转软碎片基本要求
switch ($targetType) {
case 'company':
if ($companyName === '') {
Response::error('企业类型转软碎片:企业名称为必填项,请先「继续补全」', 400);
}
if ($industry === '') {
Response::error('企业类型转软碎片:行业为必填项,请先「继续补全」填写行业', 400);
}
if ($registrationNum === '') {
Response::error('企业类型转软碎片:注册号为必填项,请先「继续补全」填写注册号', 400);
}
break;
case 'person':
if ($personName === '') {
Response::error('人员类型转软碎片:姓名为必填项,请先「继续补全」', 400);
}
if ($phone === '' && $email === '') {
Response::error('人员类型转软碎片:手机号码、邮箱至少填写一项,请先「继续补全」', 400);
}
break;
case 'product':
if ($companyName === '') {
Response::error('产品类型转软碎片:公司名称为必填项,请先「继续补全」', 400);
}
break;
case 'need':
if ($companyName === '') {
Response::error('需求类型转软碎片:公司名称为必填项,请先「继续补全」', 400);
}
break;
}
// 唯一性校验:按目标类型,收集全部重复
$dups = [];
if ($targetType === 'company' && $companyName !== '') {
$dup = findDuplicate($pdo, 'company_name', $companyName);
if ($dup) $dups[] = $dup;
}
if (in_array($targetType, ['person', 'company'], true)) {
$dups = array_merge($dups, checkSingleAccountDuplicate($pdo, $phone !== '' ? 'phone' : '', $phone, ''));
$dups = array_merge($dups, checkSingleAccountDuplicate($pdo, $email !== '' ? 'email' : '', $email, ''));
}
if (!empty($dups)) Response::duplicates($dups);
/** 创建 social_accounts(phone/email,常用) */
$saveContacts = function ($ownerType, $ownerId) use ($pdo, $phone, $email) {
if ($phone !== '') {
$pdo->prepare(
"INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, is_primary, is_defult)
VALUES (?, ?, 'phone', ?, 1, 1)"
)->execute([$ownerType, $ownerId, $phone]);
}
if ($email !== '') {
$pdo->prepare(
"INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, is_primary, is_defult)
VALUES (?, ?, 'email', ?, 1, 1)"
)->execute([$ownerType, $ownerId, $email]);
}
};
/** 写入社媒账号(platform + account_id,主页链接作备注) */
function saveSocialAccountIfAny(PDO $pdo, $ownerType, $ownerId, $platform, $accountId, $profileUrl = '')
{
$platform = trim((string)$platform);
$accountId = trim((string)$accountId);
if ($platform === '' || $accountId === '' || in_array($platform, ['phone', 'email'], true)) {
return;
}
$pdo->prepare(
"INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, profile_url, is_primary, is_defult)
VALUES (?, ?, ?, ?, ?, 0, 0)"
)->execute([$ownerType, $ownerId, $platform, $accountId, trim((string)$profileUrl) !== '' ? $profileUrl : null]);
}
/** 按名称找公司,找不到则自动创建 */
$resolveCompany = function () use ($pdo, $companyName, $sourceChannel, $industry, $registrationNum) {
$stmt = $pdo->prepare("SELECT id FROM companies WHERE display_name = ? AND is_active = 1 LIMIT 1");
$stmt->execute([$companyName]);
$cid = (int)$stmt->fetchColumn();
if ($cid > 0) {
return $cid;
}
$pdo->prepare(
"INSERT INTO companies (display_name, name_zh, industry, registration_number, source_channel) VALUES (?, ?, ?, ?, ?)"
)->execute([$companyName, $companyName, $industry !== '' ? $industry : null, $registrationNum !== '' ? $registrationNum : null, $sourceChannel]);
return (int)$pdo->lastInsertId();
};
switch ($targetType) {
case 'company':
$pdo->prepare(
"INSERT INTO companies (display_name, name_zh, industry, registration_number, business_role, country, address, source_channel)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
)->execute([
$companyName, $companyName,
$industry !== '' ? $industry : null,
$registrationNum !== '' ? $registrationNum : null,
$businessRole !== '' ? $businessRole : null,
$country !== '' ? $country : null,
$address !== '' ? $address : null,
$sourceChannel,
]);
$convertedId = (int)$pdo->lastInsertId();
$saveContacts('company', $convertedId);
saveSocialAccountIfAny($pdo, 'company', $convertedId, $platform, $accountId, $profileUrl);
updateIncomplete($pdo, 'companies', $convertedId);
updateAccountsIncomplete($pdo, 'company', $convertedId);
break;
case 'person':
$unionId = 'P' . date('YmdHis') . substr(uniqid(), -6);
$pdo->prepare(
"INSERT INTO persons (union_id, full_name, work_location, id_number, source_channel) VALUES (?, ?, ?, ?, ?)"
)->execute([
$unionId, $personName,
$workLocation !== '' ? $workLocation : null,
$idNumber !== '' ? $idNumber : null,
$sourceChannel,
]);
$convertedId = (int)$pdo->lastInsertId();
$saveContacts('person', $convertedId);
saveSocialAccountIfAny($pdo, 'person', $convertedId, $platform, $accountId, $profileUrl);
updateIncomplete($pdo, 'persons', $convertedId);
updateAccountsIncomplete($pdo, 'person', $convertedId);
break;
case 'product':
$companyId = $resolveCompany();
// 品类字段已在 preliminary 移除(非必要/待定),转换时默认「未分类」
$pdo->prepare(
"INSERT INTO company_products (company_id, category_name)
VALUES (?, '未分类')"
)->execute([$companyId]);
$convertedId = (int)$pdo->lastInsertId();
updateIncomplete($pdo, 'companies', $companyId);
break;
case 'need':
$companyId = $resolveCompany();
$contactPerson = trim($_POST['contact_person'] ?? ($frag['person_name'] ?? ''));
$pdo->prepare(
"INSERT INTO company_needs (company_id, contact_person, description)
VALUES (?, ?, ?)"
)->execute([
$companyId,
$contactPerson !== '' ? $contactPerson : null,
null,
]);
$convertedId = (int)$pdo->lastInsertId();
updateIncomplete($pdo, 'companies', $companyId);
break;
}
// 标记碎片已转换
$pdo->prepare(
"UPDATE preliminary_data SET status = '已转换', converted_type = ?, converted_id = ?, processed_at = NOW() WHERE id = ?"
)->execute([$targetType, $convertedId, $id]);
logCurrent('convert', 'fragment', 'preliminary_data', $id, [
'target_type' => $targetType,
'converted_id' => $convertedId,
'fields' => ['company_name' => $companyName, 'person_name' => $personName, 'phone' => $phone, 'email' => $email],
]);
Response::success(['converted_type' => $targetType, 'converted_id' => $convertedId], '转换成功');