customerSave.php 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. <?php
  2. require_once 'conn.php';
  3. checkLogin();
  4. // 设置多字节字符编码
  5. mb_internal_encoding('UTF-8');
  6. ?>
  7. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  8. <html xmlns="http://www.w3.org/1999/xhtml">
  9. <head>
  10. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  11. <title>管理区域</title>
  12. <link rel="stylesheet" href="system/css/common.css" type="text/css" />
  13. <script src="system/js/jquery-1.7.2.min.js"></script>
  14. <script src="js/js.js"></script>
  15. </head>
  16. <body class="clear">
  17. <?php
  18. // Get query parameters
  19. $page = $_GET['Page'] ?? '';
  20. $keys = urlencode($_GET['Keys'] ?? '');
  21. $fliterBusiness = $_GET['fliterBusiness'] ?? '';
  22. $fliterDeal = $_GET['Deal'] ?? '';
  23. // Get form data
  24. $id = $_POST['id'] ?? '';
  25. $cs_code = textEncode($_POST['cs_code'] ?? '');
  26. $cs_company = textEncode($_POST['cs_company'] ?? '');
  27. $cs_country = $_POST['cs_country'] ?? '';
  28. $cs_from = $_POST['cs_from'] ?? '';
  29. $cs_address = textEncode($_POST['cs_address'] ?? '');
  30. $cs_type = $_POST['cs_type'] ?? []; // Changed to array for multi-select
  31. $cs_belongclient = $_POST['cs_belongclient'] ?? '';
  32. $cs_addtime = $_POST['cs_addtime'] ?? '';
  33. $cs_updatetime = date('Y-m-d H:i:s');
  34. $cs_belong = $_SESSION['employee_id'];
  35. $cs_state = 1;
  36. $cs_deal = $_POST['cs_deal'] ?? '';
  37. $allowedit = $_POST['Permissions'] ?? '0';
  38. // Get contact information from the form
  39. $contacts = $_POST['contact'] ?? [];
  40. // Validate numeric values
  41. $allowedit = is_numeric($allowedit) ? $allowedit : 0;
  42. $cs_country = (is_numeric($cs_country) && $cs_country !== '') ? $cs_country : 0;
  43. $cs_from = (is_numeric($cs_from) && $cs_from !== '') ? $cs_from : 0;
  44. $cs_deal = (is_numeric($cs_deal) && $cs_deal !== '') ? $cs_deal : 1;
  45. $cs_belongClient = (is_numeric($cs_belongclient) && $cs_belongclient !== '') ? $cs_belongclient : 0;
  46. $cs_note = htmlEncode($_POST['cs_note'] ?? '');
  47. $_POST['mytag']=str_replace(" ", "", $_POST['mytag']);
  48. $mytag = trim(textEncode($_POST['mytag'] ?? ''));
  49. $mytag = str_replace(['&#60;&#47;span&#62;&#60;span&#62;', '&#60;&#47;span&#62;', '&#60;span&#62;'], [',', '', ''], $mytag);
  50. $mytag = explode(',', $mytag);
  51. // Auto-detect source from code
  52. if (strpos($cs_code, ';1688') !== false) {
  53. $cs_from = 1; // 1688
  54. }
  55. if (strpos($cs_code, ';阿里') !== false) {
  56. $cs_from = 2; // International station
  57. }
  58. // Get the first contact for validation (if any)
  59. $primary_contact = !empty($contacts) ? current($contacts) : [];
  60. // Check contact-specific validation requirements based on source
  61. if ($allowedit != 1) {
  62. // Get the first contact's information for validation
  63. $contact_name = textEncode($primary_contact['contact_name'] ?? '');
  64. $tel_1 = textEncode($primary_contact['tel_1'] ?? '');
  65. $wechat_1 = textEncode($primary_contact['wechat_1'] ?? '');
  66. $whatsapp_1 = textEncode($primary_contact['whatsapp_1'] ?? '');
  67. $email_1 = textEncode($primary_contact['email_1'] ?? '');
  68. $alibaba_1 = textEncode($primary_contact['alibaba_1'] ?? '');
  69. $facebook_1 = textEncode($primary_contact['facebook_1'] ?? '');
  70. // Alibaba validation
  71. if (($cs_from == 1 || $cs_from == 2) && empty($alibaba_1)) {
  72. echo "<script>alert('阿里旺旺为必填项');history.back();</script>";
  73. exit;
  74. }
  75. // Website source validation
  76. if (strpos($cs_code, '官网') !== false) {
  77. $cs_from = 3;
  78. }
  79. if ($cs_from == 3 && empty($tel_1) && empty($whatsapp_1) && empty($wechat_1)) {
  80. echo "<script>alert('电话和WhatsApp为必填项');history.back();</script>";
  81. exit;
  82. }
  83. // Market customer validation
  84. if ($cs_from == 8 && empty($wechat_1)) {
  85. echo "<script>alert('微信为必填项');history.back();</script>";
  86. exit;
  87. }
  88. // Facebook validation
  89. if ($cs_from == 12 && empty($facebook_1)) {
  90. echo "<script>alert('Facebook为必填项');history.back();</script>";
  91. exit;
  92. }
  93. }
  94. // Determine action type
  95. $act = empty($id) || !is_numeric($id) ? 'addSave' : 'editSave';
  96. if ($act === 'editSave') {
  97. // Verify customer ownership - 将bind_param改为SQL拼接
  98. $id = intval($id); // 确保ID是整数,防止SQL注入
  99. $sql = "SELECT cs_belong FROM customer WHERE id = " . $id;
  100. $result = $conn->query($sql);
  101. if ($row = $result->fetch_assoc()) {
  102. if ($row['cs_belong'] != $cs_belong) {
  103. echo "<script>alert('抱歉,该客户属于另一业务,你没有权限修改');history.back();</script>";
  104. exit;
  105. }
  106. } else {
  107. echo "<script>alert('没有此客户!');history.back();</script>";
  108. exit;
  109. }
  110. }
  111. // Validate customer code
  112. if (empty($cs_code)) {
  113. echo "<script>alert('客户编码不能为空');history.back();</script>";
  114. exit;
  115. }
  116. $customer_id = is_numeric($id) ? intval($id) : 0;
  117. // Check for duplicate customer information
  118. $checkStr = "SELECT c.*, cc.*
  119. FROM customer c
  120. LEFT JOIN customer_contact cc ON c.id = cc.customer_id
  121. WHERE c.id != " . $customer_id." AND ( 1=2 ";
  122. $Dupli = "";
  123. /* 暂时不需要这些检查 START */
  124. // Company name similarity check
  125. //if (!empty($cs_company)) {
  126. // $companyWords = explode(' ', strtolower($cs_company));
  127. // foreach ($companyWords as $word) {
  128. // if (strlen($word) > 3) { // Only check words longer than 3 characters
  129. // $checkStr .= " OR LOWER(c.cs_company) LIKE '%" . $conn->real_escape_string($word) . "%'";
  130. // }
  131. // }
  132. //}
  133. // Address similarity check
  134. //if (!empty($cs_address)) {
  135. // $addressWords = explode(' ', strtolower($cs_address));
  136. // foreach ($addressWords as $word) {
  137. // if (strlen($word) > 3) { // Only check words longer than 3 characters
  138. // $checkStr .= " OR LOWER(c.cs_address) LIKE '%" . $conn->real_escape_string($word) . "%'";
  139. // }
  140. // }
  141. //}
  142. /* 暂时不需要这些检查 END */
  143. // Check all contacts for duplicates
  144. foreach ($contacts as $contact) {
  145. //遍历处理空格
  146. foreach ($contact as $key => $value) {
  147. $contact[$key] = trim($value);
  148. }
  149. // Check all phone numbers
  150. for ($i = 1; $i <= 3; $i++) {
  151. $tel_field = 'tel_' . $i;
  152. if (!empty($contact[$tel_field])) {
  153. $tel_format = numFormat($contact[$tel_field]);
  154. // Remove country code and spaces for better matching
  155. $tel_clean = preg_replace('/[^0-9]/', '', $tel_format);
  156. if(!empty($tel_clean))
  157. {
  158. $checkStr .= " OR cc.tel_1_format LIKE '%" . mb_substr($tel_clean, -9) . "%'" .
  159. " OR cc.tel_2_format LIKE '%" . mb_substr($tel_clean, -9) . "%'" .
  160. " OR cc.tel_3_format LIKE '%" . mb_substr($tel_clean, -9) . "%'" .
  161. " OR cc.wechat_1 LIKE '%" . mb_substr($tel_clean, -9) . "%'" .
  162. " OR cc.wechat_2 LIKE '%" . mb_substr($tel_clean, -9) . "%'" .
  163. " OR cc.wechat_3 LIKE '%" . mb_substr($tel_clean, -9) . "%'";
  164. $Dupli .= "电话" . $i . ":" . $contact[$tel_field] . " ";
  165. }
  166. }
  167. }
  168. // Check all email addresses
  169. for ($i = 1; $i <= 3; $i++) {
  170. $email_field = 'email_' . $i;
  171. if (!empty($contact[$email_field])) {
  172. $contact[$email_field]=trim($contact[$email_field]);
  173. $email = strtolower($contact[$email_field]);
  174. $checkStr .= " OR LOWER(cc.email_1) = '" . $conn->real_escape_string($email) . "'" .
  175. " OR LOWER(cc.email_2) = '" . $conn->real_escape_string($email) . "'" .
  176. " OR LOWER(cc.email_3) = '" . $conn->real_escape_string($email) . "'";
  177. $Dupli .= "邮箱" . $i . ":" . $contact[$email_field] . " ";
  178. }
  179. }
  180. // Check all WhatsApp numbers
  181. for ($i = 1; $i <= 3; $i++) {
  182. $whatsapp_field = 'whatsapp_' . $i;
  183. if (!empty($contact[$whatsapp_field])) {
  184. $whatsapp_format = numFormat($contact[$whatsapp_field]);
  185. $whatsapp_clean = preg_replace('/[^0-9]/', '', $whatsapp_format);
  186. if(!empty($whatsapp_clean))
  187. {
  188. $checkStr .= " OR cc.whatsapp_1_format LIKE '%" . mb_substr($whatsapp_clean, -9) . "%'" .
  189. " OR cc.whatsapp_2_format LIKE '%" . mb_substr($whatsapp_clean, -9) . "%'" .
  190. " OR cc.whatsapp_3_format LIKE '%" . mb_substr($whatsapp_clean, -9) . "%'" .
  191. " OR cc.tel_1_format LIKE '%" . mb_substr($whatsapp_clean, -9) . "%'" .
  192. " OR cc.tel_2_format LIKE '%" . mb_substr($whatsapp_clean, -9) . "%'" .
  193. " OR cc.tel_3_format LIKE '%" . mb_substr($whatsapp_clean, -9) . "%'";
  194. $Dupli .= "WhatsApp" . $i . ":" . $contact[$whatsapp_field] . " ";
  195. }
  196. }
  197. }
  198. // Check all WeChat accounts
  199. for ($i = 1; $i <= 3; $i++) {
  200. $wechat_field = 'wechat_' . $i;
  201. if (!empty($contact[$wechat_field])) {
  202. $wechat = $contact[$wechat_field];
  203. $checkStr .= " OR cc.wechat_1 LIKE '%" . textEncode($conn->real_escape_string($wechat)) . "%'" .
  204. " OR cc.wechat_2 LIKE '%" . textEncode($conn->real_escape_string($wechat)) . "%'" .
  205. " OR cc.wechat_3 LIKE '%" . textEncode( $conn->real_escape_string($wechat)) . "%'" .
  206. " OR cc.tel_1_format LIKE '%" . $conn->real_escape_string($wechat) . "%'" .
  207. " OR cc.tel_2_format LIKE '%" . $conn->real_escape_string($wechat). "%'" .
  208. " OR cc.tel_3_format LIKE '%" . $conn->real_escape_string($wechat) . "%'";
  209. $Dupli .= "微信" . $i . ":" . $contact[$wechat_field] . " ";
  210. }
  211. }
  212. // Check all LinkedIn accounts
  213. for ($i = 1; $i <= 3; $i++) {
  214. $linkedin_field = 'linkedin_' . $i;
  215. if (!empty($contact[$linkedin_field])) {
  216. $linkedin = strtolower($contact[$linkedin_field]);
  217. $checkStr .= " OR LOWER(cc.linkedin_1) LIKE '%" . textEncode($conn->real_escape_string($linkedin)) . "%'" .
  218. " OR LOWER(cc.linkedin_2) LIKE '%" . textEncode($conn->real_escape_string($linkedin)) . "%'" .
  219. " OR LOWER(cc.linkedin_3) LIKE '%" . textEncode($conn->real_escape_string($linkedin)) . "%'";
  220. $Dupli .= "LinkedIn" . $i . ":" . $contact[$linkedin_field] . " ";
  221. }
  222. }
  223. // Check all Facebook accounts
  224. for ($i = 1; $i <= 3; $i++) {
  225. $facebook_field = 'facebook_' . $i;
  226. if (!empty($contact[$facebook_field])) {
  227. $facebook = strtolower($contact[$facebook_field]);
  228. $checkStr .= " OR LOWER(cc.facebook_1) LIKE '%" . textEncode($conn->real_escape_string($facebook)) . "%'" .
  229. " OR LOWER(cc.facebook_2) LIKE '%" . textEncode($conn->real_escape_string($facebook)) . "%'" .
  230. " OR LOWER(cc.facebook_3) LIKE '%" . textEncode($conn->real_escape_string($facebook)) . "%'";
  231. $Dupli .= "Facebook" . $i . ":" . $contact[$facebook_field] . " ";
  232. }
  233. }
  234. // Check all Alibaba accounts
  235. for ($i = 1; $i <= 3; $i++) {
  236. $alibaba_field = 'alibaba_' . $i;
  237. if (!empty($contact[$alibaba_field])) {
  238. $alibaba = strtolower($contact[$alibaba_field]);
  239. if (strlen($alibaba) < 10) {
  240. $checkStr .= " OR LOWER(cc.alibaba_1) LIKE '" . textEncode($conn->real_escape_string($alibaba)) . "'" .
  241. " OR LOWER(cc.alibaba_2) LIKE '" . textEncode($conn->real_escape_string($alibaba)) . "'" .
  242. " OR LOWER(cc.alibaba_3) LIKE '" . textEncode($conn->real_escape_string($alibaba)) . "'";
  243. } else {
  244. // 修改正则表达式,仅移除特殊符号,保留中文和英文字母数字
  245. $alibaba_clean = preg_replace('/[^\p{Han}0-9a-zA-Z]/u', '', $alibaba);
  246. $checkStr .= " OR LOWER(cc.alibaba_1) LIKE '%" . textEncode(mb_substr($alibaba_clean, -9)) . "%'" .
  247. " OR LOWER(cc.alibaba_2) LIKE '%" . textEncode(mb_substr($alibaba_clean, -9)) . "%'" .
  248. " OR LOWER(cc.alibaba_3) LIKE '%" . textEncode(mb_substr($alibaba_clean, -9)) . "%'";
  249. }
  250. $Dupli .= "阿里旺旺" . $i . ":" . $contact[$alibaba_field] . " ";
  251. }
  252. }
  253. }
  254. $checkStr .= " ) ORDER BY c.id ASC";
  255. if ($allowedit != 1) {
  256. $result = $conn->query($checkStr);
  257. if ($result && $result->num_rows > 0) {
  258. $row = $result->fetch_assoc();
  259. // Get owner name
  260. $ownerResult = $conn->query("SELECT em_user FROM employee WHERE id = " . $row['cs_belong']);
  261. $ownerRow = $ownerResult->fetch_assoc();
  262. $owner = textUncode($ownerRow['em_user']);
  263. // Determine who entered first
  264. if (strtotime($cs_addtime) > strtotime($row['cs_addtime'])) {
  265. $tstr = "INSERT INTO logrecord (loginName, loginIp, loginTime, loginAct) VALUES ('" .
  266. $_SESSION['employee_name'] . "', '" . getIp() . "', '" . date('Y-m-d H:i:s') . "', '" .
  267. $_SESSION['employee_name'] . "编辑客户\"" . $cs_code . "\",该客户与\"" .
  268. textUncode($row['cs_code']) . "\"高度类似,<br>重复项为:" . $Dupli . "<br>客户由:" .
  269. $_SESSION['employee_name'] . $cs_addtime . "首次录入')";
  270. } else {
  271. $tstr = "INSERT INTO logrecord (loginName, loginIp, loginTime, loginAct) VALUES ('" .
  272. $_SESSION['employee_name'] . "', '" . getIp() . "', '" . date('Y-m-d H:i:s') . "', '" .
  273. $_SESSION['employee_name'] . "编辑客户\"" . $cs_code . "\",该客户与\"" .
  274. textUncode($row['cs_code']) . "\"高度类似,<br>重复项为:" . $Dupli . "<br>客户由:" .
  275. $owner . $row['cs_addtime'] . "首次录入')";
  276. }
  277. $conn->query($tstr);
  278. echo "<script>alert('warning.1.录入信息\\n与" . $owner . "客户编号:" . textUncode($row['cs_code']) .
  279. "\\n高度类似,未能保存,请联系管理员核实!');history.back();</script>";
  280. exit;
  281. }
  282. // else
  283. // {
  284. // //全文检索再检查一次
  285. // //先去掉联系方式中的特殊字符
  286. // //用联系方式进行全文fullindex检索,用相关性分数大于百分70 的进行检查
  287. //
  288. // // 根据不同联系方式类型进行专门检查
  289. // $duplicateFound = false;
  290. // $matchDetails = '';
  291. // $matchScore = 0;
  292. // $matchCustomerId = 0;
  293. // $matchCustomerCode = '';
  294. // $matchOwner = '';
  295. // $matchAddTime = '';
  296. //
  297. // // 编辑模式下需要排除自己的ID
  298. // $excludeId = ($act === 'editSave' && is_numeric($id)) ? intval($id) : 0;
  299. //
  300. // // 1. 优先检查邮箱 - 邮箱是最精确的匹配
  301. // $emailTerms = [];
  302. // foreach ($contacts as $contact) {
  303. // for ($i = 1; $i <= 3; $i++) {
  304. // $field = 'email_' . $i;
  305. // if (!empty($contact[$field])) {
  306. // $email = strtolower(trim($contact[$field]));
  307. // if (strpos($email, '@') !== false) {
  308. // $emailTerms[] = $email;
  309. // }
  310. // }
  311. // }
  312. // }
  313. //
  314. // if (!empty($emailTerms)) {
  315. // $emailQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime, cc.email_1, cc.email_2, cc.email_3
  316. // FROM customer c
  317. // JOIN customer_contact cc ON c.id = cc.customer_id
  318. // WHERE c.cs_belong != " . $_SESSION['employee_id'] . "
  319. // AND c.id != " . $excludeId . " AND (";
  320. //
  321. // $emailConditions = [];
  322. // foreach ($emailTerms as $email) {
  323. // $emailConditions[] = "cc.email_1 = '" . $conn->real_escape_string($email) . "'";
  324. // $emailConditions[] = "cc.email_2 = '" . $conn->real_escape_string($email) . "'";
  325. // $emailConditions[] = "cc.email_3 = '" . $conn->real_escape_string($email) . "'";
  326. // }
  327. //
  328. // $emailQuery .= implode(" OR ", $emailConditions) . ") LIMIT 1";
  329. // $emailResult = $conn->query($emailQuery);
  330. //
  331. // if ($emailResult && $emailResult->num_rows > 0) {
  332. // $row = $emailResult->fetch_assoc();
  333. // $matchCustomerId = $row['id'];
  334. // $matchCustomerCode = $row['cs_code'];
  335. // $matchOwner = $row['cs_belong'];
  336. // $matchAddTime = $row['cs_addtime'];
  337. // $matchDetails = "邮箱完全匹配";
  338. // $matchScore = 0.95; // 邮箱精确匹配,高可信度
  339. // $duplicateFound = true;
  340. // }
  341. // }
  342. //
  343. // // 2. 检查电话号码与WhatsApp - 清理后进行后缀匹配
  344. // if (!$duplicateFound) {
  345. // $phoneTerms = [];
  346. // foreach ($contacts as $contact) {
  347. // // 收集所有电话号码
  348. // for ($i = 1; $i <= 3; $i++) {
  349. // $fields = ['tel_' . $i, 'whatsapp_' . $i];
  350. // foreach ($fields as $field) {
  351. // if (!empty($contact[$field])) {
  352. // $cleaned = preg_replace('/[^0-9]/', '', $contact[$field]);
  353. // if (strlen($cleaned) > 7) { // 至少8位有效数字
  354. // $phoneTerms[] = $cleaned;
  355. // }
  356. // }
  357. // }
  358. // }
  359. // }
  360. //
  361. // if (!empty($phoneTerms)) {
  362. // $phoneQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime,
  363. // cc.tel_1_format, cc.tel_2_format, cc.tel_3_format,
  364. // cc.whatsapp_1_format, cc.whatsapp_2_format, cc.whatsapp_3_format
  365. // FROM customer c
  366. // JOIN customer_contact cc ON c.id = cc.customer_id
  367. // WHERE c.cs_belong != " . $_SESSION['employee_id'] . "
  368. // AND c.id != " . $excludeId . " AND (";
  369. //
  370. // $phoneConditions = [];
  371. // foreach ($phoneTerms as $phone) {
  372. // // 使用后8位进行匹配,避免国家代码等差异
  373. // $suffix = substr($phone, -8);
  374. // if (strlen($suffix) == 8) {
  375. // $phoneConditions[] = "cc.tel_1_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
  376. // $phoneConditions[] = "cc.tel_2_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
  377. // $phoneConditions[] = "cc.tel_3_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
  378. // $phoneConditions[] = "cc.whatsapp_1_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
  379. // $phoneConditions[] = "cc.whatsapp_2_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
  380. // $phoneConditions[] = "cc.whatsapp_3_format LIKE '%" . $conn->real_escape_string($suffix) . "'";
  381. // }
  382. // }
  383. //
  384. // if (!empty($phoneConditions)) {
  385. // $phoneQuery .= implode(" OR ", $phoneConditions) . ") LIMIT 1";
  386. // $phoneResult = $conn->query($phoneQuery);
  387. //
  388. // if ($phoneResult && $phoneResult->num_rows > 0) {
  389. // $row = $phoneResult->fetch_assoc();
  390. // $matchCustomerId = $row['id'];
  391. // $matchCustomerCode = $row['cs_code'];
  392. // $matchOwner = $row['cs_belong'];
  393. // $matchAddTime = $row['cs_addtime'];
  394. // $matchDetails = "电话号码后8位匹配";
  395. // $matchScore = 0.90; // 电话匹配,高可信度
  396. // $duplicateFound = true;
  397. // }
  398. // }
  399. // }
  400. // }
  401. //
  402. // // 3. 检查社交媒体账号 (alibaba/wechat/facebook/linkedin)
  403. // if (!$duplicateFound) {
  404. // $socialTerms = [];
  405. // $socialFields = [
  406. // 'alibaba' => '阿里旺旺',
  407. // 'wechat' => '微信',
  408. // 'facebook' => 'Facebook',
  409. // 'linkedin' => 'LinkedIn'
  410. // ];
  411. //
  412. // foreach ($contacts as $contact) {
  413. // foreach ($socialFields as $field => $label) {
  414. // for ($i = 1; $i <= 3; $i++) {
  415. // $fieldName = $field . '_' . $i;
  416. // if (!empty($contact[$fieldName])) {
  417. // $value = trim($contact[$fieldName]);
  418. // if (strlen($value) > 3) { // 至少4个字符
  419. // $socialTerms[] = [
  420. // 'type' => $field,
  421. // 'label' => $label,
  422. // 'value' => $value
  423. // ];
  424. // }
  425. // }
  426. // }
  427. // }
  428. // }
  429. //
  430. // if (!empty($socialTerms)) {
  431. // foreach ($socialTerms as $term) {
  432. // $field = $term['type'];
  433. // $value = $term['value'];
  434. // $label = $term['label'];
  435. //
  436. // // 根据社交媒体类型构建不同的查询
  437. // $socialQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime FROM customer c
  438. // JOIN customer_contact cc ON c.id = cc.customer_id
  439. // WHERE c.cs_belong != " . $_SESSION['employee_id'] . "
  440. // AND c.id != " . $excludeId . " AND (";
  441. //
  442. // // 根据社交账号类型确定匹配方式
  443. // if ($field == 'alibaba' || $field == 'wechat') {
  444. // // 阿里旺旺和微信用精确匹配
  445. // $socialQuery .=
  446. // "cc.{$field}_1 = '" . $conn->real_escape_string($value) . "' OR " .
  447. // "cc.{$field}_2 = '" . $conn->real_escape_string($value) . "' OR " .
  448. // "cc.{$field}_3 = '" . $conn->real_escape_string($value) . "'";
  449. // } else {
  450. // // Facebook和LinkedIn用模糊匹配
  451. // $socialQuery .=
  452. // "cc.{$field}_1 LIKE '%" . $conn->real_escape_string($value) . "%' OR " .
  453. // "cc.{$field}_2 LIKE '%" . $conn->real_escape_string($value) . "%' OR " .
  454. // "cc.{$field}_3 LIKE '%" . $conn->real_escape_string($value) . "%'";
  455. // }
  456. //
  457. // $socialQuery .= ") LIMIT 1";
  458. // $socialResult = $conn->query($socialQuery);
  459. //
  460. // if ($socialResult && $socialResult->num_rows > 0) {
  461. // $row = $socialResult->fetch_assoc();
  462. // $matchCustomerId = $row['id'];
  463. // $matchCustomerCode = $row['cs_code'];
  464. // $matchOwner = $row['cs_belong'];
  465. // $matchAddTime = $row['cs_addtime'];
  466. // $matchDetails = $label . "账号匹配";
  467. //
  468. // // 不同社交媒体账号的可信度
  469. // switch ($field) {
  470. // case 'alibaba':
  471. // $matchScore = 0.85;
  472. // break;
  473. // case 'wechat':
  474. // $matchScore = 0.85;
  475. // break;
  476. // case 'facebook':
  477. // $matchScore = 0.80;
  478. // break;
  479. // case 'linkedin':
  480. // $matchScore = 0.80;
  481. // break;
  482. // default:
  483. // $matchScore = 0.75;
  484. // }
  485. //
  486. // $duplicateFound = true;
  487. // break; // 找到匹配就退出循环
  488. // }
  489. // }
  490. // }
  491. // }
  492. //
  493. // // 4. 最后尝试全文检索 - 作为补充检测手段
  494. // if (!$duplicateFound) {
  495. // // 准备全文检索字符串
  496. // $searchTerms = [];
  497. //
  498. // // 处理所有联系人信息用于检索
  499. // foreach ($contacts as $contact) {
  500. // // 添加联系人名称
  501. // if (!empty($contact['contact_name'])) {
  502. // $searchTerms[] = textUncode($contact['contact_name']);
  503. // }
  504. //
  505. // // 所有联系方式的组合检索
  506. // $contactFields = [
  507. // 'tel', 'email', 'whatsapp', 'wechat',
  508. // 'linkedin', 'facebook', 'alibaba'
  509. // ];
  510. //
  511. // foreach ($contactFields as $fieldType) {
  512. // for ($i = 1; $i <= 3; $i++) {
  513. // $field = $fieldType . '_' . $i;
  514. // if (!empty($contact[$field])) {
  515. // // 针对不同类型的联系方式进行不同清理
  516. // if ($fieldType == 'tel' || $fieldType == 'whatsapp') {
  517. // $cleaned = preg_replace('/[^0-9]/', '', $contact[$field]);
  518. // if (strlen($cleaned) > 5) {
  519. // $searchTerms[] = $cleaned;
  520. // }
  521. // } else if ($fieldType == 'email') {
  522. // $cleaned = strtolower(trim($contact[$field]));
  523. // if (strpos($cleaned, '@') !== false) {
  524. // $searchTerms[] = $cleaned;
  525. // }
  526. // } else {
  527. // $searchTerms[] = trim($contact[$field]);
  528. // }
  529. // }
  530. // }
  531. // }
  532. // }
  533. //
  534. // // 如果有搜索条件
  535. // if (!empty($searchTerms)) {
  536. // // 创建MATCH AGAINST语句的词条
  537. // $searchStr = implode(' ', array_unique(array_filter($searchTerms)));
  538. //
  539. // // 确保搜索字符串不为空
  540. // if (!empty($searchStr)) {
  541. // // 构建全文检索SQL
  542. // $ftQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime,
  543. // MATCH( cc.tel_1, cc.tel_2, cc.tel_3,
  544. // cc.email_1, cc.email_2, cc.email_3,
  545. // cc.whatsapp_1, cc.whatsapp_2, cc.whatsapp_3,
  546. // cc.wechat_1, cc.wechat_2, cc.wechat_3
  547. // )
  548. // AGAINST('" . $conn->real_escape_string($searchStr) . "' IN NATURAL LANGUAGE MODE) AS score
  549. // FROM customer c
  550. // JOIN customer_contact cc ON c.id = cc.customer_id
  551. // WHERE c.id != " . $excludeId . "
  552. // HAVING score > 0.7
  553. // ORDER BY score DESC
  554. // LIMIT 1";
  555. // $ftResult = $conn->query($ftQuery);
  556. //
  557. // if(!($ftResult && $ftResult->num_rows > 0 ))
  558. // {
  559. //
  560. // $ftQuery = "SELECT c.id, c.cs_code, c.cs_belong, c.cs_addtime,
  561. // MATCH( cc.alibaba_1, cc.alibaba_2, cc.alibaba_3,
  562. // cc.facebook_1, cc.facebook_2, cc.facebook_3,
  563. // cc.linkedin_1, cc.linkedin_2, cc.linkedin_3)
  564. // AGAINST('" . $conn->real_escape_string($searchStr) . "' IN NATURAL LANGUAGE MODE) AS score
  565. // FROM customer c
  566. // JOIN customer_contact cc ON c.id = cc.customer_id
  567. // WHERE c.id != " . $excludeId . "
  568. // HAVING score > 0.7
  569. // ORDER BY score DESC
  570. // LIMIT 1";
  571. // $ftResult = $conn->query($ftQuery);
  572. // }
  573. //
  574. //
  575. //
  576. // if ($ftResult && $ftResult->num_rows > 0) {
  577. // $row = $ftResult->fetch_assoc();
  578. // $matchCustomerId = $row['id'];
  579. // $matchCustomerCode = $row['cs_code'];
  580. // $matchOwner = $row['cs_belong'];
  581. // $matchAddTime = $row['cs_addtime'];
  582. // $matchDetails = "全文检索相似度" . number_format($row['score'] * 100, 1) . "%";
  583. // $matchScore = $row['score'];
  584. // $duplicateFound = true;
  585. // }
  586. // }
  587. // }
  588. // }
  589. //
  590. // // 如果找到重复客户,记录并提示
  591. // if ($duplicateFound) {
  592. // // 获取客户所有者姓名
  593. // $ownerResult = $conn->query("SELECT em_user FROM employee WHERE id = " . $matchOwner);
  594. // $ownerRow = $ownerResult->fetch_assoc();
  595. // $owner = textUncode($ownerRow['em_user']);
  596. //
  597. // // 确定谁先录入
  598. // if (strtotime($cs_addtime) > strtotime($matchAddTime)) {
  599. // $tstr = "INSERT INTO logrecord (loginName, loginIp, loginTime, loginAct) VALUES ('" .
  600. // $_SESSION['employee_name'] . "', '" . getIp() . "', '" . date('Y-m-d H:i:s') . "', '" .
  601. // $_SESSION['employee_name'] . "编辑客户\"" . $cs_code . "\",该客户与\"" .
  602. // textUncode($matchCustomerCode) . "\"存在重复,<br>匹配类型:" . $matchDetails .
  603. // "<br>客户由:" . $owner . $matchAddTime . "首次录入')";
  604. // } else {
  605. // $tstr = "INSERT INTO logrecord (loginName, loginIp, loginTime, loginAct) VALUES ('" .
  606. // $_SESSION['employee_name'] . "', '" . getIp() . "', '" . date('Y-m-d H:i:s') . "', '" .
  607. // $_SESSION['employee_name'] . "编辑客户\"" . $cs_code . "\",该客户与\"" .
  608. // textUncode($matchCustomerCode) . "\"存在重复,<br>匹配类型:" . $matchDetails .
  609. // "<br>客户由:" . $_SESSION['employee_name'] . $cs_addtime . "首次录入')";
  610. // }
  611. //
  612. // $conn->query($tstr);
  613. // echo "<script>alert('warning.2.录入信息\\n与" . $owner . "客户编号:" . textUncode($matchCustomerCode) .
  614. // "\\存在重复(" . $matchDetails . "),未能保存\\n请联系管理员核实!');history.back();</script>";
  615. // exit;
  616. // }
  617. // }
  618. }
  619. // Save or update customer data
  620. if ($act == "editSave" || $allowedit == 1) {
  621. $hrefstr = "/customers.php?Keys=" . $keys . "&fliterBusiness=" . $fliterBusiness .
  622. "&fliterDeal=" . $fliterDeal . "&Page=" . $page;
  623. // 更新客户基本信息
  624. $updateSql = "UPDATE customer SET
  625. cs_code='" . $conn->real_escape_string($cs_code) . "',
  626. cs_company='" . $conn->real_escape_string($cs_company) . "',
  627. cs_country=" . $cs_country . ",
  628. cs_from=" . $cs_from . ",
  629. cs_address='" . $conn->real_escape_string($cs_address) . "',
  630. cs_updatetime='" . $cs_updatetime . "',
  631. cs_belong=" . $cs_belong . ",
  632. cs_belongclient=" . $cs_belongClient . ",
  633. cs_state=" . $cs_state . ",
  634. cs_deal=" . $cs_deal . ",
  635. cs_note='" . $conn->real_escape_string($cs_note) . "'";
  636. // 处理cs_dealdate
  637. if ($cs_deal == 3) {
  638. $updateSql .= ", cs_dealdate = CASE WHEN cs_dealdate IS NULL THEN NOW() ELSE cs_dealdate END";
  639. }
  640. $updateSql .= " WHERE id=" . intval($id);
  641. $conn->query($updateSql);
  642. // 处理业务类型 - 先删除已有的业务类型
  643. $conn->query("DELETE FROM customer_business_type WHERE customer_id = " . intval($id));
  644. // 添加新的业务类型
  645. if (!empty($cs_type) && is_array($cs_type)) {
  646. foreach ($cs_type as $type_id) {
  647. $type_id = intval($type_id);
  648. if ($type_id > 0) {
  649. $conn->query("INSERT INTO customer_business_type (customer_id, business_type_id)
  650. VALUES (" . intval($id) . ", " . $type_id . ")");
  651. }
  652. }
  653. }
  654. // 处理联系人信息 - 首先删除已有的不在提交列表中的联系人
  655. $existingContactIds = [];
  656. foreach ($contacts as $contact) {
  657. if (!empty($contact['id'])) {
  658. $existingContactIds[] = (int)$contact['id'];
  659. }
  660. }
  661. if (!empty($existingContactIds)) {
  662. $idsToKeep = implode(',', $existingContactIds);
  663. $deleteContactsSql = "DELETE FROM customer_contact WHERE customer_id = " . intval($id) .
  664. " AND id NOT IN (" . $idsToKeep . ")";
  665. } else {
  666. $deleteContactsSql = "DELETE FROM customer_contact WHERE customer_id = " . intval($id);
  667. }
  668. $conn->query($deleteContactsSql);
  669. // 处理联系人信息 - 更新或添加联系人
  670. foreach ($contacts as $contact) {
  671. $contact_id = !empty($contact['id']) ? (int)$contact['id'] : 0;
  672. $contact_name = textEncode($contact['contact_name'] ?? '');
  673. // 准备SQL字段和值
  674. $fields = ['contact_name'];
  675. $values = ["'" . $conn->real_escape_string($contact_name) . "'"];
  676. $updates = ["contact_name = '" . $conn->real_escape_string($contact_name) . "'"];
  677. // 处理所有联系方式类型
  678. $methodTypes = ['tel', 'email', 'whatsapp', 'wechat', 'linkedin', 'facebook', 'alibaba'];
  679. foreach ($methodTypes as $type) {
  680. for ($i = 1; $i <= 3; $i++) {
  681. $field = $type . '_' . $i;
  682. $format_field = $field . '_format';
  683. $bu_field = $field . '_bu';
  684. $value = textEncode($contact[$field] ?? '');
  685. $format_value = ($type == 'tel' || $type == 'whatsapp') ? numFormat($value) : '';
  686. $bu_value = textEncode($contact[$bu_field] ?? $value);
  687. // 添加字段名
  688. $fields[] = $field;
  689. $fields[] = $bu_field;
  690. if ($type == 'tel' || $type == 'whatsapp') {
  691. $fields[] = $format_field;
  692. }
  693. // 添加值
  694. $values[] = "'" . $conn->real_escape_string($value) . "'";
  695. $values[] = "'" . $conn->real_escape_string($bu_value) . "'";
  696. if ($type == 'tel' || $type == 'whatsapp') {
  697. $values[] = "'" . $conn->real_escape_string($format_value) . "'";
  698. }
  699. // 添加更新语句
  700. $updates[] = $field . " = '" . $conn->real_escape_string($value) . "'";
  701. $updates[] = $bu_field . " = '" . $conn->real_escape_string($bu_value) . "'";
  702. if ($type == 'tel' || $type == 'whatsapp') {
  703. $updates[] = $format_field . " = '" . $conn->real_escape_string($format_value) . "'";
  704. }
  705. }
  706. }
  707. if ($contact_id > 0) {
  708. // 更新已有联系人
  709. $updateContactSql = "UPDATE customer_contact SET " .
  710. implode(", ", $updates) . ", updated_at = NOW() " .
  711. "WHERE id = " . $contact_id . " AND customer_id = " . intval($id);
  712. $conn->query($updateContactSql);
  713. } else {
  714. // 添加新联系人
  715. $insertContactSql = "INSERT INTO customer_contact (" .
  716. implode(", ", $fields) . ", customer_id, created_at, updated_at) VALUES (" .
  717. implode(", ", $values) . ", " . intval($id) . ", NOW(), NOW())";
  718. $conn->query($insertContactSql);
  719. }
  720. }
  721. // Update tags
  722. $conn->query("DELETE FROM tagtable WHERE customerId = " . intval($id));
  723. foreach ($mytag as $tag) {
  724. if (!empty(trim($tag))) {
  725. $tagSql = "INSERT INTO tagtable (tagName, employeeId, customerId) VALUES ('" .
  726. $conn->real_escape_string($tag) . "', " .
  727. intval($_SESSION['employee_id']) . ", " .
  728. intval($id) . ")";
  729. $conn->query($tagSql);
  730. }
  731. }
  732. echo "<script>location.href='$hrefstr';</script>";
  733. } else {
  734. // Insert new customer record
  735. $insertSql = "INSERT INTO customer (
  736. cs_code, cs_company, cs_country, cs_from, cs_address,
  737. cs_addtime, cs_updatetime, cs_belong, cs_belongClient,
  738. cs_state, cs_deal, cs_note, cs_chain, is_silent, cs_dealdate
  739. ) VALUES (
  740. '" . $conn->real_escape_string($cs_code) . "',
  741. '" . $conn->real_escape_string($cs_company) . "',
  742. " . $cs_country . ",
  743. " . $cs_from . ",
  744. '" . $conn->real_escape_string($cs_address) . "',
  745. NOW(),
  746. NOW(),
  747. " . $cs_belong . ",
  748. " . $cs_belongClient . ",
  749. " . $cs_state . ",
  750. " . $cs_deal . ",
  751. '" . $conn->real_escape_string($cs_note) . "',
  752. " . $cs_belong . ",
  753. 0,
  754. " . ($cs_deal == 3 ? "NOW()" : "NULL") . "
  755. )";
  756. $conn->query($insertSql);
  757. $new_customer_id = $conn->insert_id;
  758. // Insert business types for new customer
  759. if ($new_customer_id > 0 && !empty($cs_type) && is_array($cs_type)) {
  760. foreach ($cs_type as $type_id) {
  761. $type_id = intval($type_id);
  762. if ($type_id > 0) {
  763. $conn->query("INSERT INTO customer_business_type (customer_id, business_type_id)
  764. VALUES (" . $new_customer_id . ", " . $type_id . ")");
  765. }
  766. }
  767. }
  768. // Insert contact information for all contacts
  769. if ($new_customer_id > 0) {
  770. foreach ($contacts as $contact) {
  771. $contact_name = textEncode($contact['contact_name'] ?? '');
  772. // 准备SQL字段和值
  773. $fields = ['contact_name'];
  774. $values = ["'" . $conn->real_escape_string($contact_name) . "'"];
  775. // 处理所有联系方式类型
  776. $methodTypes = ['tel', 'email', 'whatsapp', 'wechat', 'linkedin', 'facebook', 'alibaba'];
  777. foreach ($methodTypes as $type) {
  778. for ($i = 1; $i <= 3; $i++) {
  779. $field = $type . '_' . $i;
  780. $format_field = $field . '_format';
  781. $bu_field = $field . '_bu';
  782. $value = textEncode($contact[$field] ?? '');
  783. $format_value = ($type == 'tel' || $type == 'whatsapp') ? numFormat($value) : '';
  784. $bu_value = textEncode($contact[$bu_field] ?? $value);
  785. // 添加字段名
  786. $fields[] = $field;
  787. $fields[] = $bu_field;
  788. if ($type == 'tel' || $type == 'whatsapp') {
  789. $fields[] = $format_field;
  790. }
  791. // 添加值
  792. $values[] = "'" . $conn->real_escape_string($value) . "'";
  793. $values[] = "'" . $conn->real_escape_string($bu_value) . "'";
  794. if ($type == 'tel' || $type == 'whatsapp') {
  795. $values[] = "'" . $conn->real_escape_string($format_value) . "'";
  796. }
  797. }
  798. }
  799. // 添加新联系人
  800. $insertContactSql = "INSERT INTO customer_contact (" .
  801. implode(", ", $fields) . ", customer_id, created_at, updated_at) VALUES (" .
  802. implode(", ", $values) . ", " . $new_customer_id . ", NOW(), NOW())";
  803. $conn->query($insertContactSql);
  804. }
  805. // Save tags for new customer
  806. foreach ($mytag as $tag) {
  807. if (!empty(trim($tag))) {
  808. $tagSql = "INSERT INTO tagtable (tagName, employeeId, customerId) VALUES ('" .
  809. $conn->real_escape_string($tag) . "', " .
  810. intval($_SESSION['employee_id']) . ", " .
  811. intval($new_customer_id) . ")";
  812. $conn->query($tagSql);
  813. }
  814. }
  815. }
  816. echo "<script>location.href='customerAdd.php';</script>";
  817. }
  818. ?>
  819. </body>
  820. </html>