Files
superlink/api/fragment/hard_convert.php
T

227 lines
9.8 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'] ?? ''));
$category = trim($_POST['target_product_category'] ?? ''); // 仅补全录入表单提供(表中已无该字段)
$description = trim($_POST['description'] ?? ''); // 仅补全录入表单提供
$industry = trim($_POST['industry'] ?? ($frag['industry'] ?? '')); // 企业:行业(转软碎片必填)
$registrationNum = trim($_POST['registration_number'] ?? ($frag['registration_number'] ?? '')); // 企业:注册号(转软碎片必填)
$sourceChannel = $frag['source_channel'] ?? null;
// 补全表单额外信息(extra_info)
$fragExtra = json_decode($frag['extra_info'] ?? 'null', true);
if (!is_array($fragExtra)) {
$fragExtra = [];
}
if ($category === '') $category = trim((string)($fragExtra['category'] ?? ''));
$needCategory = trim($_POST['need_category'] ?? ($fragExtra['need_category'] ?? ''));
$convertedId = 0;
// 格式校验:手机 / 邮箱
checkFieldFormat('phone', $phone);
checkFieldFormat('email', $email);
// 各类型转软碎片基本要求
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);
}
if ($category === '') {
Response::error('产品类型转软碎片:产品品类为必填项,请先「继续补全」填写品类', 400);
}
break;
case 'need':
if ($companyName === '') {
Response::error('需求类型转软碎片:公司名称为必填项,请先「继续补全」', 400);
}
if ($needCategory === '') {
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]);
}
};
/** 按名称找公司,找不到则自动创建 */
$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_scope, source_channel, source_detail)
VALUES (?, ?, ?, ?, ?, ?, ?)"
)->execute([
$companyName, $companyName,
$industry !== '' ? $industry : null,
$registrationNum !== '' ? $registrationNum : null,
$description !== '' ? $description : null,
$sourceChannel,
$description !== '' ? $description : null,
]);
$convertedId = (int)$pdo->lastInsertId();
$saveContacts('company', $convertedId);
updateIncomplete($pdo, 'companies', $convertedId);
updateAccountsIncomplete($pdo, 'company', $convertedId);
break;
case 'person':
if ($personName === '') {
Response::error('联系人为必填项', 400);
}
$unionId = 'P' . date('YmdHis') . substr(uniqid(), -6);
$pdo->prepare(
"INSERT INTO persons (union_id, full_name, source_channel, source_detail) VALUES (?, ?, ?, ?)"
)->execute([$unionId, $personName, $sourceChannel, $description !== '' ? $description : null]);
$convertedId = (int)$pdo->lastInsertId();
$saveContacts('person', $convertedId);
updateIncomplete($pdo, 'persons', $convertedId);
updateAccountsIncomplete($pdo, 'person', $convertedId);
break;
case 'product':
if ($companyName === '') {
Response::error('公司名称为必填项', 400);
}
if ($category === '') {
Response::error('产品品类为必填项', 400);
}
$companyId = $resolveCompany();
$pdo->prepare(
"INSERT INTO company_products (company_id, category_name, category_description)
VALUES (?, ?, ?)"
)->execute([$companyId, $category, $description !== '' ? $description : null]);
$convertedId = (int)$pdo->lastInsertId();
updateIncomplete($pdo, 'companies', $companyId);
break;
case 'need':
if ($companyName === '') {
Response::error('公司名称为必填项', 400);
}
$companyId = $resolveCompany();
$contactPerson = trim($_POST['contact_person'] ?? ($frag['person_name'] ?? ''));
$scenario = trim($_POST['application_scenario'] ?? '');
$pdo->prepare(
"INSERT INTO company_needs (company_id, contact_person, need_category, target_product_category, application_scenario, description)
VALUES (?, ?, ?, ?, ?, ?)"
)->execute([
$companyId,
$contactPerson !== '' ? $contactPerson : null,
$needCategory !== '' ? $needCategory : null,
$category !== '' ? $category : null,
$scenario !== '' ? $scenario : null,
$description !== '' ? $description : 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], '转换成功');