v1.0.48: preliminary_data重构按三层原则 - 核心+重要字段正式化(business_role/country/address/work_location/id_number/platform/account_id/profile_url新增列,身份证/社媒/主页从extra_info提为正式列)+删除extra_info(品类/需求类别等非必要不再存放)+表单/转换/列表全部适配(product品类默认未分类)
This commit is contained in:
+26
-23
@@ -22,17 +22,19 @@ if (!in_array($sourceType, ['company', 'person', 'product', 'need', 'mixed'], tr
|
|||||||
}
|
}
|
||||||
|
|
||||||
$companyName = trim($_POST['company_name'] ?? '');
|
$companyName = trim($_POST['company_name'] ?? '');
|
||||||
|
$industry = trim($_POST['industry'] ?? ''); // 核心-企业
|
||||||
|
$registrationNum = trim($_POST['registration_number'] ?? ''); // 核心-企业
|
||||||
|
$businessRole = trim($_POST['business_role'] ?? ''); // 重要-企业
|
||||||
|
$country = trim($_POST['country'] ?? ''); // 重要-企业
|
||||||
|
$address = trim($_POST['address'] ?? ''); // 重要-企业
|
||||||
$personName = trim($_POST['person_name'] ?? '');
|
$personName = trim($_POST['person_name'] ?? '');
|
||||||
$phone = trim($_POST['contact_phone'] ?? '');
|
$phone = trim($_POST['contact_phone'] ?? '');
|
||||||
$email = trim($_POST['contact_email'] ?? '');
|
$email = trim($_POST['contact_email'] ?? '');
|
||||||
$idNumber = trim($_POST['id_number'] ?? '');
|
$workLocation = trim($_POST['work_location'] ?? ''); // 重要-人员
|
||||||
$platform = trim($_POST['platform'] ?? '');
|
$idNumber = trim($_POST['id_number'] ?? ''); // 重要-人员
|
||||||
$accountId = trim($_POST['account_id'] ?? '');
|
$platform = trim($_POST['platform'] ?? ''); // 核心-社媒
|
||||||
$profileUrl = trim($_POST['profile_url'] ?? '');
|
$accountId = trim($_POST['account_id'] ?? ''); // 核心-社媒
|
||||||
$industry = trim($_POST['industry'] ?? ''); // 企业:行业
|
$profileUrl = trim($_POST['profile_url'] ?? ''); // 重要-主页
|
||||||
$registrationNum = trim($_POST['registration_number'] ?? ''); // 企业:注册号
|
|
||||||
$category = trim($_POST['target_product_category'] ?? ''); // 产品:品类(存 extra)
|
|
||||||
$needCategory = trim($_POST['need_category'] ?? ''); // 需求:需求类别(存 extra)
|
|
||||||
$sourceChannel = trim($_POST['source_channel'] ?? '');
|
$sourceChannel = trim($_POST['source_channel'] ?? '');
|
||||||
|
|
||||||
// 硬数据标准校验:
|
// 硬数据标准校验:
|
||||||
@@ -74,36 +76,35 @@ if ($accountId !== '' && $platform !== '') {
|
|||||||
}
|
}
|
||||||
if (!empty($dups)) Response::duplicates($dups);
|
if (!empty($dups)) Response::duplicates($dups);
|
||||||
|
|
||||||
// 额外信息(身份证/社媒平台/账号ID/主页链接/产品品类/需求类别)存 extra_info
|
|
||||||
$extra = [];
|
|
||||||
if ($idNumber !== '') $extra['id_number'] = $idNumber;
|
|
||||||
if ($platform !== '') $extra['platform'] = $platform;
|
|
||||||
if ($accountId !== '') $extra['account_id'] = $accountId;
|
|
||||||
if ($profileUrl !== '') $extra['profile_url'] = $profileUrl;
|
|
||||||
if ($category !== '') $extra['category'] = $category;
|
|
||||||
if ($needCategory !== '') $extra['need_category'] = $needCategory;
|
|
||||||
|
|
||||||
// 至少有一项内容才能录为碎片
|
// 至少有一项内容才能录为碎片
|
||||||
if ($companyName === '' && $personName === '' && $phone === '' && $email === '' && !$extra) {
|
if ($companyName === '' && $personName === '' && $phone === '' && $email === '' && $idNumber === '' && $accountId === '') {
|
||||||
Response::error('请至少填写一项内容', 400);
|
Response::error('请至少填写一项内容', 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$pdo->prepare(
|
$pdo->prepare(
|
||||||
"INSERT INTO preliminary_data
|
"INSERT INTO preliminary_data
|
||||||
(source_type, company_name, industry, registration_number, person_name, contact_phone, contact_email,
|
(source_type, company_name, industry, registration_number, business_role, country, address,
|
||||||
source_channel, recorded_by, status, extra_info)
|
person_name, contact_phone, contact_email, work_location, id_number, platform, account_id, profile_url,
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, '待处理', ?)"
|
source_channel, recorded_by, status)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '待处理')"
|
||||||
)->execute([
|
)->execute([
|
||||||
$sourceType,
|
$sourceType,
|
||||||
$companyName !== '' ? $companyName : null,
|
$companyName !== '' ? $companyName : null,
|
||||||
$industry !== '' ? $industry : null,
|
$industry !== '' ? $industry : null,
|
||||||
$registrationNum !== '' ? $registrationNum : null,
|
$registrationNum !== '' ? $registrationNum : null,
|
||||||
|
$businessRole !== '' ? $businessRole : null,
|
||||||
|
$country !== '' ? $country : null,
|
||||||
|
$address !== '' ? $address : null,
|
||||||
$personName !== '' ? $personName : null,
|
$personName !== '' ? $personName : null,
|
||||||
$phone !== '' ? $phone : null,
|
$phone !== '' ? $phone : null,
|
||||||
$email !== '' ? $email : null,
|
$email !== '' ? $email : null,
|
||||||
|
$workLocation !== '' ? $workLocation : null,
|
||||||
|
$idNumber !== '' ? $idNumber : null,
|
||||||
|
$platform !== '' ? $platform : null,
|
||||||
|
$accountId !== '' ? $accountId : null,
|
||||||
|
$profileUrl !== '' ? $profileUrl : null,
|
||||||
$sourceChannel !== '' ? $sourceChannel : null, // 未选择来源保持空白
|
$sourceChannel !== '' ? $sourceChannel : null, // 未选择来源保持空白
|
||||||
$_SESSION['username'] ?? null,
|
$_SESSION['username'] ?? null,
|
||||||
$extra ? json_encode($extra, JSON_UNESCAPED_UNICODE) : null,
|
|
||||||
]);
|
]);
|
||||||
$newId = (int)$pdo->lastInsertId();
|
$newId = (int)$pdo->lastInsertId();
|
||||||
|
|
||||||
@@ -113,7 +114,9 @@ logCurrent('add', 'fragment', 'preliminary_data', $newId, [
|
|||||||
'person_name' => $personName,
|
'person_name' => $personName,
|
||||||
'phone' => $phone,
|
'phone' => $phone,
|
||||||
'email' => $email,
|
'email' => $email,
|
||||||
'extra' => $extra,
|
'id_number' => $idNumber,
|
||||||
|
'platform' => $platform,
|
||||||
|
'account_id' => $accountId,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Response::success(['id' => $newId], '新增成功');
|
Response::success(['id' => $newId], '新增成功');
|
||||||
|
|||||||
@@ -39,25 +39,27 @@ $companyName = trim($_POST['company_name'] ?? ($frag['company_name'] ?? ''));
|
|||||||
$personName = trim($_POST['person_name'] ?? ($frag['person_name'] ?? ''));
|
$personName = trim($_POST['person_name'] ?? ($frag['person_name'] ?? ''));
|
||||||
$phone = trim($_POST['contact_phone'] ?? ($frag['contact_phone'] ?? ''));
|
$phone = trim($_POST['contact_phone'] ?? ($frag['contact_phone'] ?? ''));
|
||||||
$email = trim($_POST['contact_email'] ?? ($frag['contact_email'] ?? ''));
|
$email = trim($_POST['contact_email'] ?? ($frag['contact_email'] ?? ''));
|
||||||
$category = trim($_POST['target_product_category'] ?? ''); // 仅补全录入表单提供(表中已无该字段)
|
$industry = trim($_POST['industry'] ?? ($frag['industry'] ?? '')); // 核心-企业(转软碎片必填)
|
||||||
$description = trim($_POST['description'] ?? ''); // 仅补全录入表单提供
|
$registrationNum = trim($_POST['registration_number'] ?? ($frag['registration_number'] ?? '')); // 核心-企业(转软碎片必填)
|
||||||
$industry = trim($_POST['industry'] ?? ($frag['industry'] ?? '')); // 企业:行业(转软碎片必填)
|
$businessRole = trim($_POST['business_role'] ?? ($frag['business_role'] ?? ''));
|
||||||
$registrationNum = trim($_POST['registration_number'] ?? ($frag['registration_number'] ?? '')); // 企业:注册号(转软碎片必填)
|
$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;
|
$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;
|
$convertedId = 0;
|
||||||
|
|
||||||
// 格式校验:手机 / 邮箱
|
// 格式校验:手机 / 邮箱 / 身份证 / 主页链接
|
||||||
checkFieldFormat('phone', $phone);
|
checkFieldFormat('phone', $phone);
|
||||||
checkFieldFormat('email', $email);
|
checkFieldFormat('email', $email);
|
||||||
|
checkFieldFormat('id_number', $idNumber);
|
||||||
|
if ($profileUrl !== '' && !preg_match('/^https?:\/\//i', $profileUrl)) {
|
||||||
|
Response::error('主页链接格式不正确(应以 http:// 或 https:// 开头)', 400);
|
||||||
|
}
|
||||||
|
|
||||||
// 各类型转软碎片基本要求
|
// 各类型转软碎片基本要求
|
||||||
switch ($targetType) {
|
switch ($targetType) {
|
||||||
@@ -84,17 +86,11 @@ switch ($targetType) {
|
|||||||
if ($companyName === '') {
|
if ($companyName === '') {
|
||||||
Response::error('产品类型转软碎片:公司名称为必填项,请先「继续补全」', 400);
|
Response::error('产品类型转软碎片:公司名称为必填项,请先「继续补全」', 400);
|
||||||
}
|
}
|
||||||
if ($category === '') {
|
|
||||||
Response::error('产品类型转软碎片:产品品类为必填项,请先「继续补全」填写品类', 400);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'need':
|
case 'need':
|
||||||
if ($companyName === '') {
|
if ($companyName === '') {
|
||||||
Response::error('需求类型转软碎片:公司名称为必填项,请先「继续补全」', 400);
|
Response::error('需求类型转软碎片:公司名称为必填项,请先「继续补全」', 400);
|
||||||
}
|
}
|
||||||
if ($needCategory === '') {
|
|
||||||
Response::error('需求类型转软碎片:需求类别为必填项,请先「继续补全」填写需求类别', 400);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +122,20 @@ $saveContacts = function ($ownerType, $ownerId) use ($pdo, $phone, $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) {
|
$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 = $pdo->prepare("SELECT id FROM companies WHERE display_name = ? AND is_active = 1 LIMIT 1");
|
||||||
@@ -143,69 +153,62 @@ $resolveCompany = function () use ($pdo, $companyName, $sourceChannel, $industry
|
|||||||
switch ($targetType) {
|
switch ($targetType) {
|
||||||
case 'company':
|
case 'company':
|
||||||
$pdo->prepare(
|
$pdo->prepare(
|
||||||
"INSERT INTO companies (display_name, name_zh, industry, registration_number, business_scope, source_channel, source_detail)
|
"INSERT INTO companies (display_name, name_zh, industry, registration_number, business_role, country, address, source_channel)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)"
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
||||||
)->execute([
|
)->execute([
|
||||||
$companyName, $companyName,
|
$companyName, $companyName,
|
||||||
$industry !== '' ? $industry : null,
|
$industry !== '' ? $industry : null,
|
||||||
$registrationNum !== '' ? $registrationNum : null,
|
$registrationNum !== '' ? $registrationNum : null,
|
||||||
$description !== '' ? $description : null,
|
$businessRole !== '' ? $businessRole : null,
|
||||||
|
$country !== '' ? $country : null,
|
||||||
|
$address !== '' ? $address : null,
|
||||||
$sourceChannel,
|
$sourceChannel,
|
||||||
$description !== '' ? $description : null,
|
|
||||||
]);
|
]);
|
||||||
$convertedId = (int)$pdo->lastInsertId();
|
$convertedId = (int)$pdo->lastInsertId();
|
||||||
$saveContacts('company', $convertedId);
|
$saveContacts('company', $convertedId);
|
||||||
|
saveSocialAccountIfAny($pdo, 'company', $convertedId, $platform, $accountId, $profileUrl);
|
||||||
updateIncomplete($pdo, 'companies', $convertedId);
|
updateIncomplete($pdo, 'companies', $convertedId);
|
||||||
updateAccountsIncomplete($pdo, 'company', $convertedId);
|
updateAccountsIncomplete($pdo, 'company', $convertedId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'person':
|
case 'person':
|
||||||
if ($personName === '') {
|
|
||||||
Response::error('联系人为必填项', 400);
|
|
||||||
}
|
|
||||||
$unionId = 'P' . date('YmdHis') . substr(uniqid(), -6);
|
$unionId = 'P' . date('YmdHis') . substr(uniqid(), -6);
|
||||||
$pdo->prepare(
|
$pdo->prepare(
|
||||||
"INSERT INTO persons (union_id, full_name, source_channel, source_detail) VALUES (?, ?, ?, ?)"
|
"INSERT INTO persons (union_id, full_name, work_location, id_number, source_channel) VALUES (?, ?, ?, ?, ?)"
|
||||||
)->execute([$unionId, $personName, $sourceChannel, $description !== '' ? $description : null]);
|
)->execute([
|
||||||
|
$unionId, $personName,
|
||||||
|
$workLocation !== '' ? $workLocation : null,
|
||||||
|
$idNumber !== '' ? $idNumber : null,
|
||||||
|
$sourceChannel,
|
||||||
|
]);
|
||||||
$convertedId = (int)$pdo->lastInsertId();
|
$convertedId = (int)$pdo->lastInsertId();
|
||||||
$saveContacts('person', $convertedId);
|
$saveContacts('person', $convertedId);
|
||||||
|
saveSocialAccountIfAny($pdo, 'person', $convertedId, $platform, $accountId, $profileUrl);
|
||||||
updateIncomplete($pdo, 'persons', $convertedId);
|
updateIncomplete($pdo, 'persons', $convertedId);
|
||||||
updateAccountsIncomplete($pdo, 'person', $convertedId);
|
updateAccountsIncomplete($pdo, 'person', $convertedId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'product':
|
case 'product':
|
||||||
if ($companyName === '') {
|
|
||||||
Response::error('公司名称为必填项', 400);
|
|
||||||
}
|
|
||||||
if ($category === '') {
|
|
||||||
Response::error('产品品类为必填项', 400);
|
|
||||||
}
|
|
||||||
$companyId = $resolveCompany();
|
$companyId = $resolveCompany();
|
||||||
|
// 品类字段已在 preliminary 移除(非必要/待定),转换时默认「未分类」
|
||||||
$pdo->prepare(
|
$pdo->prepare(
|
||||||
"INSERT INTO company_products (company_id, category_name, category_description)
|
"INSERT INTO company_products (company_id, category_name)
|
||||||
VALUES (?, ?, ?)"
|
VALUES (?, '未分类')"
|
||||||
)->execute([$companyId, $category, $description !== '' ? $description : null]);
|
)->execute([$companyId]);
|
||||||
$convertedId = (int)$pdo->lastInsertId();
|
$convertedId = (int)$pdo->lastInsertId();
|
||||||
updateIncomplete($pdo, 'companies', $companyId);
|
updateIncomplete($pdo, 'companies', $companyId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'need':
|
case 'need':
|
||||||
if ($companyName === '') {
|
|
||||||
Response::error('公司名称为必填项', 400);
|
|
||||||
}
|
|
||||||
$companyId = $resolveCompany();
|
$companyId = $resolveCompany();
|
||||||
$contactPerson = trim($_POST['contact_person'] ?? ($frag['person_name'] ?? ''));
|
$contactPerson = trim($_POST['contact_person'] ?? ($frag['person_name'] ?? ''));
|
||||||
$scenario = trim($_POST['application_scenario'] ?? '');
|
|
||||||
$pdo->prepare(
|
$pdo->prepare(
|
||||||
"INSERT INTO company_needs (company_id, contact_person, need_category, target_product_category, application_scenario, description)
|
"INSERT INTO company_needs (company_id, contact_person, description)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)"
|
VALUES (?, ?, ?)"
|
||||||
)->execute([
|
)->execute([
|
||||||
$companyId,
|
$companyId,
|
||||||
$contactPerson !== '' ? $contactPerson : null,
|
$contactPerson !== '' ? $contactPerson : null,
|
||||||
$needCategory !== '' ? $needCategory : null,
|
null,
|
||||||
$category !== '' ? $category : null,
|
|
||||||
$scenario !== '' ? $scenario : null,
|
|
||||||
$description !== '' ? $description : null,
|
|
||||||
]);
|
]);
|
||||||
$convertedId = (int)$pdo->lastInsertId();
|
$convertedId = (int)$pdo->lastInsertId();
|
||||||
updateIncomplete($pdo, 'companies', $companyId);
|
updateIncomplete($pdo, 'companies', $companyId);
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ $total = (int)$stmt->fetchColumn();
|
|||||||
|
|
||||||
$offset = ($page - 1) * $limit;
|
$offset = ($page - 1) * $limit;
|
||||||
$stmt = $pdo->prepare(
|
$stmt = $pdo->prepare(
|
||||||
"SELECT id, source_type, company_name, person_name, contact_phone, contact_email,
|
"SELECT id, source_type, company_name, industry, registration_number, business_role, country, address,
|
||||||
|
person_name, contact_phone, contact_email, work_location, id_number, platform, account_id, profile_url,
|
||||||
status, source_channel, recorded_by,
|
status, source_channel, recorded_by,
|
||||||
follow_person, converted_type, converted_id, created_at, updated_at
|
follow_person, converted_type, converted_id, created_at, updated_at
|
||||||
FROM preliminary_data
|
FROM preliminary_data
|
||||||
|
|||||||
@@ -32,17 +32,19 @@ if (in_array($frag['status'], ['已转换', '已废弃'], true)) {
|
|||||||
|
|
||||||
$sourceType = trim($_POST['source_type'] ?? ($frag['source_type'] ?? ''));
|
$sourceType = trim($_POST['source_type'] ?? ($frag['source_type'] ?? ''));
|
||||||
$companyName = trim($_POST['company_name'] ?? '');
|
$companyName = trim($_POST['company_name'] ?? '');
|
||||||
|
$industry = trim($_POST['industry'] ?? '');
|
||||||
|
$registrationNum = trim($_POST['registration_number'] ?? '');
|
||||||
|
$businessRole = trim($_POST['business_role'] ?? '');
|
||||||
|
$country = trim($_POST['country'] ?? '');
|
||||||
|
$address = trim($_POST['address'] ?? '');
|
||||||
$personName = trim($_POST['person_name'] ?? '');
|
$personName = trim($_POST['person_name'] ?? '');
|
||||||
$phone = trim($_POST['contact_phone'] ?? '');
|
$phone = trim($_POST['contact_phone'] ?? '');
|
||||||
$email = trim($_POST['contact_email'] ?? '');
|
$email = trim($_POST['contact_email'] ?? '');
|
||||||
|
$workLocation = trim($_POST['work_location'] ?? '');
|
||||||
$idNumber = trim($_POST['id_number'] ?? '');
|
$idNumber = trim($_POST['id_number'] ?? '');
|
||||||
$platform = trim($_POST['platform'] ?? '');
|
$platform = trim($_POST['platform'] ?? '');
|
||||||
$accountId = trim($_POST['account_id'] ?? '');
|
$accountId = trim($_POST['account_id'] ?? '');
|
||||||
$profileUrl = trim($_POST['profile_url'] ?? '');
|
$profileUrl = trim($_POST['profile_url'] ?? '');
|
||||||
$industry = trim($_POST['industry'] ?? ''); // 企业:行业
|
|
||||||
$registrationNum = trim($_POST['registration_number'] ?? ''); // 企业:注册号
|
|
||||||
$category = trim($_POST['target_product_category'] ?? ''); // 产品:品类
|
|
||||||
$needCategory = trim($_POST['need_category'] ?? ''); // 需求:需求类别
|
|
||||||
if (!in_array($sourceType, ['company', 'person', 'product', 'need', 'mixed'], true)) {
|
if (!in_array($sourceType, ['company', 'person', 'product', 'need', 'mixed'], true)) {
|
||||||
Response::error('碎片类型不合法', 400);
|
Response::error('碎片类型不合法', 400);
|
||||||
}
|
}
|
||||||
@@ -84,32 +86,27 @@ if ($accountId !== '' && $platform !== '') {
|
|||||||
}
|
}
|
||||||
if (!empty($dups)) Response::duplicates($dups);
|
if (!empty($dups)) Response::duplicates($dups);
|
||||||
|
|
||||||
// extra_info 合并更新(身份证/平台/账号ID/主页链接/品类/需求类别)
|
|
||||||
$extra = json_decode($frag['extra_info'] ?? 'null', true);
|
|
||||||
if (!is_array($extra)) {
|
|
||||||
$extra = [];
|
|
||||||
}
|
|
||||||
if ($idNumber !== '') $extra['id_number'] = $idNumber; else unset($extra['id_number']);
|
|
||||||
if ($platform !== '') $extra['platform'] = $platform; else unset($extra['platform']);
|
|
||||||
if ($accountId !== '') $extra['account_id'] = $accountId; else unset($extra['account_id']);
|
|
||||||
if ($profileUrl !== '') $extra['profile_url'] = $profileUrl; else unset($extra['profile_url']);
|
|
||||||
if ($category !== '') $extra['category'] = $category; else unset($extra['category']);
|
|
||||||
if ($needCategory !== '') $extra['need_category'] = $needCategory; else unset($extra['need_category']);
|
|
||||||
|
|
||||||
$pdo->prepare(
|
$pdo->prepare(
|
||||||
"UPDATE preliminary_data
|
"UPDATE preliminary_data
|
||||||
SET source_type = ?, company_name = ?, industry = ?, registration_number = ?, person_name = ?,
|
SET source_type = ?, company_name = ?, industry = ?, registration_number = ?, business_role = ?, country = ?, address = ?,
|
||||||
contact_phone = ?, contact_email = ?, extra_info = ?
|
person_name = ?, contact_phone = ?, contact_email = ?, work_location = ?, id_number = ?, platform = ?, account_id = ?, profile_url = ?
|
||||||
WHERE id = ?"
|
WHERE id = ?"
|
||||||
)->execute([
|
)->execute([
|
||||||
$sourceType,
|
$sourceType,
|
||||||
$companyName !== '' ? $companyName : null,
|
$companyName !== '' ? $companyName : null,
|
||||||
$industry !== '' ? $industry : null,
|
$industry !== '' ? $industry : null,
|
||||||
$registrationNum !== '' ? $registrationNum : null,
|
$registrationNum !== '' ? $registrationNum : null,
|
||||||
|
$businessRole !== '' ? $businessRole : null,
|
||||||
|
$country !== '' ? $country : null,
|
||||||
|
$address !== '' ? $address : null,
|
||||||
$personName !== '' ? $personName : null,
|
$personName !== '' ? $personName : null,
|
||||||
$phone !== '' ? $phone : null,
|
$phone !== '' ? $phone : null,
|
||||||
$email !== '' ? $email : null,
|
$email !== '' ? $email : null,
|
||||||
$extra ? json_encode($extra, JSON_UNESCAPED_UNICODE) : null,
|
$workLocation !== '' ? $workLocation : null,
|
||||||
|
$idNumber !== '' ? $idNumber : null,
|
||||||
|
$platform !== '' ? $platform : null,
|
||||||
|
$accountId !== '' ? $accountId : null,
|
||||||
|
$profileUrl !== '' ? $profileUrl : null,
|
||||||
$id,
|
$id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -119,7 +116,7 @@ logCurrent('update', 'fragment', 'preliminary_data', $id, [
|
|||||||
'person_name' => $personName,
|
'person_name' => $personName,
|
||||||
'phone' => $phone,
|
'phone' => $phone,
|
||||||
'email' => $email,
|
'email' => $email,
|
||||||
'extra' => $extra,
|
'id_number' => $idNumber,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Response::success(null, '已保存,点击「转软碎片」完成转换');
|
Response::success(null, '已保存,点击「转软碎片」完成转换');
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
-- ============================================================
|
||||||
|
-- SuperLink Web - v1.0.48 数据库结构变更
|
||||||
|
-- preliminary_data 重构:只保留核心+重要字段为正式列,删除非必要字段
|
||||||
|
-- 新增(重要字段正式化):business_role / country / address / work_location /
|
||||||
|
-- id_number / platform / account_id / profile_url
|
||||||
|
-- 删除:extra_info(原 JSON 容器;其中品类/需求类别为非必要/待定,不再存放)
|
||||||
|
-- 说明:删除前先备份整表到 preliminary_data_bak_20260810b
|
||||||
|
-- ============================================================
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
CREATE TABLE `preliminary_data_bak_20260810b` AS SELECT * FROM `preliminary_data`;
|
||||||
|
|
||||||
|
ALTER TABLE `preliminary_data`
|
||||||
|
ADD COLUMN `business_role` varchar(50) DEFAULT NULL COMMENT '业务类型(重要)' AFTER `registration_number`,
|
||||||
|
ADD COLUMN `country` varchar(100) DEFAULT NULL COMMENT '国家/地区(重要)' AFTER `business_role`,
|
||||||
|
ADD COLUMN `address` varchar(255) DEFAULT NULL COMMENT '地址(重要)' AFTER `country`,
|
||||||
|
ADD COLUMN `work_location` varchar(100) DEFAULT NULL COMMENT '工作所在地(重要)' AFTER `contact_email`,
|
||||||
|
ADD COLUMN `id_number` varchar(100) DEFAULT NULL COMMENT '身份证号码(重要)' AFTER `work_location`,
|
||||||
|
ADD COLUMN `platform` varchar(50) DEFAULT NULL COMMENT '社媒平台(核心)' AFTER `id_number`,
|
||||||
|
ADD COLUMN `account_id` varchar(200) DEFAULT NULL COMMENT '社媒账号ID(核心)' AFTER `platform`,
|
||||||
|
ADD COLUMN `profile_url` varchar(500) DEFAULT NULL COMMENT '主页链接(重要)' AFTER `account_id`,
|
||||||
|
DROP COLUMN `extra_info`;
|
||||||
+1
-1
@@ -5,7 +5,7 @@ var BASE_URL = '/api/';
|
|||||||
var PAGE_SIZE = 20;
|
var PAGE_SIZE = 20;
|
||||||
|
|
||||||
/** 系统版本号(logo旁展示):修改代码后运行 tools/bump_version.php 自动递增 */
|
/** 系统版本号(logo旁展示):修改代码后运行 tools/bump_version.php 自动递增 */
|
||||||
var APP_VERSION = 'v1.0.47';
|
var APP_VERSION = 'v1.0.48';
|
||||||
|
|
||||||
/** 页脚版权/备案信息(在 config.js 中修改) */
|
/** 页脚版权/备案信息(在 config.js 中修改) */
|
||||||
var FOOTER_TEXT = '© 2026 SuperLink 管理系统 版权所有 | 备案号:请替换为真实备案号';
|
var FOOTER_TEXT = '© 2026 SuperLink 管理系统 版权所有 | 备案号:请替换为真实备案号';
|
||||||
|
|||||||
+32
-26
@@ -209,8 +209,10 @@ $(function () {
|
|||||||
' <div class="form-item"><label>联系邮箱</label><input type="text" name="contact_email" placeholder="如:a@b.com"></div>' +
|
' <div class="form-item"><label>联系邮箱</label><input type="text" name="contact_email" placeholder="如:a@b.com"></div>' +
|
||||||
' <div class="form-item" id="ha-f-industry"><label>行业</label><input type="text" name="industry" placeholder="转软碎片必填,如:工业机器人"></div>' +
|
' <div class="form-item" id="ha-f-industry"><label>行业</label><input type="text" name="industry" placeholder="转软碎片必填,如:工业机器人"></div>' +
|
||||||
' <div class="form-item" id="ha-f-regnum"><label>注册号</label><input type="text" name="registration_number" placeholder="转软碎片必填"></div>' +
|
' <div class="form-item" id="ha-f-regnum"><label>注册号</label><input type="text" name="registration_number" placeholder="转软碎片必填"></div>' +
|
||||||
' <div class="form-item" id="ha-f-category"><label>产品品类</label><input type="text" name="target_product_category" placeholder="转软碎片必填,如:工业机器人"></div>' +
|
' <div class="form-item" id="ha-f-bizrole"><label>业务类型</label><input type="text" name="business_role" placeholder="如:manufacturer/integrator"></div>' +
|
||||||
' <div class="form-item" id="ha-f-needcat"><label>需求类别</label><input type="text" name="need_category" placeholder="转软碎片必填,如:设备采购"></div>' +
|
' <div class="form-item" id="ha-f-country"><label>国家/地区</label><input type="text" name="country" placeholder="如:中国"></div>' +
|
||||||
|
' <div class="form-item" id="ha-f-address"><label>地址</label><input type="text" name="address" placeholder="注册地址"></div>' +
|
||||||
|
' <div class="form-item" id="ha-f-workloc"><label>工作所在地</label><input type="text" name="work_location" placeholder="如:广东深圳"></div>' +
|
||||||
' <div class="form-item" id="ha-f-idnumber"><label>身份证号码</label><input type="text" name="id_number" placeholder="15 或 18 位"></div>' +
|
' <div class="form-item" id="ha-f-idnumber"><label>身份证号码</label><input type="text" name="id_number" placeholder="15 或 18 位"></div>' +
|
||||||
' <div class="form-item"><label>来源渠道</label><select name="source_channel" id="ha-source"><option value="">-</option></select></div>' +
|
' <div class="form-item"><label>来源渠道</label><select name="source_channel" id="ha-source"><option value="">-</option></select></div>' +
|
||||||
' <div class="form-item" id="ha-f-platform"><label>社媒平台</label><select name="platform" id="ha-platform"><option value="">-</option>' +
|
' <div class="form-item" id="ha-f-platform"><label>社媒平台</label><select name="platform" id="ha-platform"><option value="">-</option>' +
|
||||||
@@ -247,12 +249,15 @@ $(function () {
|
|||||||
// 姓名/联系人:人员与混合显示「姓名」,其它类型显示「联系人」
|
// 姓名/联系人:人员与混合显示「姓名」,其它类型显示「联系人」
|
||||||
$('#ha-f-person_name').toggle(true);
|
$('#ha-f-person_name').toggle(true);
|
||||||
$('#ha-f-person_name label').text((t === 'person' || t === 'mixed') ? '姓名' : '联系人');
|
$('#ha-f-person_name label').text((t === 'person' || t === 'mixed') ? '姓名' : '联系人');
|
||||||
// 企业专属:行业 / 注册号
|
// 企业专属:行业 / 注册号 / 业务类型 / 国家 / 地址
|
||||||
$('#ha-f-industry').toggle(t === 'company');
|
var isCompany = (t === 'company');
|
||||||
$('#ha-f-regnum').toggle(t === 'company');
|
$('#ha-f-industry').toggle(isCompany);
|
||||||
// 产品:品类;需求:需求类别
|
$('#ha-f-regnum').toggle(isCompany);
|
||||||
$('#ha-f-category').toggle(t === 'product');
|
$('#ha-f-bizrole').toggle(isCompany);
|
||||||
$('#ha-f-needcat').toggle(t === 'need');
|
$('#ha-f-country').toggle(isCompany);
|
||||||
|
$('#ha-f-address').toggle(isCompany);
|
||||||
|
// 人员专属:工作所在地
|
||||||
|
$('#ha-f-workloc').toggle(t === 'person');
|
||||||
// 身份证 / 社媒平台 / 账号 / 主页:企业与人员显示
|
// 身份证 / 社媒平台 / 账号 / 主页:企业与人员显示
|
||||||
var showIdSocial = (t === 'company' || t === 'person');
|
var showIdSocial = (t === 'company' || t === 'person');
|
||||||
$('#ha-f-idnumber').toggle(showIdSocial);
|
$('#ha-f-idnumber').toggle(showIdSocial);
|
||||||
@@ -316,8 +321,6 @@ $(function () {
|
|||||||
/* ================= 硬碎片:补全录入(转换) ================= */
|
/* ================= 硬碎片:补全录入(转换) ================= */
|
||||||
window.convertHard = function (id) {
|
window.convertHard = function (id) {
|
||||||
httpGet('fragment/hard_detail.php', { id: id }).then(function (d) {
|
httpGet('fragment/hard_detail.php', { id: id }).then(function (d) {
|
||||||
var ex = d.extra_info || {};
|
|
||||||
if (typeof ex === 'string') { try { ex = JSON.parse(ex); } catch (e) { ex = {}; } }
|
|
||||||
var typeSel = '<select id="cv-type">' +
|
var typeSel = '<select id="cv-type">' +
|
||||||
'<option value="company"' + (d.source_type === 'company' ? ' selected' : '') + '>企业</option>' +
|
'<option value="company"' + (d.source_type === 'company' ? ' selected' : '') + '>企业</option>' +
|
||||||
'<option value="person"' + (d.source_type === 'person' ? ' selected' : '') + '>人员</option>' +
|
'<option value="person"' + (d.source_type === 'person' ? ' selected' : '') + '>人员</option>' +
|
||||||
@@ -334,15 +337,17 @@ $(function () {
|
|||||||
' <div class="form-item"><label>联系邮箱</label><input type="text" name="contact_email" value="' + escHtml(d.contact_email || '') + '"></div>' +
|
' <div class="form-item"><label>联系邮箱</label><input type="text" name="contact_email" value="' + escHtml(d.contact_email || '') + '"></div>' +
|
||||||
' <div class="form-item" id="cv-f-industry"><label>行业</label><input type="text" name="industry" value="' + escHtml(d.industry || '') + '" placeholder="转软碎片必填"></div>' +
|
' <div class="form-item" id="cv-f-industry"><label>行业</label><input type="text" name="industry" value="' + escHtml(d.industry || '') + '" placeholder="转软碎片必填"></div>' +
|
||||||
' <div class="form-item" id="cv-f-regnum"><label>注册号</label><input type="text" name="registration_number" value="' + escHtml(d.registration_number || '') + '" placeholder="转软碎片必填"></div>' +
|
' <div class="form-item" id="cv-f-regnum"><label>注册号</label><input type="text" name="registration_number" value="' + escHtml(d.registration_number || '') + '" placeholder="转软碎片必填"></div>' +
|
||||||
' <div class="form-item" id="cv-f-category"><label>产品品类</label><input type="text" name="target_product_category" value="' + escHtml(ex.category || '') + '" placeholder="转软碎片必填"></div>' +
|
' <div class="form-item" id="cv-f-bizrole"><label>业务类型</label><input type="text" name="business_role" value="' + escHtml(d.business_role || '') + '"></div>' +
|
||||||
' <div class="form-item" id="cv-f-needcat"><label>需求类别</label><input type="text" name="need_category" value="' + escHtml(ex.need_category || '') + '" placeholder="转软碎片必填"></div>' +
|
' <div class="form-item" id="cv-f-country"><label>国家/地区</label><input type="text" name="country" value="' + escHtml(d.country || '') + '"></div>' +
|
||||||
' <div class="form-item" id="cv-f-idnumber"><label>身份证号码</label><input type="text" name="id_number" value="' + escHtml(ex.id_number || '') + '" placeholder="15 或 18 位"></div>' +
|
' <div class="form-item" id="cv-f-address"><label>地址</label><input type="text" name="address" value="' + escHtml(d.address || '') + '"></div>' +
|
||||||
|
' <div class="form-item" id="cv-f-workloc"><label>工作所在地</label><input type="text" name="work_location" value="' + escHtml(d.work_location || '') + '"></div>' +
|
||||||
|
' <div class="form-item" id="cv-f-idnumber"><label>身份证号码</label><input type="text" name="id_number" value="' + escHtml(d.id_number || '') + '" placeholder="15 或 18 位"></div>' +
|
||||||
' <div class="form-item" id="cv-f-platform"><label>社媒平台</label><select name="platform" id="cv-platform"><option value="">-</option>' +
|
' <div class="form-item" id="cv-f-platform"><label>社媒平台</label><select name="platform" id="cv-platform"><option value="">-</option>' +
|
||||||
' <option value="wechat">微信</option><option value="weibo">微博</option><option value="douyin">抖音</option>' +
|
' <option value="wechat">微信</option><option value="weibo">微博</option><option value="douyin">抖音</option>' +
|
||||||
' <option value="bilibili">B站</option><option value="linkedin">领英</option><option value="xiaohongshu">小红书</option>' +
|
' <option value="bilibili">B站</option><option value="linkedin">领英</option><option value="xiaohongshu">小红书</option>' +
|
||||||
' <option value="other">其他</option></select></div>' +
|
' <option value="other">其他</option></select></div>' +
|
||||||
' <div class="form-item" id="cv-f-account"><label>账号ID</label><input type="text" name="account_id" value="' + escHtml(ex.account_id || '') + '" placeholder="社媒账号ID"></div>' +
|
' <div class="form-item" id="cv-f-account"><label>账号ID</label><input type="text" name="account_id" value="' + escHtml(d.account_id || '') + '" placeholder="社媒账号ID"></div>' +
|
||||||
' <div class="form-item" id="cv-f-profile"><label>主页链接</label><input type="text" name="profile_url" value="' + escHtml(ex.profile_url || '') + '" placeholder="https://..."></div>' +
|
' <div class="form-item" id="cv-f-profile"><label>主页链接</label><input type="text" name="profile_url" value="' + escHtml(d.profile_url || '') + '" placeholder="https://..."></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div style="font-size:12px;color:#8a94a6;margin-top:4px;">补全仅保存到硬数据,点击「转软碎片」后才转换为主表数据。</div>' +
|
'<div style="font-size:12px;color:#8a94a6;margin-top:4px;">补全仅保存到硬数据,点击「转软碎片」后才转换为主表数据。</div>' +
|
||||||
'<div class="dialog-footer"><button type="button" class="btn" id="cv-cancel">取消</button>' +
|
'<div class="dialog-footer"><button type="button" class="btn" id="cv-cancel">取消</button>' +
|
||||||
@@ -355,17 +360,20 @@ $(function () {
|
|||||||
content: content,
|
content: content,
|
||||||
btn: false
|
btn: false
|
||||||
});
|
});
|
||||||
$('#cv-platform').val(ex.platform || '');
|
$('#cv-platform').val(d.platform || '');
|
||||||
|
|
||||||
function syncFields() {
|
function syncFields() {
|
||||||
var t = $('#cv-type').val();
|
var t = $('#cv-type').val();
|
||||||
$('#cv-f-company_name').toggle(t !== 'person');
|
$('#cv-f-company_name').toggle(t !== 'person');
|
||||||
$('#cv-f-person_name').toggle(true);
|
$('#cv-f-person_name').toggle(true);
|
||||||
$('#cv-f-person_name label').text((t === 'person' || t === 'mixed') ? '姓名' : '联系人');
|
$('#cv-f-person_name label').text((t === 'person' || t === 'mixed') ? '姓名' : '联系人');
|
||||||
$('#cv-f-industry').toggle(t === 'company');
|
var isCompany = (t === 'company');
|
||||||
$('#cv-f-regnum').toggle(t === 'company');
|
$('#cv-f-industry').toggle(isCompany);
|
||||||
$('#cv-f-category').toggle(t === 'product');
|
$('#cv-f-regnum').toggle(isCompany);
|
||||||
$('#cv-f-needcat').toggle(t === 'need');
|
$('#cv-f-bizrole').toggle(isCompany);
|
||||||
|
$('#cv-f-country').toggle(isCompany);
|
||||||
|
$('#cv-f-address').toggle(isCompany);
|
||||||
|
$('#cv-f-workloc').toggle(t === 'person');
|
||||||
var showIdSocial = (t === 'company' || t === 'person');
|
var showIdSocial = (t === 'company' || t === 'person');
|
||||||
$('#cv-f-idnumber').toggle(showIdSocial);
|
$('#cv-f-idnumber').toggle(showIdSocial);
|
||||||
$('#cv-f-platform').toggle(showIdSocial);
|
$('#cv-f-platform').toggle(showIdSocial);
|
||||||
@@ -421,8 +429,6 @@ $(function () {
|
|||||||
Dialog.error('该碎片缺少可转换信息,请使用「继续补全」');
|
Dialog.error('该碎片缺少可转换信息,请使用「继续补全」');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var ex = d.extra_info || {};
|
|
||||||
if (typeof ex === 'string') { try { ex = JSON.parse(ex); } catch (e) { ex = {}; } }
|
|
||||||
// 各类型转软碎片基本要求预检
|
// 各类型转软碎片基本要求预检
|
||||||
if (target === 'company' && (!d.industry || !d.registration_number)) {
|
if (target === 'company' && (!d.industry || !d.registration_number)) {
|
||||||
Dialog.error('企业类型转软碎片:请先「继续补全」填写行业和注册号');
|
Dialog.error('企业类型转软碎片:请先「继续补全」填写行业和注册号');
|
||||||
@@ -432,12 +438,12 @@ $(function () {
|
|||||||
Dialog.error('人员类型转软碎片:请先「继续补全」填写姓名');
|
Dialog.error('人员类型转软碎片:请先「继续补全」填写姓名');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (target === 'product' && !ex.category) {
|
if (target === 'product' && !d.company_name) {
|
||||||
Dialog.error('产品类型转软碎片:请先「继续补全」填写产品品类');
|
Dialog.error('产品类型转软碎片:请先「继续补全」填写公司名称');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (target === 'need' && !ex.need_category) {
|
if (target === 'need' && !d.company_name) {
|
||||||
Dialog.error('需求类型转软碎片:请先「继续补全」填写需求类别');
|
Dialog.error('需求类型转软碎片:请先「继续补全」填写公司名称');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Dialog.confirm('确定将该硬数据直接转换为软数据碎片吗?', function () {
|
Dialog.confirm('确定将该硬数据直接转换为软数据碎片吗?', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user