4 Commits d1f408be7b ... 413328381a

Author SHA1 Message Date
  igb 413328381a fleat: update customersave 1 week ago
  igb ca3341f9c5 fleat: update customersave 1 week ago
  igb cd9514b4f5 fleat: update customersave 1 week ago
  igb 96a863e352 fleat: update customersave 1 week ago
3 changed files with 494 additions and 58 deletions
  1. 29 5
      customerAdd.php
  2. 29 5
      customerEdit.php
  3. 436 48
      customerSave.php

+ 29 - 5
customerAdd.php

@@ -6,7 +6,7 @@ checkLogin();
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>管理区域</title>
+    <title>客户管理</title>
     <link rel="stylesheet" href="css/common.css" type="text/css" />
     <script src="js/jquery-1.7.2.min.js"></script>
     <script src="js/js.js"></script>
@@ -196,16 +196,16 @@ checkLogin();
         
         switch(value) {
             case "tel":
-                placeholder = "电话格式:区号+号码 如:+86 15012345678";
+                placeholder = "电话格式必须为:区号+号码 如:+86 15012345678";
                 break;
             case "wechat":
                 placeholder = "微信";
                 break;
             case "whatsapp":
-                placeholder = "Whatsapp 格式:区号+号码 如:+86 15012345678";
+                placeholder = "Whatsapp 格式必须为:区号+号码 如:+86 15012345678";
                 break;
             case "email":
-                placeholder = "邮";
+                placeholder = "邮箱格式必须正确,如: example@domain.com";
                 break;
             case "linkedin":
                 placeholder = "领英链接";
@@ -239,17 +239,21 @@ checkLogin();
         
         if (clientCountry == 0 || !clientCountry) {
             alert("这是哪个国家的客户?");
+            $("#cs_country").focus();
             return false;
         }
         
         if (clientFrom == "0") {
             alert("请填写客户来源!");
+            $("#cs_from").focus();
             return false;
         }
         
         // Validate that at least one contact has at least one contact method
         var hasContactMethod = false;
         var allContactsValid = true;
+        var phoneRegex = /^\+\d{1,4}\s\d{5,}$/; // Regex to validate phone format: +[country code] [number]
+        var emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; // Regex to validate email format
         
         $('.contact-form').each(function(contactIndex) {
             var $form = $(this);
@@ -272,6 +276,26 @@ checkLogin();
                     allContactsValid = false;
                     return false;
                 }
+                
+                // Validate phone number format for tel and whatsapp
+                if ((methodType === 'tel' || methodType === 'whatsapp') && methodValue) {
+                    if (!phoneRegex.test(methodValue)) {
+                        alert("电话格式不正确,请使用以下格式:区号+号码,如 +86 15012345678");
+                        $(this).find('input.method-input').focus();
+                        allContactsValid = false;
+                        return false;
+                    }
+                }
+                
+                // Validate email format
+                if (methodType === 'email' && methodValue) {
+                    if (!emailRegex.test(methodValue)) {
+                        alert("邮箱格式不正确,请输入有效的邮箱地址");
+                        $(this).find('input.method-input').focus();
+                        allContactsValid = false;
+                        return false;
+                    }
+                }
             });
             
             // If contact has a name but no methods, or has methods but no name
@@ -410,7 +434,7 @@ checkLogin();
                     <td><input type="text" id="cs_company" name="cs_company" value="" class="txt1" /></td>
                 </tr>
                 <tr>
-                    <th width="8%">地区</th>
+                    <th width="8%">地区/国家</th>
                     <td>
                         <div class="layui-input-inline">
                             <div class="layui-form-select ySearchSelect y1">

+ 29 - 5
customerEdit.php

