v1.0.33: 全局唯一性校验 - 手机号/邮箱/身份证/企业注册号/社媒账号ID/主页链接/企业名称 新增与修改时校验,重复弹窗提示并跳转定位(后端duplicate_check引擎+code 1001,前端弹窗+person/company/media页?id=跳转)

This commit is contained in:
nanguaboss
2026-08-09 22:27:05 +08:00
parent de1c227727
commit 76593d4dce
15 changed files with 393 additions and 17 deletions
+240
View File
@@ -0,0 +1,240 @@
<?php
/**
* 全局唯一性校验(2026-08-09)
* 手机号码 / 邮箱 / 身份证号码 / 企业注册号 / 社媒账号ID / 主页链接 / 企业名称
* 新增、修改时必须调用;重复时返回重复记录信息(供前端弹窗 + 跳转定位)
* 说明:
* - 手机/邮箱存在 social_accounts(platform=phone/email)
* - 社媒账号ID 同平台内唯一(wechat/douyin 等,不含 phone/email)
* - 主页链接 social_accounts.profile_url 全局唯一(非空才校验)
* - 企业名称 name_zh 或 display_name 任一相同即重复
*/
require_once __DIR__ . '/db.php';
/** 字段中文名 */
const DUP_LABELS = [
'phone' => '手机号码',
'email' => '邮箱',
'id_number' => '身份证号码',
'registration_number' => '企业注册号',
'account_id' => '社媒账号ID',
'profile_url' => '主页链接',
'company_name' => '企业名称',
];
/**
* 查询 social_accounts 重复记录(phone/email/account_id/profile_url 共用)
* @return array|null
*/
function findSocialDuplicate(PDO $pdo, $where, $params)
{
$sql =
"SELECT sa.id, sa.owner_type, sa.owner_id,
COALESCE(p.full_name, c.display_name) AS owner_name
FROM social_accounts sa
LEFT JOIN persons p ON p.id = sa.owner_id AND sa.owner_type = 'person'
LEFT JOIN companies c ON c.id = sa.owner_id AND sa.owner_type = 'company'
WHERE $where AND sa.is_active = 1
LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch();
if (!$row) {
return null;
}
return $row;
}
/**
* 校验唯一性
* @param PDO $pdo
* @param string $type phone|email|id_number|registration_number|account_id|profile_url|company_name
* @param string $value 待校验值
* @param array $excludeIds 排除自身记录ID(编辑时;social_accounts 传其 id / persons 传 persons.id / companies 传 companies.id)
* @param string|null $platform account_id 类型时必传(同平台内唯一)
* @return array|null {label,value,table,id,owner_type,owner_id,name,owner_label,jump}
*/
function findDuplicate(PDO $pdo, $type, $value, $excludeIds = [], $platform = null)
{
$value = trim((string)$value);
if ($value === '') {
return null;
}
$excludeIds = array_values(array_filter(array_map('intval', (array)$excludeIds)));
$excludeSql = '';
$excludeParams = [];
if ($excludeIds) {
$excludeSql = ' AND id NOT IN (' . implode(',', $excludeIds) . ')';
}
switch ($type) {
case 'phone':
case 'email':
$row = findSocialDuplicate($pdo, "sa.platform = ? AND LOWER(sa.account_id) = LOWER(?)" . str_replace('id NOT IN', 'sa.id NOT IN', $excludeSql), array_merge([$type, $value], $excludeParams));
if (!$row) {
return null;
}
return [
'label' => $type === 'phone' ? '手机号码' : '邮箱',
'value' => $value,
'table' => 'social_accounts',
'id' => (int)$row['id'],
'owner_type' => $row['owner_type'],
'owner_id' => (int)$row['owner_id'],
'name' => $row['owner_name'] ?: ('#' . $row['owner_id']),
'owner_label'=> $row['owner_type'] === 'person' ? '人员' : '企业',
'jump' => 'media.html?id=' . (int)$row['id'],
];
case 'account_id':
// 社媒账号:同平台内唯一(phone/email 走专门校验)
if ($platform === null || in_array($platform, ['phone', 'email'], true)) {
return null;
}
$row = findSocialDuplicate($pdo, "sa.platform = ? AND LOWER(sa.account_id) = LOWER(?)" . str_replace('id NOT IN', 'sa.id NOT IN', $excludeSql), array_merge([$platform, $value], $excludeParams));
if (!$row) {
return null;
}
return [
'label' => '社媒账号ID',
'value' => $value,
'table' => 'social_accounts',
'id' => (int)$row['id'],
'owner_type' => $row['owner_type'],
'owner_id' => (int)$row['owner_id'],
'name' => $row['owner_name'] ?: ('#' . $row['owner_id']),
'owner_label'=> $row['owner_type'] === 'person' ? '人员' : '企业',
'jump' => 'media.html?id=' . (int)$row['id'],
];
case 'profile_url':
$row = findSocialDuplicate($pdo, "sa.profile_url = ? AND sa.profile_url <> ''" . str_replace('id NOT IN', 'sa.id NOT IN', $excludeSql), array_merge([$value], $excludeParams));
if (!$row) {
return null;
}
return [
'label' => '主页链接',
'value' => $value,
'table' => 'social_accounts',
'id' => (int)$row['id'],
'owner_type' => $row['owner_type'],
'owner_id' => (int)$row['owner_id'],
'name' => $row['owner_name'] ?: ('#' . $row['owner_id']),
'owner_label'=> $row['owner_type'] === 'person' ? '人员' : '企业',
'jump' => 'media.html?id=' . (int)$row['id'],
];
case 'id_number':
$stmt = $pdo->prepare("SELECT id, full_name FROM persons WHERE id_number = ? AND is_active = 1$excludeSql LIMIT 1");
$stmt->execute(array_merge([$value], $excludeParams));
$row = $stmt->fetch();
if (!$row) {
return null;
}
return [
'label' => '身份证号码',
'value' => $value,
'table' => 'persons',
'id' => (int)$row['id'],
'name' => $row['full_name'] ?: ('#' . $row['id']),
'jump' => 'person.html?id=' . (int)$row['id'],
];
case 'registration_number':
$stmt = $pdo->prepare("SELECT id, display_name FROM companies WHERE registration_number = ? AND is_active = 1$excludeSql LIMIT 1");
$stmt->execute(array_merge([$value], $excludeParams));
$row = $stmt->fetch();
if (!$row) {
return null;
}
return [
'label' => '企业注册号',
'value' => $value,
'table' => 'companies',
'id' => (int)$row['id'],
'name' => $row['display_name'] ?: ('#' . $row['id']),
'jump' => 'company.html?id=' . (int)$row['id'],
];
case 'company_name':
$stmt = $pdo->prepare("SELECT id, display_name FROM companies WHERE (name_zh = ? OR display_name = ?) AND is_active = 1$excludeSql LIMIT 1");
$stmt->execute(array_merge([$value, $value], $excludeParams));
$row = $stmt->fetch();
if (!$row) {
return null;
}
return [
'label' => '企业名称',
'value' => $value,
'table' => 'companies',
'id' => (int)$row['id'],
'name' => $row['display_name'] ?: ('#' . $row['id']),
'jump' => 'company.html?id=' . (int)$row['id'],
];
}
return null;
}
/**
* 校验单条账号(媒体模块扁平字段)
* @param PDO $pdo
* @param string $platform
* @param string $accountId
* @param string $profileUrl
* @param array $excludeIds
* @return array|null
*/
function checkSingleAccountDuplicate(PDO $pdo, $platform, $accountId, $profileUrl = '', $excludeIds = [])
{
$platform = trim((string)$platform);
$accountId = trim((string)$accountId);
if ($platform !== '' && $accountId !== '') {
if ($platform === 'phone' || $platform === 'email') {
$dup = findDuplicate($pdo, $platform, $accountId, $excludeIds);
} else {
$dup = findDuplicate($pdo, 'account_id', $accountId, $excludeIds, $platform);
}
if ($dup) {
return $dup;
}
}
$profileUrl = trim((string)$profileUrl);
if ($profileUrl !== '') {
$dup = findDuplicate($pdo, 'profile_url', $profileUrl, $excludeIds);
if ($dup) {
return $dup;
}
}
return null;
}
/**
* 校验联系方式数组(persons/companies 的 contacts/accounts JSON)
* @param PDO $pdo
* @param array $accounts [{platform,account_id,profile_url,...}]
* @param array $excludeIds 整表替换时排除自身既有账号ID
* @return array|null
*/
function checkAccountsDuplicates(PDO $pdo, $accounts, $excludeIds = [])
{
if (!is_array($accounts)) {
return null;
}
foreach ($accounts as $a) {
if (!is_array($a)) {
continue;
}
$dup = checkSingleAccountDuplicate(
$pdo,
$a['platform'] ?? '',
$a['account_id'] ?? '',
$a['profile_url'] ?? '',
$excludeIds
);
if ($dup) {
return $dup;
}
}
return null;
}
+13
View File
@@ -25,6 +25,19 @@ class Response
self::json(['code' => $code, 'msg' => $msg]); self::json(['code' => $code, 'msg' => $msg]);
} }
/**
* 重复数据错误(前端弹窗 + 跳转定位)
* @param array $dup 重复记录信息:{label,value,name,owner_label,jump,...}
*/
public static function duplicate($dup)
{
self::json([
'code' => 1001,
'msg' => ($dup['label'] ?? '字段') . '「' . ($dup['value'] ?? '') . '」出现重复',
'data' => $dup,
]);
}
private static function json($payload) private static function json($payload)
{ {
header('Content-Type: application/json; charset=utf-8'); header('Content-Type: application/json; charset=utf-8');
+19 -6
View File
@@ -9,6 +9,7 @@ require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/helpers.php'; require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('company'); checkPermission('company');
@@ -28,6 +29,23 @@ if ((int)($data['is_listed'] ?? 0) !== 1) {
} }
$pdo = DB::getInstance()->getPdo(); $pdo = DB::getInstance()->getPdo();
// 唯一性校验:企业名称 / 注册号 / 联系方式(手机/邮箱/社媒账号/主页链接)
$dup = findDuplicate($pdo, 'company_name', $data['name_zh'] ?? $data['display_name'] ?? '');
if ($dup) Response::duplicate($dup);
if (!empty($data['registration_number'])) {
$dup = findDuplicate($pdo, 'registration_number', $data['registration_number']);
if ($dup) Response::duplicate($dup);
}
if (isset($_POST['accounts'])) {
$accounts = json_decode($_POST['accounts'], true);
if (!is_array($accounts)) {
Response::error('联系方式格式错误', 400);
}
$dup = checkAccountsDuplicates($pdo, $accounts);
if ($dup) Response::duplicate($dup);
}
[$sql, $params] = buildInsert($data); [$sql, $params] = buildInsert($data);
$pdo->prepare("INSERT INTO companies $sql")->execute($params); $pdo->prepare("INSERT INTO companies $sql")->execute($params);
$newId = (int)$pdo->lastInsertId(); $newId = (int)$pdo->lastInsertId();
@@ -53,12 +71,7 @@ if (array_key_exists('financials', $_POST) || array_key_exists('certifications',
saveCompanyCertifications($pdo, $newId, $certs); saveCompanyCertifications($pdo, $newId, $certs);
} }
if (array_key_exists('accounts', $_POST)) { if (array_key_exists('accounts', $_POST)) {
$accounts = json_decode($_POST['accounts'], true); saveCompanyAccounts($pdo, $newId, $accounts ?? []);
if (!is_array($accounts)) {
$pdo->rollBack();
Response::error('联系方式格式错误', 400);
}
saveCompanyAccounts($pdo, $newId, $accounts);
} }
$pdo->commit(); $pdo->commit();
} catch (Exception $e) { } catch (Exception $e) {
+5
View File
@@ -11,6 +11,7 @@ require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/helpers.php'; require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('company'); checkPermission('company');
@@ -30,6 +31,10 @@ if ((int)$chk->fetchColumn() === 0) {
Response::error('企业不存在'); Response::error('企业不存在');
} }
// 唯一性校验:社媒账号ID(同平台)/ 手机 / 邮箱 / 主页链接
$dup = checkSingleAccountDuplicate($pdo, $platform, $accountId, $_POST['profile_url'] ?? '');
if ($dup) Response::duplicate($dup);
$ins = $pdo->prepare( $ins = $pdo->prepare(
"INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, profile_url, remark, is_primary, is_defult, is_active) "INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, profile_url, remark, is_primary, is_defult, is_active)
VALUES ('company', ?, ?, ?, ?, ?, 0, ?, ?)" VALUES ('company', ?, ?, ?, ?, ?, 0, ?, ?)"
+20 -5
View File
@@ -9,6 +9,7 @@ require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/helpers.php'; require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('company'); checkPermission('company');
@@ -40,6 +41,25 @@ if (!$old) {
Response::error('企业不存在'); Response::error('企业不存在');
} }
// 唯一性校验(排除自身):企业名称 / 注册号 / 联系方式
$dup = findDuplicate($pdo, 'company_name', $data['name_zh'] ?? $old['display_name'] ?? '', [$id]);
if ($dup) Response::duplicate($dup);
if (!empty($data['registration_number'])) {
$dup = findDuplicate($pdo, 'registration_number', $data['registration_number'], [$id]);
if ($dup) Response::duplicate($dup);
}
$accounts = null;
if ($hasAccounts) {
$accounts = json_decode($_POST['accounts'], true);
if (!is_array($accounts)) {
Response::error('联系方式格式错误', 400);
}
// 整表替换:排除企业自身既有联系方式ID
$ownIds = $pdo->query("SELECT id FROM social_accounts WHERE owner_type = 'company' AND owner_id = $id")->fetchAll(PDO::FETCH_COLUMN);
$dup = checkAccountsDuplicates($pdo, $accounts, $ownIds);
if ($dup) Response::duplicate($dup);
}
if (!empty($data)) { if (!empty($data)) {
[$sets, $params] = buildUpdate($data); [$sets, $params] = buildUpdate($data);
$params[] = $id; $params[] = $id;
@@ -67,11 +87,6 @@ if ($hasFinancials || $hasCertifications || $hasAccounts) {
saveCompanyCertifications($pdo, $id, $certs); saveCompanyCertifications($pdo, $id, $certs);
} }
if ($hasAccounts) { if ($hasAccounts) {
$accounts = json_decode($_POST['accounts'], true);
if (!is_array($accounts)) {
$pdo->rollBack();
Response::error('联系方式格式错误', 400);
}
saveCompanyAccounts($pdo, $id, $accounts); saveCompanyAccounts($pdo, $id, $accounts);
} }
$pdo->commit(); $pdo->commit();
+13
View File
@@ -11,6 +11,7 @@ require_once __DIR__ . '/../common/response.php';
require_once __DIR__ . '/../common/auth.php'; require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('preliminary'); checkPermission('preliminary');
@@ -44,6 +45,18 @@ $sourceChannel = $frag['source_channel'] ?? null;
$convertedId = 0; $convertedId = 0;
// 唯一性校验:按目标类型
if ($targetType === 'company' && $companyName !== '') {
$dup = findDuplicate($pdo, 'company_name', $companyName);
if ($dup) Response::duplicate($dup);
}
if (in_array($targetType, ['person', 'company'], true)) {
$dup = checkSingleAccountDuplicate($pdo, $phone !== '' ? 'phone' : '', $phone, '');
if ($dup) Response::duplicate($dup);
$dup = checkSingleAccountDuplicate($pdo, $email !== '' ? 'email' : '', $email, '');
if ($dup) Response::duplicate($dup);
}
/** 创建 social_accounts(phone/email,常用) */ /** 创建 social_accounts(phone/email,常用) */
$saveContacts = function ($ownerType, $ownerId) use ($pdo, $phone, $email) { $saveContacts = function ($ownerType, $ownerId) use ($pdo, $phone, $email) {
if ($phone !== '') { if ($phone !== '') {
+5
View File
@@ -10,6 +10,7 @@ require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/helpers.php'; require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('media'); checkPermission('media');
@@ -42,6 +43,10 @@ if ((int)$chk->fetchColumn() > 0) {
Response::error('该平台账号已存在', 400); Response::error('该平台账号已存在', 400);
} }
// 唯一性校验:社媒账号ID(同平台)/ 手机 / 邮箱 / 主页链接
$dup = checkSingleAccountDuplicate($pdo, $data['platform'] ?? '', $data['account_id'] ?? '', $data['profile_url'] ?? '');
if ($dup) Response::duplicate($dup);
[$sql, $params] = buildInsert($data); [$sql, $params] = buildInsert($data);
$pdo->prepare("INSERT INTO social_accounts $sql")->execute($params); $pdo->prepare("INSERT INTO social_accounts $sql")->execute($params);
$newId = (int)$pdo->lastInsertId(); $newId = (int)$pdo->lastInsertId();
+13
View File
@@ -9,6 +9,7 @@ require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/helpers.php'; require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('media'); checkPermission('media');
@@ -29,6 +30,18 @@ if (!$old) {
$data = extractFields(MEDIA_FIELDS); $data = extractFields(MEDIA_FIELDS);
unset($data['owner_type'], $data['owner_id']); // 归属关系不允许改 unset($data['owner_type'], $data['owner_id']); // 归属关系不允许改
// 唯一性校验(排除自身):社媒账号ID(同平台)/ 手机 / 邮箱 / 主页链接
if (isset($_POST['platform']) || isset($_POST['account_id']) || isset($_POST['profile_url'])) {
$dup = checkSingleAccountDuplicate(
$pdo,
$_POST['platform'] ?? ($old['platform'] ?? ''),
$_POST['account_id'] ?? ($old['account_id'] ?? ''),
$_POST['profile_url'] ?? ($old['profile_url'] ?? ''),
[$id]
);
if ($dup) Response::duplicate($dup);
}
if (!empty($data)) { if (!empty($data)) {
[$sets, $params] = buildUpdate($data); [$sets, $params] = buildUpdate($data);
$params[] = $id; $params[] = $id;
+14 -2
View File
@@ -10,6 +10,7 @@ require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/helpers.php'; require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('person'); checkPermission('person');
@@ -31,13 +32,24 @@ if ((int)$chk->fetchColumn() > 0) {
Response::error('union_id 已存在,请更换'); Response::error('union_id 已存在,请更换');
} }
// 唯一性校验:身份证号码 / 联系方式(手机/邮箱/社媒账号/主页链接)
if (!empty($data['id_number'])) {
$dup = findDuplicate($pdo, 'id_number', $data['id_number']);
if ($dup) Response::duplicate($dup);
}
$contacts = json_decode($_POST['contacts'] ?? '[]', true);
if (!is_array($contacts)) {
$contacts = [];
}
$dup = checkAccountsDuplicates($pdo, $contacts);
if ($dup) Response::duplicate($dup);
[$sql, $params] = buildInsert($data); [$sql, $params] = buildInsert($data);
$pdo->prepare("INSERT INTO persons $sql")->execute($params); $pdo->prepare("INSERT INTO persons $sql")->execute($params);
$newId = (int)$pdo->lastInsertId(); $newId = (int)$pdo->lastInsertId();
// 写入联系方式(v1.0.16:支持 is_defult 字段,1常用/0备用) // 写入联系方式(v1.0.16:支持 is_defult 字段,1常用/0备用)
$contacts = json_decode($_POST['contacts'] ?? '[]', true); if (is_array($contacts) && count($contacts) > 0) {
if (is_array($contacts)) {
$ins = $pdo->prepare( $ins = $pdo->prepare(
"INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, profile_url, remark, is_primary, is_defult) "INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, profile_url, remark, is_primary, is_defult)
VALUES ('person', ?, ?, ?, ?, ?, ?, ?)" VALUES ('person', ?, ?, ?, ?, ?, ?, ?)"
+20 -3
View File
@@ -9,6 +9,7 @@ require_once __DIR__ . '/../common/auth.php';
require_once __DIR__ . '/../common/logger.php'; require_once __DIR__ . '/../common/logger.php';
require_once __DIR__ . '/../common/helpers.php'; require_once __DIR__ . '/../common/helpers.php';
require_once __DIR__ . '/../common/completeness.php'; require_once __DIR__ . '/../common/completeness.php';
require_once __DIR__ . '/../common/duplicate_check.php';
checkAjax(); checkAjax();
checkPermission('person'); checkPermission('person');
@@ -29,13 +30,29 @@ if (!$old) {
Response::error('人员不存在'); Response::error('人员不存在');
} }
$contactsChanged = false; // 唯一性校验(排除自身):身份证号码 / 联系方式
if (!empty($data['id_number'])) {
$dup = findDuplicate($pdo, 'id_number', $data['id_number'], [$id]);
if ($dup) Response::duplicate($dup);
}
$contacts = null;
if (isset($_POST['contacts'])) { if (isset($_POST['contacts'])) {
$contacts = json_decode($_POST['contacts'], true);
if (!is_array($contacts)) {
Response::error('联系方式格式错误', 400);
}
// 整体替换:排除人员自身既有联系方式ID
$ownIds = $pdo->query("SELECT id FROM social_accounts WHERE owner_type = 'person' AND owner_id = $id")->fetchAll(PDO::FETCH_COLUMN);
$dup = checkAccountsDuplicates($pdo, $contacts, $ownIds);
if ($dup) Response::duplicate($dup);
}
$contactsChanged = false;
if ($contacts !== null) {
$contactsChanged = true; $contactsChanged = true;
// 整体替换联系方式:先删旧(保留非联系人性质?此处直接删除全部后重建) // 整体替换联系方式:先删旧(保留非联系人性质?此处直接删除全部后重建)
$pdo->prepare("DELETE FROM social_accounts WHERE owner_type = 'person' AND owner_id = ?")->execute([$id]); $pdo->prepare("DELETE FROM social_accounts WHERE owner_type = 'person' AND owner_id = ?")->execute([$id]);
$contacts = json_decode($_POST['contacts'], true); if (count($contacts) > 0) {
if (is_array($contacts)) {
$ins = $pdo->prepare( $ins = $pdo->prepare(
"INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, profile_url, remark, is_primary, is_defult) "INSERT INTO social_accounts (owner_type, owner_id, platform, account_id, profile_url, remark, is_primary, is_defult)
VALUES ('person', ?, ?, ?, ?, ?, ?, ?)" VALUES ('person', ?, ?, ?, ?, ?, ?, ?)"
+21
View File
@@ -49,6 +49,27 @@ function handleResp(resp) {
location.href = 'index.html'; location.href = 'index.html';
return $.Deferred().reject(resp).promise(); return $.Deferred().reject(resp).promise();
} }
// 重复数据:弹窗提示 + 跳转定位到已有记录
if (resp && resp.code === 1001 && resp.data) {
var d = resp.data;
layer.open({
type: 1,
title: '数据重复提示',
area: ['440px', 'auto'],
content: '<div style="padding:20px 24px;">' +
'<div style="font-size:14px;color:#e74c3c;margin-bottom:8px;">' + escHtml(d.label) + '「' + escHtml(d.value) + '」出现重复</div>' +
'<div style="font-size:13px;color:#5a6472;margin-bottom:18px;">该值已存在:' + escHtml(d.name || '未知记录') + (d.owner_label ? '(' + escHtml(d.owner_label) + ')' : '') + '</div>' +
'<div style="text-align:right;"><button class="btn btn-primary" id="dup-jump-btn">查看记录</button></div>' +
'</div>',
btn: ['知道了'],
success: function (layero) {
$(layero).find('#dup-jump-btn').on('click', function () {
location.href = d.jump;
});
}
});
return $.Deferred().reject(resp).promise();
}
var msg = (resp && resp.msg) ? resp.msg : '请求失败'; var msg = (resp && resp.msg) ? resp.msg : '请求失败';
layer.msg(msg, { icon: 2 }); layer.msg(msg, { icon: 2 });
return $.Deferred().reject(resp).promise(); return $.Deferred().reject(resp).promise();
+3
View File
@@ -10,14 +10,17 @@
$(function () { $(function () {
renderShell('企业数据', '数据管理 / 企业数据'); renderShell('企业数据', '数据管理 / 企业数据');
renderPage(); renderPage();
var jumpId = parseInt(new URLSearchParams(location.search).get('id') || '0', 10);
initPage('company', function (user) { initPage('company', function (user) {
if (!checkPagePermission('company')) return; if (!checkPagePermission('company')) return;
loadDicts().then(function (dicts) { loadDicts().then(function (dicts) {
window._companyDicts = dicts; window._companyDicts = dicts;
fillSearchDicts(dicts); fillSearchDicts(dicts);
loadList(1); loadList(1);
if (jumpId > 0) window.viewCompany(jumpId);
}).catch(function () { }).catch(function () {
loadList(1); loadList(1);
if (jumpId > 0) window.viewCompany(jumpId);
}); });
}); });
+1 -1
View File
@@ -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.32'; var APP_VERSION = 'v1.0.33';
/** 页脚版权/备案信息(在 config.js 中修改) */ /** 页脚版权/备案信息(在 config.js 中修改) */
var FOOTER_TEXT = '© 2026 SuperLink 管理系统 版权所有 | 备案号:请替换为真实备案号'; var FOOTER_TEXT = '© 2026 SuperLink 管理系统 版权所有 | 备案号:请替换为真实备案号';
+3
View File
@@ -7,6 +7,9 @@ $(function () {
initPage('media', function (user) { initPage('media', function (user) {
if (!checkPagePermission('media')) return; if (!checkPagePermission('media')) return;
loadList(1); loadList(1);
// 跳转定位:?id= 打开该媒体账号详情(重复校验跳转用)
var jumpId = parseInt(new URLSearchParams(location.search).get('id') || '0', 10);
if (jumpId > 0) window.viewMedia(jumpId);
}); });
var currentPage = 1; var currentPage = 1;
+3
View File
@@ -12,6 +12,9 @@ $(function () {
initPage('person', function (user) { initPage('person', function (user) {
if (!checkPagePermission('person')) return; if (!checkPagePermission('person')) return;
loadList(1); loadList(1);
// 跳转定位:?id= 打开该人员详情(重复校验跳转用)
var jumpId = parseInt(new URLSearchParams(location.search).get('id') || '0', 10);
if (jumpId > 0) window.viewPerson(jumpId);
}); });
var currentPage = 1; var currentPage = 1;