customerAdd.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. <?php
  2. require_once 'conn.php';
  3. checkLogin();
  4. ?>
  5. <!DOCTYPE html>
  6. <html xmlns="http://www.w3.org/1999/xhtml">
  7. <head>
  8. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  9. <title>客户管理</title>
  10. <link rel="stylesheet" href="css/common.css" type="text/css" />
  11. <script src="js/jquery-1.7.2.min.js"></script>
  12. <script src="js/js.js"></script>
  13. <script src="js/xheditor-1.1.9/xheditor-1.1.9-zh-cn.min.js"></script>
  14. <script src="js/Hz2Py-szm-min.js"></script>
  15. <script src="js/ySearchSelect.js"></script>
  16. <script>
  17. $(document).ready(function(){
  18. $('.txt2').xheditor({
  19. tools:'full',
  20. hoverExecDelay:-1,
  21. urlBase:'system',
  22. upLinkUrl:"upload.php",
  23. upLinkExt:"zip,rar,txt,pdf",
  24. upImgUrl:"upload.php",
  25. upImgExt:"jpg,jpeg,gif,png",
  26. upFlashUrl:"upload.php",
  27. upFlashExt:"swf",
  28. upMediaUrl:"upload.php",
  29. upMediaExt:"wmv,avi,wma,mp3,mid"
  30. });
  31. // Add contact form
  32. $('.add-contact-btn').click(function() {
  33. var contactsContainer = $('#contacts-container');
  34. var contactIndex = contactsContainer.children('.contact-form').length;
  35. var contactForm = `
  36. <div class="contact-form" id="contact-form-${contactIndex}">
  37. <div class="contact-header">
  38. <button type="button" class="remove-contact-btn" data-index="${contactIndex}">删除</button>
  39. <h3>联系人 #${contactIndex + 1}</h3>
  40. </div>
  41. <input type="hidden" name="contact[${contactIndex}][id]" value="">
  42. <div class="contact-method-row">
  43. <span style="width:80px;display:inline-block;font-weight:bold;" class="method-select">联系人姓名</span>
  44. <input type="text" name="contact[${contactIndex}][contact_name]" class="txt1 method-input" style="width:60%;" placeholder="联系人姓名"/>
  45. </div>
  46. <div class="contact-methods-container" id="contact-methods-${contactIndex}">
  47. <!-- Contact methods will be added here -->
  48. </div>
  49. <button type="button" class="add-method-btn" data-contact-index="${contactIndex}">添加联系方式</button>
  50. </div>
  51. `;
  52. contactsContainer.append(contactForm);
  53. });
  54. // Add contact method
  55. $(document).on('click', '.add-method-btn', function() {
  56. var contactIndex = $(this).data('contact-index');
  57. var methodsContainer = $('#contact-methods-' + contactIndex);
  58. // Count existing methods by type
  59. var methodCounts = {};
  60. methodsContainer.find('select.method-select').each(function() {
  61. var type = $(this).val();
  62. if (type) {
  63. methodCounts[type] = (methodCounts[type] || 0) + 1;
  64. }
  65. });
  66. var methodRow = `
  67. <div class="contact-method-row">
  68. <select class="method-select" onchange="updateMethodSelectAndPlaceholder(this)">
  69. <option value="">请选择联系方式</option>
  70. <option value="tel" ${(methodCounts.tel || 0) >= 3 ? 'disabled' : ''}>电话</option>
  71. <option value="wechat" ${(methodCounts.wechat || 0) >= 3 ? 'disabled' : ''}>微信</option>
  72. <option value="whatsapp" ${(methodCounts.whatsapp || 0) >= 3 ? 'disabled' : ''}>WhatsApp</option>
  73. <option value="email" ${(methodCounts.email || 0) >= 3 ? 'disabled' : ''}>邮箱</option>
  74. <option value="linkedin" ${(methodCounts.linkedin || 0) >= 3 ? 'disabled' : ''}>领英</option>
  75. <option value="facebook" ${(methodCounts.facebook || 0) >= 3 ? 'disabled' : ''}>Facebook</option>
  76. <option value="alibaba" ${(methodCounts.alibaba || 0) >= 3 ? 'disabled' : ''}>阿里巴巴</option>
  77. </select>
  78. <input type="text" class="txt1 method-input" style="width:60%;" placeholder="请选择联系方式类型">
  79. <button type="button" class="remove-method-btn">删除</button>
  80. </div>
  81. `;
  82. methodsContainer.append(methodRow);
  83. updateMethodFields(methodsContainer.find('.contact-method-row:last-child'));
  84. });
  85. // Remove contact method
  86. $(document).on('click', '.remove-method-btn', function() {
  87. var methodRow = $(this).closest('.contact-method-row');
  88. var contactIndex = methodRow.closest('.contact-form').attr('id').split('-')[2];
  89. var type = methodRow.find('select.method-select').val();
  90. methodRow.remove();
  91. // Update available options in other selects
  92. updateAvailableMethodTypes(contactIndex);
  93. });
  94. // Remove contact
  95. $(document).on('click', '.remove-contact-btn', function() {
  96. var contactForm = $(this).closest('.contact-form');
  97. contactForm.remove();
  98. // Renumber remaining contacts
  99. $('#contacts-container .contact-form').each(function(index) {
  100. $(this).find('h3').text('联系人 #' + (index + 1));
  101. });
  102. });
  103. // Add initial contact form if none exists
  104. if ($('#contacts-container').children().length === 0) {
  105. $('.add-contact-btn').click();
  106. }
  107. });
  108. // Update method fields based on selection
  109. function updateMethodFields(methodRow) {
  110. var select = methodRow.find('select.method-select');
  111. var input = methodRow.find('input.method-input');
  112. var contactForm = methodRow.closest('.contact-form');
  113. var contactIndex = contactForm.attr('id').split('-')[2];
  114. var type = select.val();
  115. if (!type) return;
  116. // Count existing methods of this type
  117. var count = 1;
  118. contactForm.find('select.method-select').each(function() {
  119. if ($(this).val() === type && $(this)[0] !== select[0]) {
  120. count++;
  121. }
  122. });
  123. // Update field names
  124. select.attr('name', `contact[${contactIndex}][${type}_${count}]`);
  125. input.attr('name', `contact[${contactIndex}][${type}_${count}]`);
  126. // Add format field for tel and whatsapp
  127. if (type === 'tel' || type === 'whatsapp') {
  128. if (!methodRow.find('.format-input').length) {
  129. input.after(`<input type="hidden" class="format-input" name="contact[${contactIndex}][${type}_${count}_format]">`);
  130. }
  131. }
  132. // Add backup field
  133. if (!methodRow.find('.backup-input').length) {
  134. methodRow.append(`<input type="hidden" class="backup-input" name="contact[${contactIndex}][${type}_${count}_bu]">`);
  135. }
  136. }
  137. // Update available method types for a contact
  138. function updateAvailableMethodTypes(contactIndex) {
  139. var methodsContainer = $('#contact-methods-' + contactIndex);
  140. // Count methods by type
  141. var methodCounts = {};
  142. methodsContainer.find('select.method-select').each(function() {
  143. var type = $(this).val();
  144. if (type) {
  145. methodCounts[type] = (methodCounts[type] || 0) + 1;
  146. }
  147. });
  148. // Update all selects in this contact
  149. methodsContainer.find('select.method-select').each(function() {
  150. var currentValue = $(this).val();
  151. $(this).find('option').each(function() {
  152. var optionValue = $(this).val();
  153. if (optionValue && optionValue !== currentValue) {
  154. $(this).prop('disabled', (methodCounts[optionValue] || 0) >= 3);
  155. }
  156. });
  157. });
  158. }
  159. // Update placeholder and handle method fields
  160. function updateMethodSelectAndPlaceholder(selectElement) {
  161. var methodRow = $(selectElement).closest('.contact-method-row');
  162. updateMethodPlaceholder(selectElement);
  163. updateMethodFields(methodRow);
  164. var contactIndex = methodRow.closest('.contact-form').attr('id').split('-')[2];
  165. updateAvailableMethodTypes(contactIndex);
  166. }
  167. // Update method placeholder based on selected type
  168. function updateMethodPlaceholder(selectElement) {
  169. var placeholder = "";
  170. var value = $(selectElement).val();
  171. switch(value) {
  172. case "tel":
  173. placeholder = "电话格式必须为:区号+号码 如:+86 15012345678";
  174. break;
  175. case "wechat":
  176. placeholder = "微信";
  177. break;
  178. case "whatsapp":
  179. placeholder = "Whatsapp 格式必须为:区号+号码 如:+86 15012345678";
  180. break;
  181. case "email":
  182. placeholder = "邮箱格式必须正确,如: example@domain.com";
  183. break;
  184. case "linkedin":
  185. placeholder = "领英链接";
  186. break;
  187. case "facebook":
  188. placeholder = "Facebook";
  189. break;
  190. case "alibaba":
  191. placeholder = "阿里巴巴";
  192. break;
  193. default:
  194. placeholder = "请选择联系方式类型";
  195. }
  196. $(selectElement).next('.method-input').attr('placeholder', placeholder);
  197. }
  198. // Custom validation function for multiple contacts form with contact methods
  199. function validateMultipleContactsForm() {
  200. var clientCode = $("#cs_code").val();
  201. var clientCompany = $("#cs_company").val();
  202. var clientFrom = $("#cs_from").val();
  203. var clientCountry = $("#cs_country").val();
  204. // Validate basic customer info
  205. if (clientCode == "" || clientCode == null) {
  206. alert("客户代码不能为空!");
  207. $("#cs_code").focus();
  208. return false;
  209. }
  210. if (clientCountry == 0 || !clientCountry) {
  211. alert("这是哪个国家的客户?");
  212. $("#cs_country").focus();
  213. return false;
  214. }
  215. if (clientFrom == "0") {
  216. alert("请填写客户来源!");
  217. $("#cs_from").focus();
  218. return false;
  219. }
  220. // Get source text to check if it's from Alibaba platforms
  221. var clientFromText = $("#cs_from option:selected").text();
  222. var isAlibabaSource = clientFromText.indexOf("1688") >= 0 ||
  223. clientFromText.indexOf("阿里") >= 0 ||
  224. clientFromText.indexOf("alibaba") >= 0;
  225. // Validate that at least one contact has at least one contact method
  226. var hasContactMethod = false;
  227. var hasAlibabaContact = false;
  228. var allContactsValid = true;
  229. var phoneRegex = /^\+\d{1,4}\s\d{5,}$/; // Regex to validate phone format: +[country code] [number]
  230. var emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; // Regex to validate email format
  231. $('.contact-form').each(function(contactIndex) {
  232. var $form = $(this);
  233. var contactName = $form.find('input[name*="[contact_name]"]').val();
  234. var hasMethodInThisContact = false;
  235. // Check if this contact has methods
  236. $form.find('.contact-method-row').each(function() {
  237. var methodType = $(this).find('select.method-select').val();
  238. var methodValue = $(this).find('input.method-input').val();
  239. if (methodValue) {
  240. hasMethodInThisContact = true;
  241. hasContactMethod = true;
  242. // Check if there's an Alibaba contact method
  243. if (methodType === 'alibaba') {
  244. hasAlibabaContact = true;
  245. }
  246. }
  247. // Check if method type is selected but value is empty
  248. if (methodType && !methodValue) {
  249. alert("联系方式类型已选择但值为空");
  250. allContactsValid = false;
  251. return false;
  252. }
  253. // Validate phone number format for tel and whatsapp
  254. if ((methodType === 'tel' || methodType === 'whatsapp') && methodValue) {
  255. if (!phoneRegex.test(methodValue)) {
  256. alert("电话格式不正确,请使用以下格式:区号+号码,如 +86 15012345678");
  257. $(this).find('input.method-input').focus();
  258. allContactsValid = false;
  259. return false;
  260. }
  261. }
  262. // Validate email format
  263. if (methodType === 'email' && methodValue) {
  264. if (!emailRegex.test(methodValue)) {
  265. alert("邮箱格式不正确,请输入有效的邮箱地址");
  266. $(this).find('input.method-input').focus();
  267. allContactsValid = false;
  268. return false;
  269. }
  270. }
  271. });
  272. // If contact has a name but no methods, or has methods but no name
  273. if ((contactName && !hasMethodInThisContact) || (!contactName && hasMethodInThisContact)) {
  274. alert("联系人 #" + (contactIndex + 1) + " 缺少联系人姓名或联系方式");
  275. allContactsValid = false;
  276. return false;
  277. }
  278. // If contact has neither name nor methods, it's an empty contact
  279. if (!contactName && !hasMethodInThisContact) {
  280. alert("联系人 #" + (contactIndex + 1) + " 是空的,请填写信息或删除此联系人");
  281. allContactsValid = false;
  282. return false;
  283. }
  284. });
  285. if (!allContactsValid) {
  286. return false;
  287. }
  288. if (!hasContactMethod) {
  289. alert("至少需要添加一个联系人,且联系人至少需要一种联系方式!");
  290. return false;
  291. }
  292. // If source is from Alibaba platforms, must have Alibaba contact method
  293. if (isAlibabaSource && !hasAlibabaContact) {
  294. alert("客户来源为1688或阿里国际站时,必须添加至少一个阿里巴巴联系方式!");
  295. return false;
  296. }
  297. // Set tag values
  298. $("input#mytag").val($(".taglist").html());
  299. return true;
  300. }
  301. // Modified submission function
  302. function subform() {
  303. if (validateMultipleContactsForm()) {
  304. $("#form1").submit();
  305. }
  306. }
  307. </script>
  308. <style>
  309. body {
  310. margin: 0;
  311. padding: 20px;
  312. background: #fff;
  313. }
  314. #man_zone {
  315. margin-left: 0;
  316. }
  317. .contact-form {
  318. margin-bottom: 10px;
  319. /*border: 1px solid #ddd;*/
  320. padding: 8px;
  321. background-color: #FFFFFF;
  322. }
  323. .contact-header {
  324. display: flex;
  325. align-items: center;
  326. margin-bottom: 8px;
  327. gap: 10px;
  328. }
  329. .contact-header h3 {
  330. margin: 0;
  331. order: 2;
  332. flex-grow: 1;
  333. }
  334. .remove-contact-btn {
  335. background-color: #f44336;
  336. color: white;
  337. border: none;
  338. padding: 4px 8px;
  339. cursor: pointer;
  340. order: 1;
  341. }
  342. .add-contact-btn {
  343. background-color: #4CAF50;
  344. color: white;
  345. border: none;
  346. padding: 6px 12px;
  347. margin-bottom: 10px;
  348. cursor: pointer;
  349. }
  350. .contact-methods-container {
  351. margin-top: 8px;
  352. }
  353. .contact-method-row {
  354. margin-bottom: 6px;
  355. padding: 6px;
  356. /*border: 1px solid #eee;*/
  357. /*background-color: #f5f5f5;*/
  358. display: flex;
  359. align-items: center;
  360. gap: 8px;
  361. }
  362. .add-method-btn {
  363. background-color: #2196F3;
  364. color: white;
  365. border: none;
  366. padding: 4px 8px;
  367. margin-top: 4px;
  368. cursor: pointer;
  369. }
  370. .remove-method-btn {
  371. background-color: #f44336;
  372. color: white;
  373. border: none;
  374. padding: 2px 4px;
  375. cursor: pointer;
  376. }
  377. .method-select {
  378. margin-right: 8px;
  379. padding: 3px;
  380. }
  381. .contact-table {
  382. margin-bottom: 6px;
  383. }
  384. .contact-table td, .contact-table th {
  385. padding: 4px 6px;
  386. }
  387. </style>
  388. </head>
  389. <body class="clear">
  390. <?php // require_once 'panel.php'; ?>
  391. <div id="man_zone">
  392. <form name="form1" id="form1" method="post" action="customerSave.php<?= $hrefstr ?? '' ?>">
  393. <table width="100%" border="0" cellpadding="3" cellspacing="1" class="table1">
  394. <tbody>
  395. <tr>
  396. <th width="8%">客户编号</th>
  397. <td>
  398. <input type="text" id="cs_code" name="cs_code" value="" class="txt1" />
  399. <input type="hidden" name="cs_addtime" value="<?= date('Y-m-d H:i:s') ?>" />
  400. </td>
  401. </tr>
  402. <tr>
  403. <th width="8%">公司名称</th>
  404. <td><input type="text" id="cs_company" name="cs_company" value="" class="txt1" /></td>
  405. </tr>
  406. <tr>
  407. <th width="8%">地区/国家</th>
  408. <td>
  409. <div class="layui-input-inline">
  410. <div class="layui-form-select ySearchSelect y1">
  411. <div class="layui-input">请选择客户区域</div>
  412. <input name="cs_country" id="cs_country" type="hidden">
  413. <i class="layui-edge"></i>
  414. <ul>
  415. <?php
  416. $result = $conn->query("SELECT id, countryCode, countryName FROM country");
  417. while ($row = $result->fetch_assoc()) {
  418. echo "<li class=\"on\" data-c=\"{$row['id']}\">(+{$row['countryCode']}){$row['countryName']}</li>";
  419. }
  420. ?>
  421. <p>无匹配项</p>
  422. </ul>
  423. </div>
  424. </div>
  425. <script>
  426. $(function () {
  427. $(".y1").ySearchSelect();
  428. })
  429. </script>
  430. </td>
  431. </tr>
  432. <tr>
  433. <th width="8%">来源</th>
  434. <td>
  435. <select id="cs_from" name="cs_from">
  436. <option value="0">请选择来源</option>
  437. <?php
  438. $result = $conn->query("SELECT id, ch_name FROM qudao");
  439. while ($row = $result->fetch_assoc()) {
  440. echo "<option value=\"{$row['id']}\">{$row['ch_name']}</option>";
  441. }
  442. ?>
  443. </select>
  444. </td>
  445. </tr>
  446. <tr>
  447. <th width="8%" valign="top">联系人信息</th>
  448. <td>
  449. <button type="button" class="add-contact-btn">添加联系人</button>
  450. <div id="contacts-container">
  451. <!-- Contact forms will be added here -->
  452. </div>
  453. </td>
  454. </tr>
  455. <tr>
  456. <th>地址</th>
  457. <td><input type="text" id="cs_address" name="cs_address" value="" class="txt1" /></td>
  458. </tr>
  459. <tr>
  460. <th>业务类型</th>
  461. <td>
  462. <?php
  463. $result = $conn->query("SELECT id, businessType FROM clienttype");
  464. while ($row = $result->fetch_assoc()) {
  465. echo "<input type=\"radio\" name=\"cs_type\" value=\"{$row['id']}\" id=\"fortype{$row['id']}\">
  466. <label for=\"fortype{$row['id']}\">{$row['businessType']}</label>";
  467. }
  468. ?>
  469. </td>
  470. </tr>
  471. <tr>
  472. <th>跟进阶段</th>
  473. <td>
  474. <input type="radio" id="fordeal1" class="cs_deal" name="cs_deal" value="0"><label for="fordeal1">无响应</label>
  475. <input type="radio" id="fordeal2" class="cs_deal" name="cs_deal" value="1" checked="checked"><label for="fordeal2">背景调查</label>
  476. <input type="radio" id="fordeal3" class="cs_deal" name="cs_deal" value="2"><label for="fordeal3">明确需求</label>
  477. <input type="radio" id="fordeal4" class="cs_deal" name="cs_deal" value="3"><label for="fordeal4">已成交</label>
  478. </td>
  479. </tr>
  480. <tr>
  481. <th>其他</th>
  482. <td>
  483. <input type="checkbox" id="belongClient" class="cs_belongClient" name="cs_belongClient" value="1">
  484. <label for="belongClient">客户的客户</label>
  485. </td>
  486. </tr>
  487. <tr>
  488. <th>自定义标签</th>
  489. <td>
  490. <div class="taglist"></div>
  491. <input type="hidden" id="mytag" name="mytag" value="">
  492. <div class="commontag clear">
  493. <i class="tag">美特柏品牌客户</i>,
  494. <i class="tag">OEM定制客户</i>,
  495. <i class="tag">小型B端客户</i>,
  496. <i class="tag">C端客户</i>,
  497. <i class="tag">贸易公司</i>,
  498. <i class="tag">档口客户</i>
  499. <?php
  500. // 将bind_param改为SQL拼接
  501. $employee_id = intval($_SESSION['employee_id']);
  502. $sql = "SELECT DISTINCT tagName FROM tagtable WHERE employeeId = ".$employee_id;
  503. $result = $conn->query($sql);
  504. while ($row = $result->fetch_assoc()) {
  505. echo "<i class=\"tag\">" . htmlspecialcharsFix(textUncode($row['tagName'])) . "</i>,";
  506. }
  507. ?>
  508. </div>
  509. <input type="text" id="tapinput" class="txt-short" placeholder="添加新标签,按Enter添加">
  510. </td>
  511. </tr>
  512. <tr>
  513. <th width="8%">备注</th>
  514. <td><textarea name="cs_note" class="txt2" placeholder=""></textarea></td>
  515. </tr>
  516. <tr>
  517. <th></th>
  518. <td>
  519. <input type="button" name="save" id="save" value="确定" class="btn1" onclick="subform();" />
  520. <input type="button" value="返回" class="btn1" onClick="location.href='customers.php'" />
  521. </td>
  522. </tr>
  523. </tbody>
  524. </table>
  525. </form>
  526. </div>
  527. </body>
  528. </html>