@@ -265,16 +265,16 @@ if (!empty($id) && is_numeric($id)) {
         
         switch(value) {
             case "tel":
-                placeholder = "电话格式:区号+号码 如:+86 15012345678";
+                placeholder = "电话格式必须为:区号+号码 如:+86 15012345678";
                 break;
             case "wechat":
                 placeholder = "微信";
                 break;
             case "whatsapp":
-                placeholder = "Whatsapp 格式:区号+号码 如:+86 15012345678";
+                placeholder = "Whatsapp 格式必须为:区号+号码 如:+86 15012345678";
                 break;
             case "email":
-                placeholder = "邮";
+                placeholder = "邮箱格式必须正确,如: example@domain.com";
                 break;
             case "linkedin":
                 placeholder = "领英链接";
@@ -306,19 +306,23 @@ if (!empty($id) && is_numeric($id)) {
             return false;
         }
         
-        if (clientCountry == 0) {
+        if (clientCountry == 0 || !clientCountry) {
             alert("这是哪个国家的客户?");
+            $("#cs_country").focus();
             return false;
         }
         
         if (clientFrom == "0") {
             alert("请填写客户来源!");
+            $("#cs_from").focus();
             return false;
         }
         
         // Validate that at least one contact has at least one contact method
         var hasContactMethod = false;
         var allContactsValid = true;
+        var phoneRegex = /^\+\d{1,4}\s\d{5,}$/; // Regex to validate phone format: +[country code] [number]
+        var emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; // Regex to validate email format
         
         $('.contact-form').each(function(contactIndex) {
             var $form = $(this);
@@ -341,6 +345,26 @@ if (!empty($id) && is_numeric($id)) {
                     allContactsValid = false;
                     return false;
                 }
+                
+                // Validate phone number format for tel and whatsapp
+                if ((methodType === 'tel' || methodType === 'whatsapp') && methodValue) {
+                    if (!phoneRegex.test(methodValue)) {
+                        alert("电话格式不正确,请使用以下格式:区号+号码,如 +86 15012345678");
+                        $(this).find('input.method-input').focus();
+                        allContactsValid = false;
+                        return false;
+                    }
+                }
+                
+                // Validate email format
+                if (methodType === 'email' && methodValue) {
+                    if (!emailRegex.test(methodValue)) {
+                        alert("邮箱格式不正确,请输入有效的邮箱地址");
+                        $(this).find('input.method-input').focus();
+                        allContactsValid = false;
+                        return false;
+                    }
+                }
             });
             
             // If contact has a name but no methods, or has methods but no name
@@ -505,7 +529,7 @@ if (!empty($id) && is_numeric($id)) {
                     <td><input type="text" id="cs_company" name="cs_company" value="<?= htmlspecialcharsFix($customer['cs_company']) ?>" class="txt1" /></td>
                 </tr>
                 <tr>
-                    <th width="8%">地区</th>
+                    <th width="8%">地区/国家</th>
                     <td>
                         <div class="layui-input-inline">
                             <div class="layui-form-select ySearchSelect y1">

+ 436 - 48
customerSave.php

@@ -132,38 +132,80 @@ if (empty($cs_code)) {
     exit;
 }
 
+
+$customer_id = is_numeric($id) ? intval($id) : 0;
+
 // Check for duplicate customer information
 $checkStr = "SELECT c.*, cc.* 
              FROM customer c 
              LEFT JOIN customer_contact cc ON c.id = cc.customer_id
-             WHERE c.cs_belong != " . $_SESSION['employee_id'] . " AND (c.id = 0 ";
+             WHERE c.id != " . $customer_id." AND ( 1=2 ";
 
 $Dupli = "";
 
+
+/* 暂时不需要这些检查 START */
+// Company name similarity check
+//if (!empty($cs_company)) {
+//    $companyWords = explode(' ', strtolower($cs_company));
+//    foreach ($companyWords as $word) {
+//        if (strlen($word) > 3) { // Only check words longer than 3 characters
+//            $checkStr .= " OR LOWER(c.cs_company) LIKE '%" . $conn->real_escape_string($word) . "%'";
+//        }
+//    }
+//}
+
+// Address similarity check
+//if (!empty($cs_address)) {
+//    $addressWords = explode(' ', strtolower($cs_address));
+//    foreach ($addressWords as $word) {
+//        if (strlen($word) > 3) { // Only check words longer than 3 characters
+//            $checkStr .= " OR LOWER(c.cs_address) LIKE '%" . $conn->real_escape_string($word) . "%'";
+//        }
+//    }
+//}
+
+/* 暂时不需要这些检查 END */
+
 // Check all contacts for duplicates
 foreach ($contacts as $contact) {
+
+    //遍历处理空格
+    foreach ($contact as $key => $value) {
+        $contact[$key] = trim($value);
+    }
+
     // Check all phone numbers
     for ($i = 1; $i <= 3; $i++) {
         $tel_field = 'tel_' . $i;
         if (!empty($contact[$tel_field])) {
             $tel_format = numFormat($contact[$tel_field]);
-            $checkStr .= " OR cc.tel_1_format LIKE '%" . substr($tel_format, 3, 9) . "%'" .
-                        " OR cc.tel_2_format LIKE '%" . substr($tel_format, 3, 9) . "%'" .
-                        " OR cc.tel_3_format LIKE '%" . substr($tel_format, 3, 9) . "%'" .
-                        " OR cc.wechat_1 LIKE '%" . substr($tel_format, 3, 9) . "%'" .
-                        " OR cc.wechat_2 LIKE '%" . substr($tel_format, 3, 9) . "%'" .
-                        " OR cc.wechat_3 LIKE '%" . substr($tel_format, 3, 9) . "%'";
-            $Dupli .= "电话" . $i . ":" . $contact[$tel_field] . " ";
+            // Remove country code and spaces for better matching
+            $tel_clean = preg_replace('/[^0-9]/', '', $tel_format);
+
+            if(!empty($tel_clean))
+            {
+                $checkStr .= " OR cc.tel_1_format LIKE '%" . substr($tel_clean, -9) . "%'" .
+                            " OR cc.tel_2_format LIKE '%" . substr($tel_clean, -9) . "%'" .
+                        " OR cc.tel_3_format LIKE '%" . substr($tel_clean, -9) . "%'" .
+                        " OR cc.wechat_1 LIKE '%" . substr($tel_clean, -9) . "%'" .
+                        " OR cc.wechat_2 LIKE '%" . substr($tel_clean, -9) . "%'" .
+                        " OR cc.wechat_3 LIKE '%" . substr($tel_clean, -9) . "%'";
+                $Dupli .= "电话" . $i . ":" . $contact[$tel_field] . " ";
+            }
         }
     }
 
     // Check all email addresses
     for ($i = 1; $i <= 3; $i++) {
         $email_field = 'email_' . $i;
+
         if (!empty($contact[$email_field])) {
-            $checkStr .= " OR cc.email_1 = '" . $conn->real_escape_string($contact[$email_field]) . "'" .
-                        " OR cc.email_2 = '" . $conn->real_escape_string($contact[$email_field]) . "'" .
-                        " OR cc.email_3 = '" . $conn->real_escape_string($contact[$email_field]) . "'";
+            $contact[$email_field]=trim($contact[$email_field]);
+            $email = strtolower($contact[$email_field]);
+            $checkStr .= " OR LOWER(cc.email_1) = '" . $conn->real_escape_string($email) . "'" .
+                        " OR LOWER(cc.email_2) = '" . $conn->real_escape_string($email) . "'" .
+                        " OR LOWER(cc.email_3) = '" . $conn->real_escape_string($email) . "'";
             $Dupli .= "邮箱" . $i . ":" . $contact[$email_field] . " ";
         }
     }
@@ -171,15 +213,20 @@ foreach ($contacts as $contact) {
     // Check all WhatsApp numbers
     for ($i = 1; $i <= 3; $i++) {
         $whatsapp_field = 'whatsapp_' . $i;
+
         if (!empty($contact[$whatsapp_field])) {
             $whatsapp_format = numFormat($contact[$whatsapp_field]);
-            $checkStr .= " OR cc.whatsapp_1_format LIKE '%" . substr($whatsapp_format, 3, 9) . "%'" .
-                        " OR cc.whatsapp_2_format LIKE '%" . substr($whatsapp_format, 3, 9) . "%'" .
-                        " OR cc.whatsapp_3_format LIKE '%" . substr($whatsapp_format, 3, 9) . "%'" .
-                        " OR cc.tel_1_format LIKE '%" . substr($whatsapp_format, 3, 9) . "%'" .
-                        " OR cc.tel_2_format LIKE '%" . substr($whatsapp_format, 3, 9) . "%'" .
-                        " OR cc.tel_3_format LIKE '%" . substr($whatsapp_format, 3, 9) . "%'";
-            $Dupli .= "WhatsApp" . $i . ":" . $contact[$whatsapp_field] . " ";
+            $whatsapp_clean = preg_replace('/[^0-9]/', '', $whatsapp_format);
+            if(!empty($whatsapp_clean))
+            {
+                $checkStr .= " OR cc.whatsapp_1_format LIKE '%" . substr($whatsapp_clean, -9) . "%'" .
+                        " OR cc.whatsapp_2_format LIKE '%" . substr($whatsapp_clean, -9) . "%'" .
+                        " OR cc.whatsapp_3_format LIKE '%" . substr($whatsapp_clean, -9) . "%'" .
+                        " OR cc.tel_1_format LIKE '%" . substr($whatsapp_clean, -9) . "%'" .
+                        " OR cc.tel_2_format LIKE '%" . substr($whatsapp_clean, -9) . "%'" .
+                        " OR cc.tel_3_format LIKE '%" . substr($whatsapp_clean, -9) . "%'";
+                $Dupli .= "WhatsApp" . $i . ":" . $contact[$whatsapp_field] . " ";
+            }
         }
     }
 
@@ -187,21 +234,15 @@ foreach ($contacts as $contact) {
     for ($i = 1; $i <= 3; $i++) {
         $wechat_field = 'wechat_' . $i;
         if (!empty($contact[$wechat_field])) {
-            if (strlen($contact[$wechat_field]) < 10) {
-                $checkStr .= " OR cc.wechat_1 LIKE '%" . $conn->real_escape_string($contact[$wechat_field]) . "%'" .
-                            " OR cc.wechat_2 LIKE '%" . $conn->real_escape_string($contact[$wechat_field]) . "%'" .
-                            " OR cc.wechat_3 LIKE '%" . $conn->real_escape_string($contact[$wechat_field]) . "%'" .
-                            " OR cc.tel_1_format LIKE '%" . $conn->real_escape_string($contact[$wechat_field]) . "%'" .
-                            " OR cc.tel_2_format LIKE '%" . $conn->real_escape_string($contact[$wechat_field]) . "%'" .
-                            " OR cc.tel_3_format LIKE '%" . $conn->real_escape_string($contact[$wechat_field]) . "%'";
-            } else {
-                $checkStr .= " OR cc.wechat_1 LIKE '%" . substr($contact[$wechat_field], 2, 12) . "%'" .
-                            " OR cc.wechat_2 LIKE '%" . substr($contact[$wechat_field], 2, 12) . "%'" .
-                            " OR cc.wechat_3 LIKE '%" . substr($contact[$wechat_field], 2, 12) . "%'" .
-                            " OR cc.tel_1_format LIKE '%" . substr($contact[$wechat_field], 2, 12) . "%'" .
-                            " OR cc.tel_2_format LIKE '%" . substr($contact[$wechat_field], 2, 12) . "%'" .
-                            " OR cc.tel_3_format LIKE '%" . substr($contact[$wechat_field], 2, 12) . "%'";
-            }
+            $wechat = $contact[$wechat_field];
+
+            $checkStr .= " OR cc.wechat_1 LIKE '%" . $conn->real_escape_string($wechat) . "%'" .
+                            " OR cc.wechat_2 LIKE '%" . $conn->real_escape_string($wechat) . "%'" .
+                            " OR cc.wechat_3 LIKE '%" . $conn->real_escape_string($wechat) . "%'" .
+                            " OR cc.tel_1_format LIKE '%" . $conn->real_escape_string($wechat) . "%'" .
+                            " OR cc.tel_2_format LIKE '%" . $conn->real_escape_string($wechat) . "%'" .
+                            " OR cc.tel_3_format LIKE '%" . $conn->real_escape_string($wechat) . "%'";
+
             $Dupli .= "微信" . $i . ":" . $contact[$wechat_field] . " ";
         }
     }
@@ -210,9 +251,10 @@ foreach ($contacts as $contact) {
     for ($i = 1; $i <= 3; $i++) {
         $linkedin_field = 'linkedin_' . $i;
         if (!empty($contact[$linkedin_field])) {
-            $checkStr .= " OR cc.linkedin_1 LIKE '%" . $conn->real_escape_string($contact[$linkedin_field]) . "%'" .
-                        " OR cc.linkedin_2 LIKE '%" . $conn->real_escape_string($contact[$linkedin_field]) . "%'" .
-                        " OR cc.linkedin_3 LIKE '%" . $conn->real_escape_string($contact[$linkedin_field]) . "%'";
+            $linkedin = strtolower($contact[$linkedin_field]);
+            $checkStr .= " OR LOWER(cc.linkedin_1) LIKE '%" . $conn->real_escape_string($linkedin) . "%'" .
+                        " OR LOWER(cc.linkedin_2) LIKE '%" . $conn->real_escape_string($linkedin) . "%'" .
+                        " OR LOWER(cc.linkedin_3) LIKE '%" . $conn->real_escape_string($linkedin) . "%'";
             $Dupli .= "LinkedIn" . $i . ":" . $contact[$linkedin_field] . " ";
         }
     }
@@ -221,9 +263,10 @@ foreach ($contacts as $contact) {
     for ($i = 1; $i <= 3; $i++) {
         $facebook_field = 'facebook_' . $i;
         if (!empty($contact[$facebook_field])) {
-            $checkStr .= " OR cc.facebook_1 LIKE '%" . $conn->real_escape_string($contact[$facebook_field]) . "%'" .
-                        " OR cc.facebook_2 LIKE '%" . $conn->real_escape_string($contact[$facebook_field]) . "%'" .
-                        " OR cc.facebook_3 LIKE '%" . $conn->real_escape_string($contact[$facebook_field]) . "%'";
+            $facebook = strtolower($contact[$facebook_field]);
+            $checkStr .= " OR LOWER(cc.facebook_1) LIKE '%" . $conn->real_escape_string($facebook) . "%'" .
+                        " OR LOWER(cc.facebook_2) LIKE '%" . $conn->real_escape_string($facebook) . "%'" .
+                        " OR LOWER(cc.facebook_3) LIKE '%" . $conn->real_escape_string($facebook) . "%'";
             $Dupli .= "Facebook" . $i . ":" . $contact[$facebook_field] . " ";
         }
     }
@@ -232,14 +275,16 @@ foreach ($contacts as $contact) {
     for ($i = 1; $i <= 3; $i++) {
         $alibaba_field = 'alibaba_' . $i;
         if (!empty($contact[$alibaba_field])) {
-            if (strlen($contact[$alibaba_field]) < 10) {
-                $checkStr .= " OR cc.alibaba_1 LIKE '" . $conn->real_escape_string($contact[$alibaba_field]) . "'" .
-                            " OR cc.alibaba_2 LIKE '" . $conn->real_escape_string($contact[$alibaba_field]) . "'" .
-                            " OR cc.alibaba_3 LIKE '" . $conn->real_escape_string($contact[$alibaba_field]) . "'";
+            $alibaba = strtolower($contact[$alibaba_field]);
+            if (strlen($alibaba) < 10) {
+                $checkStr .= " OR LOWER(cc.alibaba_1) LIKE '" . $conn->real_escape_string($alibaba) . "'" .
+                            " OR LOWER(cc.alibaba_2) LIKE '" . $conn->real_escape_string($alibaba) . "'" .
+                            " OR LOWER(cc.alibaba_3) LIKE '" . $conn->real_escape_string($alibaba) . "'";
             } else {
-                $checkStr .= " OR cc.alibaba_1 LIKE '%" . substr($contact[$alibaba_field], 3, 12) . "%'" .
-                            " OR cc.alibaba_2 LIKE '%" . substr($contact[$alibaba_field], 3, 12) . "%'" .
-                            " OR cc.alibaba_3 LIKE '%" . substr($contact[$alibaba_field], 3, 12) . "%'";
+                $alibaba_clean = preg_replace('/[^0-9a-zA-Z]/', '', $alibaba);
+                $checkStr .= " OR LOWER(cc.alibaba_1) LIKE '%" . substr($alibaba_clean, -9) . "%'" .
+                            " OR LOWER(cc.alibaba_2) LIKE '%" . substr($alibaba_clean, -9) . "%'" .
+                            " OR LOWER(cc.alibaba_3) LIKE '%" . substr($alibaba_clean, -9) . "%'";
             }
             $Dupli .= "阿里旺旺" . $i . ":" . $contact[$alibaba_field] . " ";
         }
@@ -248,11 +293,18 @@ foreach ($contacts as $contact) {
 
 $checkStr .= " ) ORDER BY c.id ASC";
 
+
+
 if ($allowedit != 1) {
+
+
     $result = $conn->query($checkStr);
+
+
+
     if ($result && $result->num_rows > 0) {
         $row = $result->fetch_assoc();
-        
+ 
         // Get owner name
         $ownerResult = $conn->query("SELECT em_user FROM employee WHERE id = " . $row['cs_belong']);
         $ownerRow = $ownerResult->fetch_assoc();
@@ -274,10 +326,346 @@ if ($allowedit != 1) {
         }
         
         $conn->query($tstr);
-        echo "<script>alert('录入信息\\n与" . $owner . "客户编号:" . textUncode($row['cs_code']) . 
+        echo "<script>alert('warning.1.录入信息\\n与" . $owner . "客户编号:" . textUncode($row['cs_code']) . 
              "\\n高度类似,未能保存,请联系管理员核实!');history.back();</script>";
         exit;
     }
+    else
+    {
+        //全文检索再检查一次
+        //先去掉联系方式中的特殊字符
+        //用联系方式进行全文fullindex检索,用相关性分数大于百分70 的进行检查
+        
+        // 根据不同联系方式类型进行专门检查
+        $duplicateFound = false;
+        $matchDetails = '';
+        $matchScore = 0;
+        $matchCustomerId = 0;
+        $matchCustomerCode = '';
+        $matchOwner = '';
+        $matchAddTime = '';
+        
+        // 编辑模式下需要排除自己的ID
+        $excludeId = ($act === 'editSave' && is_numeric($id)) ? intval($id) : 0;
+        
+        // 1. 优先检查邮箱 - 邮箱是最精确的匹配
+        $emailTerms = [];
+        foreach ($contacts as $contact) {
+            for ($i = 1; $i <= 3; $i++) {
+                $field = 'email_' . $i;
+                if (!empty($contact[$field])) {
+                    $email = strtolower(trim($contact[$field]));
+                    if (strpos($email, '@') !== false) {
+                        $emailTerms[] = $email;
+                    }
+                }
+            }
+        }
+        
+        if (!empty($emailTerms)) {
+            $emailQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime, cc.email_1, cc.email_2, cc.email_3 
+                          FROM customer c 
+                          JOIN customer_contact cc ON c.id = cc.customer_id
+                          WHERE c.cs_belong != " . $_SESSION['employee_id'] . " 
+                          AND c.id != " . $excludeId . " AND (";
+            
+            $emailConditions = [];
+            foreach ($emailTerms as $email) {
+                $emailConditions[] = "cc.email_1 = '" . $conn->real_escape_string($email) . "'";
+                $emailConditions[] = "cc.email_2 = '" . $conn->real_escape_string($email) . "'";
+                $emailConditions[] = "cc.email_3 = '" . $conn->real_escape_string($email) . "'";
+            }
+            
+            $emailQuery .= implode(" OR ", $emailConditions) . ") LIMIT 1";
+            $emailResult = $conn->query($emailQuery);
+            
+            if ($emailResult && $emailResult->num_rows > 0) {
+                $row = $emailResult->fetch_assoc();
+                $matchCustomerId = $row['id'];
+                $matchCustomerCode = $row['cs_code'];
+                $matchOwner = $row['cs_belong'];
+                $matchAddTime = $row['cs_addtime'];
+                $matchDetails = "邮箱完全匹配";
+                $matchScore = 0.95; // 邮箱精确匹配,高可信度
+                $duplicateFound = true;
+            }
+        }
+        
+        // 2. 检查电话号码与WhatsApp - 清理后进行后缀匹配
+        if (!$duplicateFound) {
+            $phoneTerms = [];
+            foreach ($contacts as $contact) {
+                // 收集所有电话号码
+                for ($i = 1; $i <= 3; $i++) {
+                    $fields = ['tel_' . $i, 'whatsapp_' . $i];
+                    foreach ($fields as $field) {
+                        if (!empty($contact[$field])) {
+                            $cleaned = preg_replace('/[^0-9]/', '', $contact[$field]);
+                            if (strlen($cleaned) > 7) { // 至少8位有效数字
+                                $phoneTerms[] = $cleaned;
+                            }
+                        }
+                    }
+                }
+            }
+            
+            if (!empty($phoneTerms)) {
+                $phoneQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime, 
+                               cc.tel_1_format, cc.tel_2_format, cc.tel_3_format,
+                               cc.whatsapp_1_format, cc.whatsapp_2_format, cc.whatsapp_3_format 
+                               FROM customer c 
+                               JOIN customer_contact cc ON c.id = cc.customer_id
+                               WHERE c.cs_belong != " . $_SESSION['employee_id'] . "
+                               AND c.id != " . $excludeId . " AND (";
+                               
+                $phoneConditions = [];
+                foreach ($phoneTerms as $phone) {
+                    // 使用后8位进行匹配,避免国家代码等差异
+                    $suffix = substr($phone, -8);
+                    if (strlen($suffix) == 8) {
+                        $phoneConditions[] = "cc.tel_1_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
+                        $phoneConditions[] = "cc.tel_2_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
+                        $phoneConditions[] = "cc.tel_3_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
+                        $phoneConditions[] = "cc.whatsapp_1_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
+                        $phoneConditions[] = "cc.whatsapp_2_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
+                        $phoneConditions[] = "cc.whatsapp_3_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
+                    }
+                }
+                
+                if (!empty($phoneConditions)) {
+                    $phoneQuery .= implode(" OR ", $phoneConditions) . ") LIMIT 1";
+                    $phoneResult = $conn->query($phoneQuery);
+                    
+                    if ($phoneResult && $phoneResult->num_rows > 0) {
+                        $row = $phoneResult->fetch_assoc();
+                        $matchCustomerId = $row['id'];
+                        $matchCustomerCode = $row['cs_code'];
+                        $matchOwner = $row['cs_belong'];
+                        $matchAddTime = $row['cs_addtime'];
+                        $matchDetails = "电话号码后8位匹配";
+                        $matchScore = 0.90; // 电话匹配,高可信度
+                        $duplicateFound = true;
+                    }
+                }
+            }
+        }
+        
+        // 3. 检查社交媒体账号 (alibaba/wechat/facebook/linkedin)
+        if (!$duplicateFound) {
+            $socialTerms = [];
+            $socialFields = [
+                'alibaba' => '阿里旺旺',
+                'wechat' => '微信',
+                'facebook' => 'Facebook',
+                'linkedin' => 'LinkedIn'
+            ];
+            
+            foreach ($contacts as $contact) {
+                foreach ($socialFields as $field => $label) {
+                    for ($i = 1; $i <= 3; $i++) {
+                        $fieldName = $field . '_' . $i;
+                        if (!empty($contact[$fieldName])) {
+                            $value = trim($contact[$fieldName]);
+                            if (strlen($value) > 3) { // 至少4个字符
+                                $socialTerms[] = [
+                                    'type' => $field,
+                                    'label' => $label,
+                                    'value' => $value
+                                ];
+                            }
+                        }
+                    }
+                }
+            }
+            
+            if (!empty($socialTerms)) {
+                foreach ($socialTerms as $term) {
+                    $field = $term['type'];
+                    $value = $term['value'];
+                    $label = $term['label'];
+                    
+                    // 根据社交媒体类型构建不同的查询
+                    $socialQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime FROM customer c 
+                                    JOIN customer_contact cc ON c.id = cc.customer_id
+                                    WHERE c.cs_belong != " . $_SESSION['employee_id'] . "
+                                    AND c.id != " . $excludeId . " AND (";
+                    
+                    // 根据社交账号类型确定匹配方式                    
+                    if ($field == 'alibaba' || $field == 'wechat') {
+                        // 阿里旺旺和微信用精确匹配
+                        $socialQuery .= 
+                            "cc.{$field}_1 = '" . $conn->real_escape_string($value) . "' OR " .
+                            "cc.{$field}_2 = '" . $conn->real_escape_string($value) . "' OR " .
+                            "cc.{$field}_3 = '" . $conn->real_escape_string($value) . "'";
+                    } else {
+                        // Facebook和LinkedIn用模糊匹配
+                        $socialQuery .= 
+                            "cc.{$field}_1 LIKE '%" . $conn->real_escape_string($value) . "%' OR " .
+                            "cc.{$field}_2 LIKE '%" . $conn->real_escape_string($value) . "%' OR " .
+                            "cc.{$field}_3 LIKE '%" . $conn->real_escape_string($value) . "%'";
+                    }
+                    
+                    $socialQuery .= ") LIMIT 1";
+                    $socialResult = $conn->query($socialQuery);
+                    
+                    if ($socialResult && $socialResult->num_rows > 0) {
+                        $row = $socialResult->fetch_assoc();
+                        $matchCustomerId = $row['id'];
+                        $matchCustomerCode = $row['cs_code'];
+                        $matchOwner = $row['cs_belong'];
+                        $matchAddTime = $row['cs_addtime'];
+                        $matchDetails = $label . "账号匹配";
+                        
+                        // 不同社交媒体账号的可信度
+                        switch ($field) {
+                            case 'alibaba':
+                                $matchScore = 0.85;
+                                break;
+                            case 'wechat':
+                                $matchScore = 0.85;
+                                break;
+                            case 'facebook':
+                                $matchScore = 0.80;
+                                break;
+                            case 'linkedin':
+                                $matchScore = 0.80;
+                                break;
+                            default:
+                                $matchScore = 0.75;
+                        }
+                        
+                        $duplicateFound = true;
+                        break; // 找到匹配就退出循环
+                    }
+                }
+            }
+        }
+        
+        // 4. 最后尝试全文检索 - 作为补充检测手段
+        if (!$duplicateFound) {
+            // 准备全文检索字符串
+            $searchTerms = [];
+            
+            // 处理所有联系人信息用于检索
+            foreach ($contacts as $contact) {
+                // 添加联系人名称
+                if (!empty($contact['contact_name'])) {
+                    $searchTerms[] = textUncode($contact['contact_name']);
+                }
+                
+                // 所有联系方式的组合检索
+                $contactFields = [
+                    'tel', 'email', 'whatsapp', 'wechat', 
+                    'linkedin', 'facebook', 'alibaba'
+                ];
+                
+                foreach ($contactFields as $fieldType) {
+                    for ($i = 1; $i <= 3; $i++) {
+                        $field = $fieldType . '_' . $i;
+                        if (!empty($contact[$field])) {
+                            // 针对不同类型的联系方式进行不同清理
+                            if ($fieldType == 'tel' || $fieldType == 'whatsapp') {
+                                $cleaned = preg_replace('/[^0-9]/', '', $contact[$field]);
+                                if (strlen($cleaned) > 5) {
+                                    $searchTerms[] = $cleaned;
+                                }
+                            } else if ($fieldType == 'email') {
+                                $cleaned = strtolower(trim($contact[$field]));
+                                if (strpos($cleaned, '@') !== false) {
+                                    $searchTerms[] = $cleaned;
+                                }
+                            } else {
+                                $searchTerms[] = trim($contact[$field]);
+                            }
+                        }
+                    }
+                }
+            }
+            
+            // 如果有搜索条件
+            if (!empty($searchTerms)) {
+                // 创建MATCH AGAINST语句的词条
+                $searchStr = implode(' ', array_unique(array_filter($searchTerms)));
+                
+                // 确保搜索字符串不为空
+                if (!empty($searchStr)) {
+                    // 构建全文检索SQL
+                    $ftQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime,
+                                MATCH( cc.tel_1, cc.tel_2, cc.tel_3, 
+                                      cc.email_1, cc.email_2, cc.email_3,
+                                      cc.whatsapp_1, cc.whatsapp_2, cc.whatsapp_3,
+                                      cc.wechat_1, cc.wechat_2, cc.wechat_3
+                                       ) 
+                                      AGAINST('" . $conn->real_escape_string($searchStr) . "' IN NATURAL LANGUAGE MODE) AS score
+                                FROM customer c 
+                                JOIN customer_contact cc ON c.id = cc.customer_id
+                                WHERE c.id != " . $excludeId . "
+                                HAVING score > 0.7  
+                                ORDER BY score DESC
+                                LIMIT 1";      
+                    $ftResult = $conn->query($ftQuery);
+                    
+                    if(!($ftResult && $ftResult->num_rows > 0 ))
+                    {
+
+                        $ftQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime,
+                        MATCH( cc.alibaba_1, cc.alibaba_2, cc.alibaba_3,
+                              cc.facebook_1, cc.facebook_2, cc.facebook_3,
+                              cc.linkedin_1, cc.linkedin_2, cc.linkedin_3) 
+                              AGAINST('" . $conn->real_escape_string($searchStr) . "' IN NATURAL LANGUAGE MODE) AS score
+                        FROM customer c 
+                        JOIN customer_contact cc ON c.id = cc.customer_id
+                        WHERE c.id != " . $excludeId . "
+                        HAVING score > 0.7  
+                        ORDER BY score DESC
+                        LIMIT 1";      
+                       $ftResult = $conn->query($ftQuery);
+                    }
+
+
+
+                    if ($ftResult && $ftResult->num_rows > 0) {
+                        $row = $ftResult->fetch_assoc();
+                        $matchCustomerId = $row['id'];
+                        $matchCustomerCode = $row['cs_code'];
+                        $matchOwner = $row['cs_belong'];
+                        $matchAddTime = $row['cs_addtime'];
+                        $matchDetails = "全文检索相似度" . number_format($row['score'] * 100, 1) . "%";
+                        $matchScore = $row['score'];
+                        $duplicateFound = true;
+                    }
+                }
+            }
+        }
+        
+        // 如果找到重复客户,记录并提示
+        if ($duplicateFound) {
+            // 获取客户所有者姓名
+            $ownerResult = $conn->query("SELECT em_user FROM employee WHERE id = " . $matchOwner);
+            $ownerRow = $ownerResult->fetch_assoc();
+            $owner = textUncode($ownerRow['em_user']);
+            
+            // 确定谁先录入
+            if (strtotime($cs_addtime) > strtotime($matchAddTime)) {
+                $tstr = "INSERT INTO logrecord (loginName, loginIp, loginTime, loginAct) VALUES ('" .
+                       $_SESSION['employee_name'] . "', '" . getIp() . "', '" . date('Y-m-d H:i:s') . "', '" .
+                       $_SESSION['employee_name'] . "编辑客户\"" . $cs_code . "\",该客户与\"" . 
+                       textUncode($matchCustomerCode) . "\"存在重复,<br>匹配类型:" . $matchDetails . 
+                       "<br>客户由:" . $owner . $matchAddTime . "首次录入')";
+            } else {
+                $tstr = "INSERT INTO logrecord (loginName, loginIp, loginTime, loginAct) VALUES ('" .
+                       $_SESSION['employee_name'] . "', '" . getIp() . "', '" . date('Y-m-d H:i:s') . "', '" .
+                       $_SESSION['employee_name'] . "编辑客户\"" . $cs_code . "\",该客户与\"" . 
+                       textUncode($matchCustomerCode) . "\"存在重复,<br>匹配类型:" . $matchDetails . 
+                       "<br>客户由:" . $_SESSION['employee_name'] . $cs_addtime . "首次录入')";
+            }
+            
+            $conn->query($tstr);
+            echo "<script>alert('warning.2.录入信息\\n与" . $owner . "客户编号:" . textUncode($matchCustomerCode) . 
+                 "\\存在重复(" . $matchDetails . "),未能保存\\n请联系管理员核实!');history.back();</script>";
+            exit;
+        }
+    }
 }
 
 // Save or update customer data