v1.0.27: 碎片处理中心(完整方案) - 完整度计算引擎(四表分层/阈值)+is_incomplete标记(写操作挂钩)+api/fragment八接口(统计/硬碎片列表详情转换废弃/软碎片列表详情补全)+fragment.html前端(指标卡+硬软碎片双区块)
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
<?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';
|
||||
|
||||
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'] ?? ($frag['target_product_category'] ?? ''));
|
||||
$description = trim($_POST['description'] ?? ($frag['description'] ?? ''));
|
||||
$industry = trim($_POST['industry'] ?? '');
|
||||
$sourceChannel = $frag['source_channel'] ?? null;
|
||||
|
||||
$convertedId = 0;
|
||||
|
||||
/** 创建 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) {
|
||||
$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, source_channel) VALUES (?, ?, ?, ?)"
|
||||
)->execute([$companyName, $companyName, $industry !== '' ? $industry : null, $sourceChannel]);
|
||||
return (int)$pdo->lastInsertId();
|
||||
};
|
||||
|
||||
switch ($targetType) {
|
||||
case 'company':
|
||||
if ($companyName === '') {
|
||||
Response::error('公司名称为必填项', 400);
|
||||
}
|
||||
$pdo->prepare(
|
||||
"INSERT INTO companies (display_name, name_zh, industry, business_scope, source_channel, source_detail)
|
||||
VALUES (?, ?, ?, ?, ?, ?)"
|
||||
)->execute([
|
||||
$companyName, $companyName,
|
||||
$industry !== '' ? $industry : null,
|
||||
$description !== '' ? $description : null,
|
||||
$sourceChannel,
|
||||
$frag['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, $frag['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'] ?? ''));
|
||||
$needCategory = trim($_POST['need_category'] ?? '');
|
||||
$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], '转换成功');
|
||||
Reference in New Issue
Block a user