From a32d5d1bbdf81f8d8d2b538260a12f460ec4c852 Mon Sep 17 00:00:00 2001 From: Trae AI Date: Tue, 23 Dec 2025 11:15:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=85=AC=E6=B5=B7=E6=B1=A0?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E8=AE=A4=E9=A2=86=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CustomerRestController.java | 54 +++++ .../example/web/mapper/CustomerMapper.java | 7 + .../example/web/service/CustomerService.java | 8 + .../web/service/impl/CustomerServiceImpl.java | 203 ++++++++++++++++++ src/main/resources/mapper/CustomerMapper.xml | 7 + src/main/resources/static/sells.html | 72 ++++++- src/main/resources/static/supply.html | 60 +++++- 7 files changed, 407 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/web/controller/CustomerRestController.java b/src/main/java/com/example/web/controller/CustomerRestController.java index 9cb7f30..93a70bc 100644 --- a/src/main/java/com/example/web/controller/CustomerRestController.java +++ b/src/main/java/com/example/web/controller/CustomerRestController.java @@ -206,4 +206,58 @@ public class CustomerRestController { System.out.println("DEBUG: 记录客户查看操作响应: " + response); return response; } + + /** + * 认领客户 + * @param request 认领请求,包含客户ID和操作人信息 + * @return 响应结果 + */ + @PostMapping("/claim") + public Map claimCustomer(@RequestBody Map request) { + Map response = new HashMap<>(); + try { + System.out.println("DEBUG: 收到客户认领请求,数据: " + request); + + String customerId = (String) request.get("customerId"); + + // 获取操作人信息 + Map operatorInfo = (Map) request.get("operatorInfo"); + if (operatorInfo == null) { + operatorInfo = new HashMap<>(); + } + + // 创建登录者信息对象 + Login login = new Login(); + login.setProjectName((String) operatorInfo.get("role")); + login.setUserName((String) operatorInfo.get("userName")); + login.setManagercompany((String) operatorInfo.get("company")); + login.setManagerdepartment((String) operatorInfo.get("department")); + login.setOrganization((String) operatorInfo.get("organization")); + + if (customerId == null || customerId.isEmpty()) { + response.put("success", false); + response.put("message", "客户认领失败: 参数不完整"); + return response; + } + + // 调用服务层方法认领客户 + boolean success = customerService.claimCustomer(customerId, login); + + System.out.println("DEBUG: 客户认领结果: " + success); + + if (success) { + response.put("success", true); + response.put("message", "客户认领成功"); + } else { + response.put("success", false); + response.put("message", "客户认领失败"); + } + } catch (Exception e) { + System.out.println("DEBUG: 客户认领异常,异常信息: " + e.getMessage()); + e.printStackTrace(); + response.put("success", false); + response.put("message", "客户认领失败: " + e.getMessage()); + } + return response; + } } \ No newline at end of file diff --git a/src/main/java/com/example/web/mapper/CustomerMapper.java b/src/main/java/com/example/web/mapper/CustomerMapper.java index bda3e45..d8afb8c 100644 --- a/src/main/java/com/example/web/mapper/CustomerMapper.java +++ b/src/main/java/com/example/web/mapper/CustomerMapper.java @@ -90,6 +90,13 @@ public interface CustomerMapper { */ Contacts getContactsByPhoneNumber(@Param("phoneNumber") String phoneNumber); + /** + * 根据ID获取联系人信息 + * @param id 联系人ID + * @return 联系人信息 + */ + Contacts getContactsById(@Param("id") String id); + /** * 更新联系人信息 * @param contacts 联系人信息 diff --git a/src/main/java/com/example/web/service/CustomerService.java b/src/main/java/com/example/web/service/CustomerService.java index b6381ba..01a4f31 100644 --- a/src/main/java/com/example/web/service/CustomerService.java +++ b/src/main/java/com/example/web/service/CustomerService.java @@ -85,4 +85,12 @@ public interface CustomerService { * @return 是否成功 */ boolean saveOperationRecord(String userId, Login login, String operationEvent, String originalData, String modifiedData, String changedFields); + + /** + * 认领客户 + * @param customerId 客户ID + * @param login 登录者信息 + * @return 是否成功 + */ + boolean claimCustomer(String customerId, Login login); } \ No newline at end of file diff --git a/src/main/java/com/example/web/service/impl/CustomerServiceImpl.java b/src/main/java/com/example/web/service/impl/CustomerServiceImpl.java index 76fdd86..7c77ec4 100644 --- a/src/main/java/com/example/web/service/impl/CustomerServiceImpl.java +++ b/src/main/java/com/example/web/service/impl/CustomerServiceImpl.java @@ -231,6 +231,209 @@ public class CustomerServiceImpl implements CustomerService { } } + @Override + public boolean claimCustomer(String customerId, Login login) { + try { + // 获取当前时间 + LocalDateTime now = LocalDateTime.now(); + System.out.println("DEBUG: 开始认领客户,客户ID: " + customerId); + + // 1. 尝试从primary数据源查找客户 + Contacts contacts = null; + int retryCount = 0; + int maxRetries = 3; + long retryDelay = 1000; // 1秒 + + while (retryCount < maxRetries) { + try { + contacts = customerMapper.getContactsById(customerId); + break; // 获取成功,退出重试循环 + } catch (Exception e) { + retryCount++; + System.out.println("DEBUG: 第" + retryCount + "次尝试获取primary数据源连接失败,异常信息: " + e.getMessage()); + if (retryCount >= maxRetries) { + throw e; // 达到最大重试次数,抛出异常 + } + // 等待一段时间后重试 + Thread.sleep(retryDelay); + retryDelay *= 2; // 指数退避 + } + } + + if (contacts != null) { + System.out.println("DEBUG: 在primary数据源中找到客户"); + + // 获取企业信息和负责人信息 + Enterprise enterprise = customerMapper.getEnterpriseByContactId(contacts.getId()); + Managers managers = customerMapper.getManagerByContactId(contacts.getId()); + + // 保存原始数据用于操作记录 + StringBuilder originalData = new StringBuilder("{"); + if (enterprise != null) { + originalData.append("\"level\": \"" + (enterprise.getLevel() == null ? "" : enterprise.getLevel()) + "\","); + } + if (managers != null) { + originalData.append("\"managercompany\": \"" + (managers.getManagercompany() == null ? "" : managers.getManagercompany()) + "\","); + originalData.append("\"managerdepartment\": \"" + (managers.getManagerdepartment() == null ? "" : managers.getManagerdepartment()) + "\","); + originalData.append("\"organization\": \"" + (managers.getOrganization() == null ? "" : managers.getOrganization()) + "\","); + originalData.append("\"userName\": \"" + (managers.getUserName() == null ? "" : managers.getUserName()) + "\","); + } + // 移除末尾逗号 + if (originalData.length() > 1 && originalData.charAt(originalData.length() - 1) == ',') { + originalData.setLength(originalData.length() - 1); + } + originalData.append("}"); + + // 更新企业等级为未分级 + String originalLevel = null; + if (enterprise != null) { + originalLevel = enterprise.getLevel(); + enterprise.setLevel("unclassified"); + customerMapper.updateEnterprise(enterprise); + } + + // 更新负责人信息 + String originalManagerInfo = ""; + if (managers != null) { + originalManagerInfo = managers.getManagercompany() + "," + managers.getManagerdepartment() + "," + managers.getOrganization() + "," + managers.getUserName(); + managers.setManagercompany(login.getManagercompany()); + managers.setManagerdepartment(login.getManagerdepartment()); + managers.setOrganization(login.getOrganization()); + managers.setUserName(login.getUserName()); + customerMapper.updateManagers(managers); + } else { + managers = new Managers(); + managers.setId(contacts.getId()); + managers.setManagercompany(login.getManagercompany()); + managers.setManagerdepartment(login.getManagerdepartment()); + managers.setOrganization(login.getOrganization()); + managers.setUserName(login.getUserName()); + managers.setRole(login.getProjectName()); + managers.setCreated_at(now); + managers.setUpdated_at(now); + customerMapper.insertManagers(managers); + } + + // 构建修改后的数据 + StringBuilder modifiedData = new StringBuilder("{"); + modifiedData.append("\"level\": \"unclassified\","); + modifiedData.append("\"managercompany\": \"" + login.getManagercompany() + "\","); + modifiedData.append("\"managerdepartment\": \"" + login.getManagerdepartment() + "\","); + modifiedData.append("\"organization\": \"" + login.getOrganization() + "\","); + modifiedData.append("\"userName\": \"" + login.getUserName() + "\""); + modifiedData.append("}"); + + // 保存操作记录 + String changedFields = "[\"level\", \"managercompany\", \"managerdepartment\", \"organization\", \"userName\"]"; + saveOperationRecord(contacts.getId(), login, "认领客户", originalData.toString(), modifiedData.toString(), changedFields); + + // 记录客户认领操作 + customerTraceUtil.recordCustomerFollowup(contacts.getId(), login.getManagercompany(), login.getManagerdepartment(), login.getOrganization(), login.getProjectName(), login.getUserName(), originalData.toString(), modifiedData.toString(), changedFields); + + return true; + } + + System.out.println("DEBUG: 在primary数据源中未找到客户,尝试从wechat数据源查找"); + + // 2. 尝试从wechat数据源查找客户 + Users user = null; + retryCount = 0; + retryDelay = 1000; // 1秒 + + while (retryCount < maxRetries) { + try { + user = wechatCustomerMapper.getUsersByUserId(customerId); + break; // 获取成功,退出重试循环 + } catch (Exception e) { + retryCount++; + System.out.println("DEBUG: 第" + retryCount + "次尝试获取wechat数据源连接失败,异常信息: " + e.getMessage()); + if (retryCount >= maxRetries) { + throw e; // 达到最大重试次数,抛出异常 + } + // 等待一段时间后重试 + Thread.sleep(retryDelay); + retryDelay *= 2; // 指数退避 + } + } + + if (user != null) { + System.out.println("DEBUG: 在wechat数据源中找到客户"); + + // 获取负责人信息 + UsersManagements managements = wechatCustomerMapper.getManagementsByUserId(user.getUserId()); + + // 保存原始数据用于操作记录 + StringBuilder originalData = new StringBuilder("{"); + originalData.append("\"level\": \"" + (user.getLevel() == null ? "" : user.getLevel()) + "\","); + if (managements != null) { + originalData.append("\"managercompany\": \"" + (managements.getManagercompany() == null ? "" : managements.getManagercompany()) + "\","); + originalData.append("\"managerdepartment\": \"" + (managements.getManagerdepartment() == null ? "" : managements.getManagerdepartment()) + "\","); + originalData.append("\"organization\": \"" + (managements.getOrganization() == null ? "" : managements.getOrganization()) + "\","); + originalData.append("\"userName\": \"" + (managements.getUserName() == null ? "" : managements.getUserName()) + "\","); + } + // 移除末尾逗号 + if (originalData.length() > 1 && originalData.charAt(originalData.length() - 1) == ',') { + originalData.setLength(originalData.length() - 1); + } + originalData.append("}"); + + // 更新用户等级为未分级 + user.setLevel("unclassified"); + user.setUpdated_at(now); + + // 更新负责人信息 + if (managements == null) { + managements = new UsersManagements(); + managements.setUserId(user.getUserId()); + } + managements.setManagercompany(login.getManagercompany()); + managements.setManagerdepartment(login.getManagerdepartment()); + managements.setOrganization(login.getOrganization()); + managements.setUserName(login.getUserName()); + managements.setRole(login.getProjectName()); + + int result = wechatCustomerMapper.updateUsers(user); + + // 保存或更新负责人信息 + int managerResult = wechatCustomerMapper.getManagementsByUserId(user.getUserId()) == null + ? wechatCustomerMapper.updateUsersManagements(managements) + : wechatCustomerMapper.updateUsersManagements(managements); + + System.out.println("DEBUG: 更新wechat数据源用户结果: " + result + ", 更新负责人结果: " + managerResult); + + // 保存操作记录 + if (result > 0 || managerResult > 0) { + StringBuilder modifiedData = new StringBuilder("{"); + modifiedData.append("\"level\": \"unclassified\","); + modifiedData.append("\"managercompany\": \"" + login.getManagercompany() + "\","); + modifiedData.append("\"managerdepartment\": \"" + login.getManagerdepartment() + "\","); + modifiedData.append("\"organization\": \"" + login.getOrganization() + "\","); + modifiedData.append("\"userName\": \"" + login.getUserName() + "\""); + modifiedData.append("}"); + + String changedFields = "[\"level\", \"managercompany\", \"managerdepartment\", \"organization\", \"userName\"]"; + saveOperationRecord(String.valueOf(user.getUserId()), login, "认领客户", originalData.toString(), modifiedData.toString(), changedFields); + + // 记录客户认领操作 + customerTraceUtil.recordCustomerFollowup(String.valueOf(user.getUserId()), login.getManagercompany(), login.getManagerdepartment(), login.getOrganization(), login.getProjectName(), login.getUserName(), originalData.toString(), modifiedData.toString(), changedFields); + } + + return result > 0; + } + + System.out.println("DEBUG: 在两个数据源中都未找到客户信息"); + return false; + } catch (InterruptedException e) { + System.out.println("DEBUG: 认领客户过程中线程被中断,异常信息: " + e.getMessage()); + Thread.currentThread().interrupt(); + throw new RuntimeException("认领客户失败: 线程中断"); + } catch (Exception e) { + System.out.println("DEBUG: 认领客户失败,异常信息: " + e.getMessage()); + e.printStackTrace(); + throw new RuntimeException("认领客户失败: " + e.getMessage()); + } + } + @Override public List getDepartmentSeaPool(String role, Login login) { // 移除重复解码,前端已解码 diff --git a/src/main/resources/mapper/CustomerMapper.xml b/src/main/resources/mapper/CustomerMapper.xml index 7ef4295..8951f5b 100644 --- a/src/main/resources/mapper/CustomerMapper.xml +++ b/src/main/resources/mapper/CustomerMapper.xml @@ -125,6 +125,13 @@ WHERE phoneNumber = #{phoneNumber} + + + UPDATE contacts diff --git a/src/main/resources/static/sells.html b/src/main/resources/static/sells.html index 1d10247..79b0794 100644 --- a/src/main/resources/static/sells.html +++ b/src/main/resources/static/sells.html @@ -5025,6 +5025,62 @@ alert('客户新增成功!'); }); + // 认领客户功能 + function claimCustomer(customerId) { + console.log('认领客户:', customerId); + const customer = customerData[customerId]; + + if (!customer) { + console.log('客户不存在:', customerId); + alert('客户不存在!'); + return; + } + + // 获取登录用户信息 + const loginInfo = getLoginUserInfo(); + console.log('登录者信息:', loginInfo); + + // 构造请求数据 + const requestData = { + customerId: customerId, + operatorInfo: { + company: loginInfo.managercompany, + department: loginInfo.managerdepartment, + organization: loginInfo.organization, + role: loginInfo.projectName, + userName: loginInfo.userName + } + }; + + // 发送POST请求认领客户 + fetch('/DL/api/customer/claim', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(requestData) + }) + .then(response => response.json()) + .then(data => { + console.log('认领客户结果:', data); + if (data.success) { + alert('客户认领成功!'); + // 刷新公海池列表 + if (currentTab === 'departmentSeaPool') { + showDepartmentSeaPool(); + } else if (currentTab === 'organizationSeaPool') { + showOrganizationSeaPool(); + } + } else { + alert('客户认领失败: ' + (data.message || '未知错误')); + } + }) + .catch(error => { + console.error('认领客户失败:', error); + alert('客户认领失败: 网络错误'); + }); + } + // 查看详情功能 function viewCustomerDetails(customerId) { console.log('查看客户详情:', customerId); @@ -5128,9 +5184,21 @@ document.getElementById('detail-specification').textContent = customer.specification || '-'; document.getElementById('detail-quantity').textContent = customer.quantity || '-'; document.getElementById('detail-weight').textContent = customer.weight || '-'; + + // 公海池客户将编辑按钮改为认领按钮 + const editSaveBtn = document.getElementById('editSaveBtn'); + editSaveBtn.textContent = '认领'; + editSaveBtn.onclick = function() { + claimCustomer(customer.id); + }; } else { console.log('隐藏公海需求区域'); publicSeaDemandSection.style.display = 'none'; + + // 普通客户恢复编辑按钮功能 + const editSaveBtn = document.getElementById('editSaveBtn'); + editSaveBtn.textContent = '编辑'; + editSaveBtn.onclick = toggleEditMode; } document.getElementById('customerModal').classList.add('active'); @@ -6246,7 +6314,7 @@ ${customer.created_at || ''} ${customer.updated_at || ''} - + `; @@ -6281,7 +6349,7 @@ ${customer.created_at || ''} ${customer.updated_at || ''} - + `; diff --git a/src/main/resources/static/supply.html b/src/main/resources/static/supply.html index 8e07626..0406b3c 100644 --- a/src/main/resources/static/supply.html +++ b/src/main/resources/static/supply.html @@ -5028,6 +5028,62 @@ alert('客户新增成功!'); }); + // 认领客户功能 + function claimCustomer(customerId) { + console.log('认领客户:', customerId); + const customer = customerData[customerId]; + + if (!customer) { + console.log('客户不存在:', customerId); + alert('客户不存在!'); + return; + } + + // 获取登录用户信息 + const loginInfo = getLoginInfo(); + console.log('登录者信息:', loginInfo); + + // 构造请求数据 + const requestData = { + customerId: customerId, + operatorInfo: { + company: loginInfo.managercompany, + department: loginInfo.managerdepartment, + organization: loginInfo.organization, + role: loginInfo.projectName, + userName: loginInfo.userName + } + }; + + // 发送POST请求认领客户 + fetch('/DL/api/customer/claim', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(requestData) + }) + .then(response => response.json()) + .then(data => { + console.log('认领客户结果:', data); + if (data.success) { + alert('客户认领成功!'); + // 刷新公海池列表 + if (currentTab === 'departmentSeaPool') { + showDepartmentSeaPool(); + } else if (currentTab === 'organizationSeaPool') { + showOrganizationSeaPool(); + } + } else { + alert('客户认领失败: ' + (data.message || '未知错误')); + } + }) + .catch(error => { + console.error('认领客户失败:', error); + alert('客户认领失败: 网络错误'); + }); + } + // 查看详情功能 function viewCustomerDetails(customerId) { console.log('查看客户详情:', customerId); @@ -6299,7 +6355,7 @@ ${customer.created_at || '-'} ${customer.updated_at || '-'} - + `; @@ -6335,7 +6391,7 @@ ${customer.created_at || '-'} ${customer.updated_at || '-'} - + `;